Compare commits

..

No commits in common. "develop" and "release-6.x" have entirely different histories.

18 changed files with 78 additions and 150 deletions

View File

@ -25,19 +25,12 @@ matrix:
compiler: gcc compiler: gcc
- os: linux - os: linux
sudo: false sudo: false
env: GCC_VER="4.9" CMAKE_OPTIONS="-D DYNLOAD_ENABLED:BOOL=FALSE -D MULTITHREAD_SUPPORT_ENABLED:BOOL=FALSE -D USE_STD_MAKE_SHARED:BOOL=TRUE" BUILD_ONLY=1 env: GCC_VER="5"
compiler: gcc
- os: linux
sudo: false
env: GCC_VER="5" CPPCHECK=1 COVERAGE=1 CMAKE_OPTIONS="-D RUN_FUZZY_TESTS:BOOL=TRUE"
compiler: gcc compiler: gcc
- os: osx - os: osx
compiler: clang compiler: clang
osx_image: xcode8 osx_image: xcode8
- os: osx
compiler: clang
osx_image: xcode8
env: CMAKE_OPTIONS="-D DYNLOAD_ENABLED:BOOL=FALSE -D MULTITHREAD_SUPPORT_ENABLED:BOOL=FALSE -D USE_STD_MAKE_SHARED:BOOL=TRUE" BUILD_ONLY=1
env: env:
global: global:
@ -47,13 +40,14 @@ env:
before_install: before_install:
- if [ "${GCC_VER}" != "" ]; then export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER" ; fi - if [ "${GCC_VER}" != "" ]; then export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER" ; fi
- if [ "${GCC_VER}" == "5" ]; then export CPPCHECK=1 COVERAGE=1 FUZZY_CMD="-D RUN_FUZZY_TESTS:BOOL=TRUE" ; fi
- pip install --user cpp-coveralls - pip install --user cpp-coveralls
script: script:
- cmake -D ENABLE_COVERAGE:BOOL=TRUE -D CMAKE_BUILD_TYPE:STRING=Debug $CMAKE_OPTIONS . - cmake -D ENABLE_COVERAGE:BOOL=TRUE -D CMAKE_BUILD_TYPE:STRING=Debug $FUZZY_CMD .
- cmake --build . -- -j2 - cmake --build . -- -j2
- if [ "${BUILD_ONLY}" != "1" ]; then ctest; fi - ctest
- if [ "${COVERAGE}" = "1" ]; then bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/master/codecov) -x $GCOV -a "-s `pwd`" ; fi - if [ ${COVERAGE} = 1 ]; then bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/master/codecov) -x $GCOV -a "-s `pwd`" ; fi
#after_script: #after_script:
# - if [ ${CPPCHECK} = 1 ]; then contrib/codeanalysis/runcppcheck.sh ; fi # - if [ ${CPPCHECK} = 1 ]; then contrib/codeanalysis/runcppcheck.sh ; fi

View File

@ -14,7 +14,6 @@ ELSE()
project(chaiscript) project(chaiscript)
option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE) option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE)
option(DYNLOAD_ENABLED "Dynamic Loading Support Enabled" TRUE)
option(BUILD_MODULES "Build Extra Modules (stl)" TRUE) option(BUILD_MODULES "Build Extra Modules (stl)" TRUE)
@ -222,16 +221,10 @@ if(NOT MULTITHREAD_SUPPORT_ENABLED)
add_definitions(-DCHAISCRIPT_NO_THREADS) add_definitions(-DCHAISCRIPT_NO_THREADS)
endif() endif()
if(NOT DYNLOAD_ENABLED)
add_definitions(-DCHAISCRIPT_NO_DYNLOAD)
endif()
if(CMAKE_HOST_UNIX) if(CMAKE_HOST_UNIX)
if(DYNLOAD_ENABLED)
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Haiku") if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
list(APPEND LIBS "dl") list(APPEND LIBS "dl")
endif() endif()
endif()
if(MULTITHREAD_SUPPORT_ENABLED) if(MULTITHREAD_SUPPORT_ENABLED)
if(CMAKE_COMPILER_IS_GNUCC) if(CMAKE_COMPILER_IS_GNUCC)
@ -434,9 +427,6 @@ if(BUILD_TESTING)
target_link_libraries(compiled_tests ${LIBS} ${CHAISCRIPT_LIBS}) target_link_libraries(compiled_tests ${LIBS} ${CHAISCRIPT_LIBS})
ADD_CATCH_TESTS(compiled_tests) ADD_CATCH_TESTS(compiled_tests)
add_executable(static_chaiscript_test unittests/static_chaiscript.cpp)
target_link_libraries(static_chaiscript_test ${LIBS})
add_test(NAME Static_ChaiScript_Test COMMAND static_chaiscript_test)
add_executable(boxed_cast_test unittests/boxed_cast_test.cpp) add_executable(boxed_cast_test unittests/boxed_cast_test.cpp)
target_link_libraries(boxed_cast_test ${LIBS}) target_link_libraries(boxed_cast_test ${LIBS})

