Add crashes and fixes found during fuzzy testing
* Let unhandled exceptions propogate to user * Report eval_error when break statement is not in loop * Fix handling of 0 length scripts closes #193 * Don't crash on arity mismatch - Specifically affects the case where no overloads exist for a given function * Fix error printing for `bind` calls * Handle unexpected continue statement * Check arity during bind * Don't allow arith conversion on variadic function * Correct `bind` parameter match count * Add in expected Boxed_Value exception cases * Check access to AST, don't allow `;` in func def * Don't attempt arithmetic unary & call * Don't crash on 0 param call to `bind` * Catch errors during member function dispatch * Properly handle type of const bool &
This commit is contained in:
@@ -14,13 +14,14 @@ env:
|
||||
before_install:
|
||||
- export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER"
|
||||
- if [ "$GCC_VER" = "4.8" ]; then export COVERAGE=1 CPPCHECK=1; fi
|
||||
- if [ ${COVERAGE} = 1 ]; then export FUZZY_CMD="-D RUN_FUZZY_TESTS:BOOL=TRUE"; fi
|
||||
- sudo pip install cpp-coveralls
|
||||
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -qq g++-$GCC_VER
|
||||
|
||||
script:
|
||||
- if [ ${COVERITY_SCAN_BRANCH} != 1 ]; then cmake -D ENABLE_COVERAGE:BOOL=TRUE -D CMAKE_BUILD_TYPE:STRING=Debug . ; fi
|
||||
- if [ ${COVERITY_SCAN_BRANCH} != 1 ]; then cmake -D ENABLE_COVERAGE:BOOL=TRUE -D CMAKE_BUILD_TYPE:STRING=Debug $FUZZY_CMD . ; fi
|
||||
- if [ ${COVERITY_SCAN_BRANCH} != 1 ]; then make -j2 ; fi
|
||||
- make test
|
||||
- if [ ${COVERAGE} = 1 ]; then bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/master/codecov) -x $GCOV -a "-s `pwd`" ; fi
|
||||
|
@@ -18,6 +18,7 @@ option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE)
|
||||
|
||||
option(BUILD_MODULES "Build Extra Modules (stl)" TRUE)
|
||||
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
|
||||
option(RUN_FUZZY_TESTS "Run tests generated by AFL" FALSE)
|
||||
option(USE_STD_MAKE_SHARED "Use std::make_shared instead of chaiscript::make_shared" FALSE)
|
||||
|
||||
mark_as_advanced(USE_STD_MAKE_SHARED)
|
||||
@@ -269,9 +270,51 @@ if(BUILD_MODULES)
|
||||
endif()
|
||||
|
||||
file(GLOB UNIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/unittests/ ${CMAKE_CURRENT_SOURCE_DIR}/unittests/*.chai ${CMAKE_CURRENT_SOURCE_DIR}/unittests/3.x/*.chai)
|
||||
|
||||
list(SORT UNIT_TESTS)
|
||||
|
||||
|
||||
if (RUN_FUZZY_TESTS)
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/unittests")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xjf ${CMAKE_CURRENT_SOURCE_DIR}/unittests/fuzzy_tests-2015-07-16.tar.bz2
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/unittests
|
||||
)
|
||||
|
||||
|
||||
file(GLOB FUZZY_CRASH_TESTS RELATIVE ${CMAKE_BINARY_DIR}/unittests/ ${CMAKE_BINARY_DIR}/unittests/fuzzy_tests/crashes/id*)
|
||||
list(SORT FUZZY_CRASH_TESTS)
|
||||
|
||||
file(GLOB FUZZY_EXCEPTION_TESTS RELATIVE ${CMAKE_BINARY_DIR}/unittests/ ${CMAKE_BINARY_DIR}/unittests/fuzzy_tests/exceptions/id*)
|
||||
list(SORT FUZZY_EXCEPTION_TESTS)
|
||||
|
||||
|
||||
foreach(filename ${FUZZY_CRASH_TESTS})
|
||||
message(STATUS "Adding test ${filename}")
|
||||
add_test(${filename} chai "-e" ${CMAKE_BINARY_DIR}/unittests/fuzzy_tests/crashes/unit_test.inc ${CMAKE_BINARY_DIR}/unittests/${filename})
|
||||
endforeach()
|
||||
|
||||
set_property(TEST ${FUZZY_CRASH_TESTS}
|
||||
PROPERTY ENVIRONMENT
|
||||
"CHAI_USE_PATH=${CMAKE_BINARY_DIR}/unittests/"
|
||||
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
)
|
||||
|
||||
foreach(filename ${FUZZY_EXCEPTION_TESTS})
|
||||
message(STATUS "Adding test ${filename}")
|
||||
add_test(${filename} chai "--exception" ${CMAKE_BINARY_DIR}/unittests/fuzzy_tests/exceptions/unit_test.inc ${CMAKE_BINARY_DIR}/unittests/${filename})
|
||||
endforeach()
|
||||
|
||||
set_property(TEST ${FUZZY_EXCEPTION_TESTS}
|
||||
PROPERTY ENVIRONMENT
|
||||
"CHAI_USE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/unittests/"
|
||||
"CHAI_MODULE_PATH=${CMAKE_CURRENT_BINARY_DIR}/"
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
if(BUILD_TESTING)
|
||||
|
||||
# Add catch tests macro
|
||||
|
@@ -304,13 +304,17 @@ namespace chaiscript
|
||||
/// the remaining parameters are the args to bind into the result
|
||||
static Boxed_Value bind_function(const std::vector<Boxed_Value> ¶ms)
|
||||
{
|
||||
if (params.size() < 2)
|
||||
{
|
||||
throw exception::arity_error(static_cast<int>(params.size()), 2);
|
||||
if (params.empty()) {
|
||||
throw exception::arity_error(0, 1);
|
||||
}
|
||||
|
||||
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
|
||||
|
||||
if (f->get_arity() != -1 && size_t(f->get_arity()) != params.size() - 1)
|
||||
{
|
||||
throw exception::arity_error(static_cast<int>(params.size()), f->get_arity());
|
||||
}
|
||||
|
||||
return Boxed_Value(Const_Proxy_Function(std::make_shared<dispatch::Bound_Function>(std::move(f),
|
||||
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "../chaiscript_defines.hpp"
|
||||
#include "../chaiscript_threading.hpp"
|
||||
#include "bad_boxed_cast.hpp"
|
||||
#include "boxed_cast.hpp"
|
||||
#include "boxed_cast_helper.hpp"
|
||||
#include "boxed_value.hpp"
|
||||
@@ -873,7 +874,14 @@ namespace chaiscript
|
||||
std::vector<Boxed_Value> remaining_params{l_params.begin() + l_num_params, l_params.end()};
|
||||
Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions);
|
||||
if (!remaining_params.empty() || bv.get_type_info().bare_equal(user_type<dispatch::Proxy_Function_Base>())) {
|
||||
return (*boxed_cast<const dispatch::Proxy_Function_Base *>(bv))(remaining_params, l_conversions);
|
||||
auto func = boxed_cast<std::shared_ptr<const dispatch::Proxy_Function_Base>>(bv);
|
||||
try {
|
||||
return (*func)(remaining_params, l_conversions);
|
||||
} catch (const chaiscript::exception::bad_boxed_cast &) {
|
||||
} catch (const chaiscript::exception::arity_error &) {
|
||||
} catch (const chaiscript::exception::guard_error &) {
|
||||
}
|
||||
throw chaiscript::exception::dispatch_error(remaining_params, std::vector<Const_Proxy_Function>{func});
|
||||
} else {
|
||||
return bv;
|
||||
}
|
||||
|
@@ -149,7 +149,11 @@ namespace chaiscript
|
||||
|
||||
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms, const chaiscript::Type_Conversions &t_conversions) const
|
||||
{
|
||||
return do_call(params, t_conversions);
|
||||
if (m_arity < 0 || size_t(m_arity) == params.size()) {
|
||||
return do_call(params, t_conversions);
|
||||
} else {
|
||||
throw exception::arity_error(static_cast<int>(params.size()), m_arity);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a vector containing all of the types of the parameters the function returns/takes
|
||||
@@ -420,17 +424,11 @@ namespace chaiscript
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||
{
|
||||
if (m_arity < 0 || params.size() == size_t(m_arity))
|
||||
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
|
||||
{
|
||||
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
|
||||
{
|
||||
return m_f(params);
|
||||
} else {
|
||||
throw exception::guard_error();
|
||||
}
|
||||
|
||||
return m_f(params);
|
||||
} else {
|
||||
throw exception::arity_error(static_cast<int>(params.size()), m_arity);
|
||||
throw exception::guard_error();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,19 +726,14 @@ namespace chaiscript
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
|
||||
{
|
||||
if (params.size() == 1)
|
||||
const Boxed_Value &bv = params[0];
|
||||
if (bv.is_const())
|
||||
{
|
||||
const Boxed_Value &bv = params[0];
|
||||
if (bv.is_const())
|
||||
{
|
||||
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
|
||||
return detail::Handle_Return<const typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
||||
} else {
|
||||
Class *o = boxed_cast<Class *>(bv, &t_conversions);
|
||||
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
||||
}
|
||||
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
|
||||
return detail::Handle_Return<const typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
||||
} else {
|
||||
throw exception::arity_error(static_cast<int>(params.size()), 1);
|
||||
Class *o = boxed_cast<Class *>(bv, &t_conversions);
|
||||
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,6 +780,9 @@ namespace chaiscript
|
||||
const Type_Conversions &t_conversions)
|
||||
{
|
||||
const std::vector<Type_Info> &types = t_func->get_param_types();
|
||||
|
||||
if (t_func->get_arity() == -1) return false;
|
||||
|
||||
assert(plist.size() == types.size() - 1);
|
||||
|
||||
return std::mismatch(plist.begin(), plist.end(),
|
||||
|
@@ -29,7 +29,7 @@ namespace chaiscript
|
||||
class Type_Info
|
||||
{
|
||||
public:
|
||||
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
|
||||
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_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
|
||||
@@ -38,7 +38,7 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
CHAISCRIPT_CONSTEXPR Type_Info()
|
||||
CHAISCRIPT_CONSTEXPR Type_Info()
|
||||
: m_type_info(nullptr), m_bare_type_info(nullptr),
|
||||
m_is_const(false), m_is_reference(false), m_is_pointer(false),
|
||||
m_is_void(false), m_is_arithmetic(false),
|
||||
@@ -134,13 +134,13 @@ namespace chaiscript
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
static Type_Info get()
|
||||
static Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value,
|
||||
std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
(std::is_arithmetic<T>::value || std::is_arithmetic<typename std::remove_reference<T>::type>::value)
|
||||
&& !std::is_same<typename std::remove_const<T>::type, bool>::value,
|
||||
&& !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(T),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@@ -151,11 +151,11 @@ namespace chaiscript
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
static Type_Info get()
|
||||
static Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(std::shared_ptr<T> ),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@@ -166,11 +166,11 @@ namespace chaiscript
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
static Type_Info get()
|
||||
static Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(const std::shared_ptr<T> &),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@@ -181,11 +181,11 @@ namespace chaiscript
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
static Type_Info get()
|
||||
static Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(std::reference_wrapper<T> ),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
@@ -196,11 +196,11 @@ namespace chaiscript
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
static Type_Info get()
|
||||
static Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(const std::reference_wrapper<T> &),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
|
@@ -276,10 +276,13 @@ namespace chaiscript
|
||||
template<typename T>
|
||||
static std::string format_location(const T &t)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "(" << t->filename() << " " << t->start().line << ", " << t->start().column << ")";
|
||||
|
||||
return oss.str();
|
||||
if (t) {
|
||||
std::ostringstream oss;
|
||||
oss << "(" << t->filename() << " " << t->start().line << ", " << t->start().column << ")";
|
||||
return oss.str();
|
||||
} else {
|
||||
return "(internal)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -1117,11 +1117,22 @@ namespace chaiscript
|
||||
AST_Node(std::move(t_ast_node_text), AST_Node_Type::File, std::move(t_loc), std::move(t_children)) { }
|
||||
virtual ~File_AST_Node() {}
|
||||
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE {
|
||||
const auto num_children = children.size();
|
||||
for (size_t i = 0; i < num_children-1; ++i) {
|
||||
children[i]->eval(t_ss);
|
||||
try {
|
||||
const auto num_children = children.size();
|
||||
|
||||
if (num_children > 0) {
|
||||
for (size_t i = 0; i < num_children-1; ++i) {
|
||||
children[i]->eval(t_ss);
|
||||
}
|
||||
return children.back()->eval(t_ss);
|
||||
} else {
|
||||
return Boxed_Value();
|
||||
}
|
||||
} catch (const detail::Continue_Loop &) {
|
||||
throw exception::eval_error("Unexpected `continue` statement outside of a loop");
|
||||
} catch (const detail::Break_Loop &) {
|
||||
throw exception::eval_error("Unexpected `break` statement outside of a loop");
|
||||
}
|
||||
return children.back()->eval(t_ss);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1158,7 +1169,7 @@ namespace chaiscript
|
||||
|
||||
try {
|
||||
// short circuit arithmetic operations
|
||||
if (m_oper != Operators::invalid && bv.get_type_info().is_arithmetic())
|
||||
if (m_oper != Operators::invalid && m_oper != Operators::bitwise_and && bv.get_type_info().is_arithmetic())
|
||||
{
|
||||
return Boxed_Number::do_oper(m_oper, bv);
|
||||
} else {
|
||||
|
@@ -194,6 +194,7 @@ namespace chaiscript
|
||||
|
||||
/// Returns the front-most AST node
|
||||
AST_NodePtr ast() const {
|
||||
if (m_match_stack.empty()) throw exception::eval_error("Attempted to access AST of failed parse.");
|
||||
return m_match_stack.front();
|
||||
}
|
||||
|
||||
@@ -261,7 +262,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
AST_NodePtr optimized_ast(bool t_optimize_blocks = false, bool t_optimize_returns = true) {
|
||||
AST_NodePtr p = m_match_stack.front();
|
||||
AST_NodePtr p = ast();
|
||||
//Note, optimize_blocks is currently broken; it breaks stack management
|
||||
if (t_optimize_blocks) { optimize_blocks(p); }
|
||||
if (t_optimize_returns) { optimize_returns(p); }
|
||||
@@ -1208,37 +1209,32 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
/// Reads an end-of-line group from input, without skipping initial whitespace
|
||||
bool Eol_() {
|
||||
bool Eol_(const bool t_eos = false) {
|
||||
bool retval = false;
|
||||
|
||||
if (has_more_input() && (Symbol_("\r\n") || Char_('\n'))) {
|
||||
retval = true;
|
||||
++m_line;
|
||||
m_col = 1;
|
||||
} else if (has_more_input() && Char_(';')) {
|
||||
} else if (has_more_input() && !t_eos && Char_(';')) {
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// Reads (and potentially captures) an end-of-line group from input
|
||||
bool Eol(const bool t_capture = false) {
|
||||
/// Reads until the end of the current statement
|
||||
bool Eos() {
|
||||
SkipWS();
|
||||
|
||||
if (!t_capture) {
|
||||
return Eol_();
|
||||
} else {
|
||||
const auto start = m_input_pos;
|
||||
const auto prev_col = m_col;
|
||||
const auto prev_line = m_line;
|
||||
if (Eol_()) {
|
||||
m_match_stack.push_back(make_node<eval::Eol_AST_Node>(std::string(start, m_input_pos), prev_line, prev_col));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Eol_(true);
|
||||
}
|
||||
|
||||
/// Reads (and potentially captures) an end-of-line group from input
|
||||
bool Eol() {
|
||||
SkipWS();
|
||||
|
||||
return Eol_();
|
||||
}
|
||||
|
||||
/// Reads a comma-separated list of values from input. Id's only, no types allowed
|
||||
@@ -1441,7 +1437,7 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
while (Eol()) {}
|
||||
while (Eos()) {}
|
||||
|
||||
if (Char(':')) {
|
||||
if (!Operator()) {
|
||||
|
27
src/main.cpp
27
src/main.cpp
@@ -297,6 +297,8 @@ int main(int argc, char *argv[])
|
||||
chai.add(chaiscript::fun(&get_eval_error), "get_eval_error");
|
||||
chai.add(chaiscript::fun(&now), "now");
|
||||
|
||||
bool eval_error_ok = false;
|
||||
bool boxed_exception_ok = false;
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if ( i == 0 && argc > 1 ) {
|
||||
@@ -327,6 +329,12 @@ int main(int argc, char *argv[])
|
||||
arg = "print(version())" ;
|
||||
} else if ( arg == "-h" || arg == "--help" ) {
|
||||
arg = "help(-1)";
|
||||
} else if ( arg == "-e" || arg == "--evalerrorok" ) {
|
||||
eval_error_ok = true;
|
||||
continue;
|
||||
} else if ( arg == "--exception" ) {
|
||||
boxed_exception_ok = true;
|
||||
continue;
|
||||
} else if ( arg == "-i" || arg == "--interactive" ) {
|
||||
mode = eInteractive ;
|
||||
} else if ( arg.find('-') == 0 ) {
|
||||
@@ -352,12 +360,23 @@ int main(int argc, char *argv[])
|
||||
catch (const chaiscript::exception::eval_error &ee) {
|
||||
std::cout << ee.pretty_print();
|
||||
std::cout << '\n';
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (!eval_error_ok) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
std::cout << e.what() << '\n';
|
||||
return EXIT_FAILURE;
|
||||
catch (const chaiscript::Boxed_Value &e) {
|
||||
std::cout << "Unhandled exception thrown of type " << e.get_type_info().name() << '\n';
|
||||
|
||||
if (!boxed_exception_ok) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// catch (std::exception &e) {
|
||||
// std::cout << e.what() << '\n';
|
||||
// return EXIT_FAILURE;
|
||||
// }
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
BIN
unittests/fuzzy_tests-2015-07-16.tar.bz2
Normal file
BIN
unittests/fuzzy_tests-2015-07-16.tar.bz2
Normal file
Binary file not shown.
@@ -5,33 +5,58 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
void test_type(const chaiscript::Type_Info &ti, bool t_is_const, bool t_is_pointer, bool t_is_reference, bool t_is_void,
|
||||
bool t_is_undef)
|
||||
#ifdef CHAISCRIPT_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4190 4640 28251 4702 6330)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
#ifdef __llvm__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal"
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
TEST_CASE("Type_Info objects generate expected results")
|
||||
{
|
||||
if (ti.is_const() == t_is_const
|
||||
&& ti.is_pointer() == t_is_pointer
|
||||
&& ti.is_reference() == t_is_reference
|
||||
&& ti.is_void() == t_is_void
|
||||
&& ti.is_undef() == t_is_undef)
|
||||
const auto test_type = [](const chaiscript::Type_Info &ti, bool t_is_const, bool t_is_pointer, bool t_is_reference, bool t_is_void,
|
||||
bool t_is_undef, bool t_is_arithmetic)
|
||||
{
|
||||
return;
|
||||
} else {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
CHECK(ti.is_const() == t_is_const);
|
||||
CHECK(ti.is_pointer() == t_is_pointer);
|
||||
CHECK(ti.is_reference() == t_is_reference);
|
||||
CHECK(ti.is_void() == t_is_void);
|
||||
CHECK(ti.is_undef() == t_is_undef);
|
||||
CHECK(ti.is_arithmetic() == t_is_arithmetic);
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test_type(chaiscript::user_type<void>(), false, false, false, true, false);
|
||||
test_type(chaiscript::user_type<const int>(), true, false, false, false, false);
|
||||
test_type(chaiscript::user_type<const int &>(), true, false, true, false, false);
|
||||
test_type(chaiscript::user_type<int>(), false, false, false, false, false);
|
||||
test_type(chaiscript::user_type<int *>(), false, true, false, false, false);
|
||||
test_type(chaiscript::user_type<const int *>(), true, true, false, false, false);
|
||||
test_type(chaiscript::Type_Info(), false, false, false, false, true);
|
||||
SECTION("void") { test_type(chaiscript::user_type<void>(), false, false, false, true, false, false); }
|
||||
SECTION("const int") { test_type(chaiscript::user_type<const int>(), true, false, false, false, false, true); }
|
||||
SECTION("const int &") { test_type(chaiscript::user_type<const int &>(), true, false, true, false, false, true); }
|
||||
SECTION("int") { test_type(chaiscript::user_type<int>(), false, false, false, false, false, true); }
|
||||
SECTION("int *") { test_type(chaiscript::user_type<int *>(), false, true, false, false, false, false); }
|
||||
SECTION("const int *") { test_type(chaiscript::user_type<const int *>(), true, true, false, false, false, false); }
|
||||
SECTION("const bool &") { test_type(chaiscript::user_type<const bool &>(), true, false, true, false, false, false); }
|
||||
SECTION("default") { test_type(chaiscript::Type_Info(), false, false, false, false, true, false); }
|
||||
|
||||
std::cout << "Size of Type_Info " << sizeof(chaiscript::Type_Info) << '\n';
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user