diff --git a/.decent_ci-Linux.yaml b/.decent_ci-Linux.yaml index 9bd15414..d0ae93d3 100644 --- a/.decent_ci-Linux.yaml +++ b/.decent_ci-Linux.yaml @@ -43,4 +43,5 @@ compilers: - name: custom_check commands: - ./contrib/check_for_tabs.rb + - ./contrib/check_for_todos.rb diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..c0a03815 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# Contributing to ChaiScript + +Thank you for contributing! + +# Pull Requests + +Please follow the existing style in the code you are patching. + + - two space indent + - no tabs EVER + - match the existing indentation level + +All ChaiScript commits are run through a large set of builds and analysis on all supported platforms. Those results are posted on the +[build dashboard](http://chaiscript.com/ChaiScript-BuildResults/index.html). No PR will be accepted until all tests pass. + +The build system has full integration with GitHub and you will be notified automatically if all tests have passed. + +# Issues + +Please do not post a "chaiscript is too slow", "chaiscript compiles too slowly", or "chaiscript needs more documentation" issue +without first reading the following notes. + +## ChaiScript is Too Slow + +We are actively working on constently improving the runtime performance of ChaiScript. With the performance being +[monitored with each commit](http://chaiscript.com/ChaiScript-BuildResults/performance.html). + +If you feel you *must* post an issue about performance, please post a complete example that illustrates the exact case you +feel should be better optimized. + +Any issue request regarding performance without a complete example of the issue experienced will be closed. + +## ChaiScript Compiles Too Slowly + +This is also something we are actively working on. If you need highly optimized build times, please see [this discussion +on the discourse site](http://discourse.chaiscript.com/t/slow-build-times/94). + +## ChaiScript Needs More Documentation + +If you have a question that is not addressed in the [cheatsheet](https://github.com/ChaiScript/ChaiScript/blob/develop/cheatsheet.md) +please open an issue so we can get the Cheatsheet updated. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..ed9c9fe6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,10 @@ + * Compiler Used: + * Operating System: + * Architecture (ARM/x86/32bit/64bit/etc): + + +### Expected Behavior + +### Actual Behavior + +### Minimal Example to Reproduce Behavior diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..9a54760b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +Issue this pull request references: # + +Changes proposed in this pull request + + - + - + - + diff --git a/CMakeLists.txt b/CMakeLists.txt index 47a3da18..dee4449b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,10 +175,10 @@ if(MSVC) # how to workaround or fix the error. So I'm disabling it globally. add_definitions(/wd4503) else() - add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG}) + add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command) + add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command) else() add_definitions(-Wnoexcept) endif() diff --git a/contrib/check_for_todos.rb b/contrib/check_for_todos.rb new file mode 100755 index 00000000..0bddcaaf --- /dev/null +++ b/contrib/check_for_todos.rb @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby + +require 'json' + +`grep -rPIHni 'todo' src/* include/* samples/*`.lines { |line| + if /(?.+(hpp|cpp|chai)):(?[0-9]+):(?.+)/ =~ line + puts(JSON.dump({:line => linenumber, :filename => filename, :tool => "todo_checker", :message => "todo: #{restofline.strip}", :messagetype => "info"})) + end +} + + diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 8d250ebf..b12347b6 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -113,6 +113,12 @@ namespace chaiscript { #endif } + template + Iter advance_copy(Iter iter, Distance distance) { + std::advance(iter, static_cast::difference_type>(distance)); + return iter; + } + } #endif diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 8c225c3b..1823c9da 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -248,13 +248,17 @@ namespace chaiscript m->add( fun( [](ContainerType &c, int index) -> typename ContainerType::reference { - return c.at(index); + /// \todo we are prefering to keep the key as 'int' to avoid runtime conversions + /// during dispatch. reevaluate + return c.at(static_cast(index)); }), "[]"); m->add( fun( [](const ContainerType &c, int index) -> typename ContainerType::const_reference { - return c.at(index); + /// \todo we are prefering to keep the key as 'int' to avoid runtime conversions + /// during dispatch. reevaluate + return c.at(static_cast(index)); }), "[]"); return m; diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 604d0d03..8a784ec4 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -49,10 +49,12 @@ namespace chaiscript #ifdef __GNUC__ #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wfloat-conversion" #endif /// \brief Represents any numeric type, generically. Used internally for generic operations between POD values diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 23dc7ee8..c4d6b285 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -635,7 +635,7 @@ namespace chaiscript loc_mask = 0x0000FFFF }; - uint_fast32_t loc = t_loc.load(std::memory_order_relaxed); + uint_fast32_t loc = t_loc; if (loc == 0) { @@ -647,17 +647,16 @@ namespace chaiscript for (auto s = stack_elem->begin(); s != stack_elem->end(); ++s ) { if (s->first == name) { - t_loc.store( static_cast(std::distance(stack.rbegin(), stack_elem) << 16) - | static_cast(std::distance(stack_elem->begin(), s)) - | static_cast(Loc::located) - | static_cast(Loc::is_local), - std::memory_order_relaxed); + t_loc = static_cast(std::distance(stack.rbegin(), stack_elem) << 16) + | static_cast(std::distance(stack_elem->begin(), s)) + | static_cast(Loc::located) + | static_cast(Loc::is_local); return s->second; } } } - t_loc.store( static_cast(Loc::located), std::memory_order_relaxed); + t_loc = static_cast(Loc::located); } else if (loc & static_cast(Loc::is_local)) { auto &stack = get_stack_data(); @@ -675,7 +674,7 @@ namespace chaiscript // no? is it a function object? auto obj = get_function_object_int(name, loc); - if (obj.first != loc) t_loc.store(uint_fast32_t(obj.first), std::memory_order_relaxed); + if (obj.first != loc) t_loc = uint_fast32_t(obj.first); return obj.second; @@ -738,9 +737,9 @@ namespace chaiscript std::shared_ptr> get_method_missing_functions() const { - uint_fast32_t method_missing_loc = m_method_missing_loc.load(std::memory_order_relaxed); + uint_fast32_t method_missing_loc = m_method_missing_loc; auto method_missing_funs = get_function("method_missing", method_missing_loc); - if (method_missing_funs.first != method_missing_loc) m_method_missing_loc.store(uint_fast32_t(method_missing_funs.first), std::memory_order_relaxed); + if (method_missing_funs.first != method_missing_loc) m_method_missing_loc = uint_fast32_t(method_missing_funs.first); return std::move(method_missing_funs.second); } @@ -938,9 +937,9 @@ namespace chaiscript Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, bool t_has_params, const Type_Conversions_State &t_conversions) { - uint_fast32_t loc = t_loc.load(std::memory_order_relaxed); + uint_fast32_t loc = t_loc; const auto funs = get_function(t_name, loc); - if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed); + if (funs.first != loc) t_loc = uint_fast32_t(funs.first); const auto do_attribute_call = [this](int l_num_params, const std::vector &l_params, const std::vector &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value @@ -1051,9 +1050,9 @@ namespace chaiscript Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, const Type_Conversions_State &t_conversions) const { - uint_fast32_t loc = t_loc.load(std::memory_order_relaxed); + uint_fast32_t loc = t_loc; const auto funs = get_function(t_name, loc); - if (funs.first != loc) t_loc.store(uint_fast32_t(funs.first), std::memory_order_relaxed); + if (funs.first != loc) t_loc = uint_fast32_t(funs.first); return dispatch::dispatch(*funs.second, params, t_conversions); } @@ -1446,7 +1445,7 @@ namespace chaiscript static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint) { if (t_c.size() > t_hint && t_c[t_hint].first == t_key) { - return t_c.begin() + t_hint; + return advance_copy(t_c.begin(), t_hint); } else { return find_keyed_value(t_c, t_key); } diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 14260857..c91a444c 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -32,11 +32,11 @@ namespace chaiscript CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void, bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) : m_type_info(t_ti), m_bare_type_info(t_bare_ti), - m_flags((t_is_const << is_const_flag) - + (t_is_reference << is_reference_flag) - + (t_is_pointer << is_pointer_flag) - + (t_is_void << is_void_flag) - + (t_is_arithmetic << is_arithmetic_flag)) + m_flags((static_cast(t_is_const) << is_const_flag) + + (static_cast(t_is_reference) << is_reference_flag) + + (static_cast(t_is_pointer) << is_pointer_flag) + + (static_cast(t_is_void) << is_void_flag) + + (static_cast(t_is_arithmetic) << is_arithmetic_flag)) { } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index f3aa0693..f6e9b562 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -505,10 +505,10 @@ namespace chaiscript // Let's see if this is a link that we should expand std::vector buf(2048); - const size_t pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size()); - if (pathlen > 0 && pathlen < buf.size()) + const auto pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size()); + if (pathlen > 0 && static_cast(pathlen) < buf.size()) { - dllpath = std::string(&buf.front(), pathlen); + dllpath = std::string(&buf.front(), static_cast(pathlen)); } m_module_paths.insert(m_module_paths.begin(), dllpath+"/"); diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 0bfabe56..684b766f 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -147,7 +147,7 @@ namespace chaiscript } size_t remaining() const { - return std::distance(m_pos, m_end); + return static_cast(std::distance(m_pos, m_end)); } char operator*() const { @@ -2213,8 +2213,8 @@ namespace chaiscript switch (m_operators[t_precedence]) { case(AST_Node_Type::Ternary_Cond) : - m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, - m_match_stack.begin() + m_match_stack.size() - 1); + m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), + advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); if (Symbol(":")) { if (!Operator(t_precedence+1)) { throw exception::eval_error("Incomplete " @@ -2239,7 +2239,8 @@ namespace chaiscript case(AST_Node_Type::Bitwise_Or) : case(AST_Node_Type::Comparison) : assert(m_match_stack.size() > 1); - m_match_stack.erase(m_match_stack.begin() + m_match_stack.size() - 2, m_match_stack.begin() + m_match_stack.size() - 1); + m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), + advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); build_match(prev_stack_top, oper->text); break; diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index 56f28e75..1d9aac23 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -605,7 +605,7 @@ namespace { Number = std::stod( val ) * std::pow( 10, exp ); else { if( !exp_str.empty() ) - Number = std::stol( val ) * std::pow( 10, exp ); + Number = static_cast(std::stol( val )) * std::pow( 10, exp ); else Number = std::stol( val ); } diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp index 0ccc08dd..6b91fed9 100644 --- a/samples/fun_call_performance.cpp +++ b/samples/fun_call_performance.cpp @@ -89,24 +89,24 @@ std::vector default_search_paths() std::vector buf(2048); ssize_t size = -1; - if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1) + if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) > 0) { - exepath = std::string(&buf.front(), size); + exepath = std::string(&buf.front(), static_cast(size)); } if (exepath.empty()) { - if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1) + if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) > 0) { - exepath = std::string(&buf.front(), size); + exepath = std::string(&buf.front(), static_cast(size)); } } if (exepath.empty()) { - if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1) + if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) > 0) { - exepath = std::string(&buf.front(), size); + exepath = std::string(&buf.front(), static_cast(size)); } } diff --git a/src/main.cpp b/src/main.cpp index 7f203cdd..b4d5fa80 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,24 +88,24 @@ std::vector default_search_paths() std::vector buf(2048); ssize_t size = -1; - if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) != -1) + if ((size = readlink("/proc/self/exe", &buf.front(), buf.size())) >= 0) { - exepath = std::string(&buf.front(), size); + exepath = std::string(&buf.front(), static_cast(size)); } if (exepath.empty()) { - if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) != -1) + if ((size = readlink("/proc/curproc/file", &buf.front(), buf.size())) >= 0) { - exepath = std::string(&buf.front(), size); + exepath = std::string(&buf.front(), static_cast(size)); } } if (exepath.empty()) { - if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) != -1) + if ((size = readlink("/proc/self/path/a.out", &buf.front(), buf.size())) >= 0) { - exepath = std::string(&buf.front(), size); + exepath = std::string(&buf.front(), static_cast(size)); } } diff --git a/unittests/multithreaded_test.cpp b/unittests/multithreaded_test.cpp index 866a3ca8..225353c0 100644 --- a/unittests/multithreaded_test.cpp +++ b/unittests/multithreaded_test.cpp @@ -15,7 +15,7 @@ int expected_value(int num_iters) return i; } -void do_work(chaiscript::ChaiScript &c, int id) +void do_work(chaiscript::ChaiScript &c, const size_t id) { try{ std::stringstream ss; @@ -67,23 +67,23 @@ int main() std::vector > threads; // Ensure at least two, but say only 7 on an 8 core processor - int num_threads = std::max(static_cast(std::thread::hardware_concurrency()) - 1, 2); + size_t num_threads = static_cast(std::max(static_cast(std::thread::hardware_concurrency()) - 1, 2)); std::cout << "Num threads: " << num_threads << '\n'; - for (int i = 0; i < num_threads; ++i) + for (size_t i = 0; i < num_threads; ++i) { threads.push_back(std::make_shared(do_work, std::ref(chai), i)); } - for (int i = 0; i < num_threads; ++i) + for (size_t i = 0; i < num_threads; ++i) { threads[i]->join(); } - for (int i = 0; i < num_threads; ++i) + for (size_t i = 0; i < num_threads; ++i) { std::stringstream ss; ss << i; @@ -92,7 +92,7 @@ int main() return EXIT_FAILURE; } - if (chai.eval("getid(" + ss.str() + ")") != i) + if (chai.eval("getid(" + ss.str() + ")") != static_cast(i)) { return EXIT_FAILURE; }