View File

@ -216,11 +216,7 @@ namespace chaiscript {
static inline std::vector<Options> default_options() static inline std::vector<Options> default_options()
{ {
#ifdef CHAISCRIPT_NO_DYNLOAD
return {Options::No_Load_Modules, Options::External_Scripts};
#else
return {Options::Load_Modules, Options::External_Scripts}; return {Options::Load_Modules, Options::External_Scripts};
#endif
} }
} }
#endif #endif

View File

@ -67,63 +67,46 @@ namespace chaiscript
class Thread_Storage class Thread_Storage
{ {
public: public:
Thread_Storage() = default;
Thread_Storage(const Thread_Storage &) = delete; explicit Thread_Storage(void *t_key)
Thread_Storage(Thread_Storage &&) = delete; : m_key(t_key)
Thread_Storage &operator=(const Thread_Storage &) = delete; {
Thread_Storage &operator=(Thread_Storage &&) = delete; }
~Thread_Storage() ~Thread_Storage()
{ {
if (!destroyed) { t().erase(m_key);
t().erase(this);
}
} }
inline const T *operator->() const inline const T *operator->() const
{ {
return &(t()[const_cast<Thread_Storage *>(this)]); return &(t()[m_key]);
} }
inline const T &operator*() const inline const T &operator*() const
{ {
return t()[const_cast<Thread_Storage *>(this)]; return t()[m_key];
} }
inline T *operator->() inline T *operator->()
{ {
return &(t()[this]); return &(t()[m_key]);
} }
inline T &operator*() inline T &operator*()
{ {
return t()[this]; return t()[m_key];
} }
void *m_key;
private: private:
struct Map_Holder { static std::unordered_map<void*, T> &t()
std::unordered_map<Thread_Storage<T> *, T> map;
Map_Holder() = default;
Map_Holder(const Map_Holder &) = delete;
Map_Holder(Map_Holder &&) = delete;
Map_Holder& operator=(Map_Holder &&) = delete;
Map_Holder& operator=(const Map_Holder &&) = delete;
~Map_Holder() {
// here is the theory:
// * If the Map_Holder is destroyed before the Thread_Storage, a flag will get set
// * If destroyed after the Thread_Storage, the * will have been removed from `map` and nothing will happen
for(auto &elem : map) { elem.first->destroyed = true; }
}
};
static std::unordered_map<Thread_Storage<T> *, T> &t()
{ {
thread_local Map_Holder my_map; thread_local static std::unordered_map<void *, T> my_t;
return my_map.map; return my_t;
} }
bool destroyed{false};
}; };
#else // threading disabled #else // threading disabled

View File

@ -452,7 +452,7 @@ namespace chaiscript
}; };
explicit Dispatch_Engine(chaiscript::parser::ChaiScript_Parser_Base &parser) explicit Dispatch_Engine(chaiscript::parser::ChaiScript_Parser_Base &parser)
: m_stack_holder(), : m_stack_holder(this),
m_parser(parser) m_parser(parser)
{ {
} }

View File

@ -338,7 +338,9 @@ namespace chaiscript
: m_mutex(), : m_mutex(),
m_conversions(), m_conversions(),
m_convertableTypes(), m_convertableTypes(),
m_num_types(0) m_num_types(0),
m_thread_cache(this),
m_conversion_saves(this)
{ {
} }

View File

@ -36,13 +36,12 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if !defined(CHAISCRIPT_NO_DYNLOAD) && defined(_POSIX_VERSION) && !defined(__CYGWIN__) #if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#if defined(CHAISCRIPT_NO_DYNLOAD)
#include "chaiscript_unknown.hpp" #ifdef CHAISCRIPT_WINDOWS
#elif defined(CHAISCRIPT_WINDOWS)
#include "chaiscript_windows.hpp" #include "chaiscript_windows.hpp"
#elif _POSIX_VERSION #elif _POSIX_VERSION
#include "chaiscript_posix.hpp" #include "chaiscript_posix.hpp"
@ -243,7 +242,7 @@ namespace chaiscript
m_parser(std::move(parser)), m_parser(std::move(parser)),
m_engine(*m_parser) m_engine(*m_parser)
{ {
#if !defined(CHAISCRIPT_NO_DYNLOAD) && defined(_POSIX_VERSION) && !defined(__CYGWIN__) #if defined(_POSIX_VERSION) && !defined(__CYGWIN__)
// If on Unix, add the path of the current executable to the module search path // If on Unix, add the path of the current executable to the module search path
// as windows would do // as windows would do
@ -279,7 +278,6 @@ namespace chaiscript
build_eval_system(t_lib, t_opts); build_eval_system(t_lib, t_opts);
} }
#ifndef CHAISCRIPT_NO_DYNLOAD
/// \brief Constructor for ChaiScript. /// \brief Constructor for ChaiScript.
/// ///
/// This version of the ChaiScript constructor attempts to find the stdlib module to load /// This version of the ChaiScript constructor attempts to find the stdlib module to load
@ -309,12 +307,6 @@ namespace chaiscript
throw; throw;
} }
} }
#else // CHAISCRIPT_NO_DYNLOAD
explicit ChaiScript_Basic(std::unique_ptr<parser::ChaiScript_Parser_Base> &&parser,
std::vector<std::string> t_module_paths = {},
std::vector<std::string> t_use_paths = {},
const std::vector<chaiscript::Options> &t_opts = chaiscript::default_options()) = delete;
#endif
parser::ChaiScript_Parser_Base &get_parser() parser::ChaiScript_Parser_Base &get_parser()
{ {
@ -556,10 +548,6 @@ explicit ChaiScript_Basic(std::unique_ptr<parser::ChaiScript_Parser_Base> &&pars
/// \throw chaiscript::exception::load_module_error In the event that no matching module can be found. /// \throw chaiscript::exception::load_module_error In the event that no matching module can be found.
std::string load_module(const std::string &t_module_name) std::string load_module(const std::string &t_module_name)
{ {
#ifdef CHAISCRIPT_NO_DYNLOAD
(void)t_module_name; // -Wunused-parameter
throw chaiscript::exception::load_module_error("Loadable module support was disabled (CHAISCRIPT_NO_DYNLOAD)");
#else
std::vector<exception::load_module_error> errors; std::vector<exception::load_module_error> errors;
std::string version_stripped_name = t_module_name; std::string version_stripped_name = t_module_name;
size_t version_pos = version_stripped_name.find("-" + Build_Info::version()); size_t version_pos = version_stripped_name.find("-" + Build_Info::version());
@ -593,7 +581,6 @@ explicit ChaiScript_Basic(std::unique_ptr<parser::ChaiScript_Parser_Base> &&pars
} }
throw chaiscript::exception::load_module_error(t_module_name, errors); throw chaiscript::exception::load_module_error(t_module_name, errors);
#endif
} }
/// \brief Load a binary module from a dynamic library. Works on platforms that support /// \brief Load a binary module from a dynamic library. Works on platforms that support

View File

@ -2551,7 +2551,7 @@ namespace chaiscript
if (Statements(true)) { if (Statements(true)) {
if (m_position.has_more()) { if (m_position.has_more()) {
throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Unparsed input", File_Position(m_position.line, m_position.col), t_fname);
} else { } else {
build_match<eval::File_AST_Node<Tracer>>(0); build_match<eval::File_AST_Node<Tracer>>(0);
} }

View File

@ -16,11 +16,7 @@ namespace chaiscript
{ {
Loadable_Module(const std::string &, const std::string &) Loadable_Module(const std::string &, const std::string &)
{ {
#ifdef CHAISCRIPT_NO_DYNLOAD
throw chaiscript::exception::load_module_error("Loadable module support was disabled (CHAISCRIPT_NO_DYNLOAD)");
#else
throw chaiscript::exception::load_module_error("Loadable module support not available for your platform"); throw chaiscript::exception::load_module_error("Loadable module support not available for your platform");
#endif
} }
ModulePtr m_moduleptr; ModulePtr m_moduleptr;

View File

@ -567,17 +567,12 @@ struct JSONParser {
std::string val, exp_str; std::string val, exp_str;
char c = '\0'; char c = '\0';
bool isDouble = false; bool isDouble = false;
bool isNegative = false;
long exp = 0; long exp = 0;
if( offset < str.size() && str[offset] == '-' ) {
isNegative = true;
++offset;
}
for (; offset < str.size() ;) { for (; offset < str.size() ;) {
c = str[offset++]; c = str[offset++];
if( c >= '0' && c <= '9' ) { if( (c == '-') || (c >= '0' && c <= '9') ) {
val += c; val += c;
} else if( c == '.' && !isDouble ) { } else if( c == '.' ) {
val += c; val += c;
isDouble = true; isDouble = true;
} else { } else {
@ -613,12 +608,12 @@ struct JSONParser {
--offset; --offset;
if( isDouble ) { if( isDouble ) {
return JSON((isNegative?-1:1) * chaiscript::parse_num<double>( val ) * std::pow( 10, exp )); return JSON(chaiscript::parse_num<double>( val ) * std::pow( 10, exp ));
} else { } else {
if( !exp_str.empty() ) { if( !exp_str.empty() ) {
return JSON((isNegative?-1:1) * static_cast<double>(chaiscript::parse_num<long>( val )) * std::pow( 10, exp )); return JSON(static_cast<double>(chaiscript::parse_num<long>( val )) * std::pow( 10, exp ));
} else { } else {
return JSON((isNegative?-1:1) * chaiscript::parse_num<long>( val )); return JSON(chaiscript::parse_num<long>( val ));
} }
} }
} }

View File

@ -79,7 +79,7 @@ directory, and for more in-depth look at the language, the unit tests in the
"unittests" directory cover the most ground. "unittests" directory cover the most ground.
For examples of how to register parts of your C++ application, see For examples of how to register parts of your C++ application, see
"example.cpp" in the "samples" directory. Example.cpp is verbose and shows every "example.cpp" in the "src" directory. Example.cpp is verbose and shows every
possible way of working with the library. For further documentation generate possible way of working with the library. For further documentation generate
the doxygen documentation in the build folder or see the website the doxygen documentation in the build folder or see the website
http://www.chaiscript.com. http://www.chaiscript.com.
@ -87,21 +87,44 @@ http://www.chaiscript.com.
The shortest complete example possible follows: The shortest complete example possible follows:
```C++ /// main.cpp
/// main.cpp
#include <chaiscript/chaiscript.hpp> #include <chaiscript/chaiscript.hpp>
double function(int i, double j) double function(int i, double j)
{ {
return i * j; return i * j;
} }
int main() int main()
{ {
chaiscript::ChaiScript chai; chaiscript::ChaiScript chai;
chai.add(chaiscript::fun(&function), "function"); chai.add(chaiscript::fun(&function), "function");
double d = chai.eval<double>("function(3, 4.75);"); double d = chai.eval<double>("function(3, 4.75);");
} }
```
Or, if you want to compile the std lib into your code, which reduces
runtime requirements.
/// main.cpp
#include <chaiscript/chaiscript.hpp>
#include <chaiscript/chaiscript_stdlib.hpp>
double function(int i, double j)
{
return i * j;
}
int main()
{
chaiscript::ChaiScript chai(chaiscript::Std_Lib::library());
chai.add(chaiscript::fun(&function), "function");
double d = chai.eval<double>("function(3, 4.75);");
}

View File

@ -68,7 +68,6 @@ std::vector<std::string> default_search_paths()
{ {
std::vector<std::string> paths; std::vector<std::string> paths;
#ifndef CHAISCRIPT_NO_DYNLOAD
#ifdef CHAISCRIPT_WINDOWS // force no unicode #ifdef CHAISCRIPT_WINDOWS // force no unicode
CHAR path[4096]; CHAR path[4096];
int size = GetModuleFileNameA(0, path, sizeof(path) - 1); int size = GetModuleFileNameA(0, path, sizeof(path) - 1);
@ -138,7 +137,6 @@ std::vector<std::string> default_search_paths()
paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/"); paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/");
} }
#endif #endif
#endif // ifndef CHAISCRIPT_NO_DYNLOAD
return paths; return paths;
} }

View File

@ -71,7 +71,6 @@ std::vector<std::string> default_search_paths()
{ {
std::vector<std::string> paths; std::vector<std::string> paths;
#ifndef CHAISCRIPT_NO_DYNLOAD
#ifdef CHAISCRIPT_WINDOWS // force no unicode #ifdef CHAISCRIPT_WINDOWS // force no unicode
CHAR path[4096]; CHAR path[4096];
int size = GetModuleFileNameA(nullptr, path, sizeof(path)-1); int size = GetModuleFileNameA(nullptr, path, sizeof(path)-1);
@ -141,7 +140,6 @@ std::vector<std::string> default_search_paths()
paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/"); paths.push_back(exepath.substr(0, secondtolastslash) + "/lib/chaiscript/");
} }
#endif #endif
#endif // ifndef CHAISCRIPT_NO_DYNLOAD
return paths; return paths;
} }

View File

@ -1,2 +1 @@
assert_equal(from_json("100"), 100) assert_equal(from_json("100"), 100)
assert_equal(from_json("-100"), -100)

View File

@ -1,22 +1 @@
assert_equal(from_json("1.234"), 1.234) assert_equal(from_json("1.234"), 1.234)
assert_equal(from_json("-1.234"), -1.234)
auto caught = false;
try {
from_json("-1-5.3");
}
catch(e) {
assert_equal("JSON ERROR: Number: unexpected character '-'", e.what());
caught = true;
}
assert_equal(caught, true);
caught = false;
try {
from_json("-15.3.2");
}
catch(e) {
assert_equal("JSON ERROR: Number: unexpected character '.'", e.what());
caught = true;
}
assert_equal(caught, true);

View File

@ -1,2 +1,2 @@
assert_equal(from_json("[1,-2,3]"), [1,-2,3]) assert_equal(from_json("[1,2,3]"), [1,2,3])

View File

@ -2,9 +2,6 @@
#include <algorithm> #include <algorithm>
#ifdef CHAISCRIPT_NO_DYNLOAD
#include <chaiscript/chaiscript.hpp>
#endif
#include <chaiscript/chaiscript_basic.hpp> #include <chaiscript/chaiscript_basic.hpp>
#include <chaiscript/language/chaiscript_parser.hpp> #include <chaiscript/language/chaiscript_parser.hpp>
@ -60,22 +57,18 @@ int main()
} }
std::vector<std::string> modulepaths; std::vector<std::string> modulepaths;
#ifdef CHAISCRIPT_NO_DYNLOAD
chaiscript::ChaiScript chai(/* unused */modulepaths, usepaths);
#else
modulepaths.push_back(""); modulepaths.push_back("");
if (modulepath) if (modulepath)
{ {
modulepaths.push_back(modulepath); modulepaths.push_back(modulepath);
} }
// For this test we are going to load the dynamic stdlib // For this test we are going to load the dynamic stdlib
// to make sure it continues to work // to make sure it continues to work
chaiscript::ChaiScript_Basic chai( chaiscript::ChaiScript_Basic chai(
std::make_unique<chaiscript::parser::ChaiScript_Parser<chaiscript::eval::Noop_Tracer, chaiscript::optimizer::Optimizer_Default>>(), std::make_unique<chaiscript::parser::ChaiScript_Parser<chaiscript::eval::Noop_Tracer, chaiscript::optimizer::Optimizer_Default>>(),
modulepaths,usepaths); modulepaths,usepaths);
#endif
std::vector<std::shared_ptr<std::thread> > threads; std::vector<std::shared_ptr<std::thread> > threads;

View File

@ -1,5 +0,0 @@
#include <chaiscript/chaiscript.hpp>
static chaiscript::ChaiScript chai;
int main() {}