Skip to content

Commit 926e962

Browse files
committed
Merge remote-tracking branch 'origin/release-4.x'
Conflicts: .travis.yml CMakeLists.txt include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/language/chaiscript_common.hpp
2 parents 372cf73 + caf4495 commit 926e962

16 files changed

Lines changed: 219 additions & 86 deletions

.travis.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ script:
1818
- find CMakeFiles/ -name "*.gc*" -exec mv {} gcov/ \;
1919
- $GCOV -d -o gcov gcov/*.gcda
2020
- coveralls -n -E ".*\.cpp"
21+
after_script:
22+
- contrib/codeanalysis/runcppcheck.sh
2123
notifications:
22-
recipients:
23-
- jason@emptycrate.com
2424
email:
25+
recipients:
26+
- jason@emptycrate.com
2527
on_success: always
2628
on_failure: always
27-
29+
env:
30+
global:
31+
secure: LCUAKUCRtFp2ak81nVLR+jx0C9+Drwx1OR4VzuvH+HNGWFdUZmAIV3R84euDqFC5cUhYYipaeMbiSOJUHE4MNlL58eQZryED6KSL7k7SgxOLpFSspMvuMjIYZLlBWpBneCR/EMDilu+zXEnASfVUMPuLmtY1GAyfSoZboqFProc=

CMakeLists.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ endif()
1818
option(BUILD_MODULES "Build Extra Modules (stl, reflection)" TRUE)
1919
option(BUILD_SAMPLES "Build Samples Folder" FALSE)
2020

21+
set(EXTRA_LINKER_FLAGS "")
22+
23+
if (CMAKE_COMPILER_IS_GNUCC)
24+
option(ENABLE_COVERAGE "Enable Coverage Reporting in GCC" FALSE)
25+
26+
if (ENABLE_COVERAGE)
27+
add_definitions(--coverage -O0)
28+
SET(EXTRA_LINKER_FLAGS ${EXTRA_LINKER_FLAGS} "--coverage")
29+
endif()
30+
31+
endif()
32+
2133
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR}")
2234
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.svn")
2335
list(APPEND CPACK_SOURCE_IGNORE_FILES "\\\\.git")
@@ -30,7 +42,7 @@ set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt"
3042

3143
set(CPACK_PACKAGE_VERSION_MAJOR 5)
3244
set(CPACK_PACKAGE_VERSION_MINOR 3)
33-
set(CPACK_PACKAGE_VERSION_PATCH 0)
45+
set(CPACK_PACKAGE_VERSION_PATCH 1)
3446

3547
set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval")
3648
set(CPACK_PACKAGE_VENDOR "ChaiScript.com")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
pushd ..
4+
wget http://sourceforge.net/projects/cppcheck/files/cppcheck/1.64/cppcheck-1.64.tar.bz2
5+
tar -xvf cppcheck-1.64.tar.bz2
6+
cd cppcheck-1.64
7+
make -j2
8+
popd
9+
../cppcheck-1.64/cppcheck --enable=all --inconclusive -I include --inline-suppr --std=c++11 --platform=unix64 src/main.cpp src/chai*.cpp --template ' - __{severity}__: [{file}:{line}](../blob/TRAVIS_COMMIT/{file}#L{line}) {message} ({id})' 2>output
10+
sed -i "s/TRAVIS_COMMIT/${TRAVIS_COMMIT}/g" output
11+
echo -n '{ "body": " ' > output.json
12+
echo -n `awk '{printf "%s\\\\n", $0;}' output` >> output.json
13+
echo -n '"}' >> output.json
14+
if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then curl -H "Authorization: token ${TOKEN}" --request POST --data @output.json https://api.github.com/repos/ChaiScript/ChaiScript/commits/${TRAVIS_COMMIT}/comments; else curl -H "Authorization: token ${TOKEN}" --request POST --data @output.json https://api.github.com/repos/ChaiScript/ChaiScript/issues/${TRAVIS_PULL_REQUEST}/comments; fi
15+
16+

include/chaiscript/dispatchkit/bootstrap.hpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,14 +304,6 @@ namespace chaiscript
304304
static void throw_exception(const Boxed_Value &bv) {
305305
throw bv;
306306
}
307-
308-
static std::shared_ptr<chaiscript::detail::Dispatch_Engine> bootstrap2(
309-
std::shared_ptr<chaiscript::detail::Dispatch_Engine> e
310-
= std::shared_ptr<chaiscript::detail::Dispatch_Engine> (new chaiscript::detail::Dispatch_Engine()))
311-
{
312-
e->add(user_type<void>(), "void");
313-
return e;
314-
}
315307

316308
static std::string what(const std::exception &e)
317309
{

include/chaiscript/dispatchkit/boxed_cast.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,18 @@ namespace chaiscript
7979
if (std::is_polymorphic<typename detail::Stripped_Type<Type>::type>::value && t_conversions)
8080
{
8181
try {
82+
// std::cout << "trying an up conversion " << typeid(Type).name() << std::endl;
8283
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
8384
// either way, we are not responsible if it doesn't work
8485
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_cast<Type>(bv), t_conversions);
85-
} catch (const chaiscript::detail::exception::bad_any_cast &) {
86-
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
86+
} catch (...) {
87+
try {
88+
// std::cout << "trying a down conversion " << typeid(Type).name() << std::endl;
89+
// try going the other way - down the inheritance graph
90+
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_dynamic_down_cast<Type>(bv), t_conversions);
91+
} catch (const chaiscript::detail::exception::bad_any_cast &) {
92+
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
93+
}
8794
}
8895
} else {
8996
// If it's not polymorphic, just throw the error, don't waste the time on the

include/chaiscript/dispatchkit/boxed_number.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ namespace chaiscript
307307
}
308308

309309
template<typename Source>
310-
std::string to_string_aux(const Boxed_Value &v) const
310+
static std::string to_string_aux(const Boxed_Value &v)
311311
{
312312
std::ostringstream oss;
313313
oss << *static_cast<const Source *>(v.get_const_ptr());
@@ -520,7 +520,7 @@ namespace chaiscript
520520
return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv);
521521
}
522522

523-
void validate_boxed_number(const Boxed_Value &v)
523+
static void validate_boxed_number(const Boxed_Value &v)
524524
{
525525
const Type_Info &inp_ = v.get_type_info();
526526
if (inp_ == typeid(bool))

include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp

Lines changed: 73 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,13 @@ namespace chaiscript
4848
{
4949
public:
5050
virtual Boxed_Value convert(const Boxed_Value &derived) const = 0;
51+
virtual Boxed_Value convert_down(const Boxed_Value &base) const = 0;
5152

52-
const Type_Info &base()
53+
const Type_Info &base() const
5354
{
5455
return m_base;
5556
}
56-
const Type_Info &derived()
57+
const Type_Info &derived() const
5758
{
5859
return m_derived;
5960
}
@@ -72,59 +73,74 @@ namespace chaiscript
7273

7374
};
7475

75-
template<typename Base, typename Derived>
76-
class Dynamic_Conversion_Impl : public Dynamic_Conversion
77-
{
78-
public:
79-
Dynamic_Conversion_Impl()
80-
: Dynamic_Conversion(user_type<Base>(), user_type<Derived>())
81-
{
82-
}
83-
84-
virtual Boxed_Value convert(const Boxed_Value &t_derived) const
85-
{
86-
if (t_derived.get_type_info().bare_equal(user_type<Derived>()))
76+
template<typename From, typename To>
77+
class Dynamic_Caster
78+
{
79+
public:
80+
static Boxed_Value cast(const Boxed_Value &t_from)
8781
{
88-
if (t_derived.is_pointer())
82+
if (t_from.get_type_info().bare_equal(user_type<From>()))
8983
{
90-
// Dynamic cast out the contained boxed value, which we know is the type we want
91-
if (t_derived.is_const())
84+
if (t_from.is_pointer())
9285
{
93-
std::shared_ptr<const Base> data
94-
= std::dynamic_pointer_cast<const Base>(detail::Cast_Helper<std::shared_ptr<const Derived> >::cast(t_derived, nullptr));
95-
if (!data)
86+
// Dynamic cast out the contained boxed value, which we know is the type we want
87+
if (t_from.is_const())
9688
{
97-
throw std::bad_cast();
89+
std::shared_ptr<const To> data
90+
= std::dynamic_pointer_cast<const To>(detail::Cast_Helper<std::shared_ptr<const From> >::cast(t_from, nullptr));
91+
if (!data)
92+
{
93+
throw std::bad_cast();
94+
}
95+
96+
return Boxed_Value(data);
97+
} else {
98+
std::shared_ptr<To> data
99+
= std::dynamic_pointer_cast<To>(detail::Cast_Helper<std::shared_ptr<From> >::cast(t_from, nullptr));
100+
101+
if (!data)
102+
{
103+
throw std::bad_cast();
104+
}
105+
106+
return Boxed_Value(data);
98107
}
99-
100-
return Boxed_Value(data);
101108
} else {
102-
std::shared_ptr<Base> data
103-
= std::dynamic_pointer_cast<Base>(detail::Cast_Helper<std::shared_ptr<Derived> >::cast(t_derived, nullptr));
104-
105-
if (!data)
109+
// Pull the reference out of the contained boxed value, which we know is the type we want
110+
if (t_from.is_const())
106111
{
107-
throw std::bad_cast();
112+
const From &d = detail::Cast_Helper<const From &>::cast(t_from, 0);
113+
const To &data = dynamic_cast<const To &>(d);
114+
return Boxed_Value(std::cref(data));
115+
} else {
116+
From &d = detail::Cast_Helper<From &>::cast(t_from, 0);
117+
To &data = dynamic_cast<To &>(d);
118+
return Boxed_Value(std::ref(data));
108119
}
109-
110-
return Boxed_Value(data);
111120
}
112121
} else {
113-
// Pull the reference out of the contained boxed value, which we know is the type we want
114-
if (t_derived.is_const())
115-
{
116-
const Derived &d = detail::Cast_Helper<const Derived &>::cast(t_derived, 0);
117-
const Base &data = dynamic_cast<const Base &>(d);
118-
return Boxed_Value(std::cref(data));
119-
} else {
120-
Derived &d = detail::Cast_Helper<Derived &>::cast(t_derived, 0);
121-
Base &data = dynamic_cast<Base &>(d);
122-
return Boxed_Value(std::ref(data));
123-
}
122+
throw chaiscript::exception::bad_boxed_dynamic_cast(t_from.get_type_info(), typeid(To), "Unknown dynamic_cast_conversion");
124123
}
125-
} else {
126-
throw chaiscript::exception::bad_boxed_dynamic_cast(t_derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
127124
}
125+
};
126+
127+
template<typename Base, typename Derived>
128+
class Dynamic_Conversion_Impl : public Dynamic_Conversion
129+
{
130+
public:
131+
Dynamic_Conversion_Impl()
132+
: Dynamic_Conversion(user_type<Base>(), user_type<Derived>())
133+
{
134+
}
135+
136+
virtual Boxed_Value convert_down(const Boxed_Value &t_base) const
137+
{
138+
return Dynamic_Caster<Base, Derived>::cast(t_base);
139+
}
140+
141+
virtual Boxed_Value convert(const Boxed_Value &t_derived) const
142+
{
143+
return Dynamic_Caster<Derived, Base>::cast(t_derived);
128144
}
129145
};
130146
}
@@ -155,7 +171,7 @@ namespace chaiscript
155171

156172
bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) const
157173
{
158-
return has_conversion(base, derived);
174+
return has_conversion(base, derived) || has_conversion(derived, base);
159175
}
160176

161177
template<typename Base>
@@ -170,6 +186,19 @@ namespace chaiscript
170186
}
171187
}
172188

189+
template<typename Derived>
190+
Boxed_Value boxed_dynamic_down_cast(const Boxed_Value &base) const
191+
{
192+
try {
193+
return get_conversion(base.get_type_info(), user_type<Derived>())->convert_down(base);
194+
} catch (const std::out_of_range &) {
195+
throw exception::bad_boxed_dynamic_cast(base.get_type_info(), typeid(Derived), "No known conversion");
196+
} catch (const std::bad_cast &) {
197+
throw exception::bad_boxed_dynamic_cast(base.get_type_info(), typeid(Derived), "Unable to perform dynamic_cast operation");
198+
}
199+
}
200+
201+
173202
bool has_conversion(const Type_Info &base, const Type_Info &derived) const
174203
{
175204
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
@@ -242,8 +271,6 @@ namespace chaiscript
242271
/// chai.add(chaiscript::base_class<Base, Derived>());
243272
/// \endcode
244273
///
245-
/// \todo Move share static type registration code into a mechanism that allows it to be properly
246-
/// shared by all modules
247274
template<typename Base, typename Derived>
248275
Dynamic_Cast_Conversion base_class()
249276
{

include/chaiscript/dispatchkit/dynamic_object.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace chaiscript
3030
return m_attrs[t_attr_name];
3131
}
3232

33-
std::map<std::string, Boxed_Value> get_attrs()
33+
std::map<std::string, Boxed_Value> get_attrs() const
3434
{
3535
return m_attrs;
3636
}

include/chaiscript/dispatchkit/function_call_detail.hpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ namespace chaiscript
1717
{
1818
namespace detail
1919
{
20-
2120
/**
2221
* Internal helper class for handling the return
2322
* value of a build_function_caller
2423
*/
25-
template<typename Ret>
24+
template<typename Ret, bool is_arithmetic>
2625
struct Function_Caller_Ret
2726
{
2827
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
@@ -32,11 +31,25 @@ namespace chaiscript
3231
}
3332
};
3433

34+
/**
35+
* Specialization for arithmetic return types
36+
*/
37+
template<typename Ret>
38+
struct Function_Caller_Ret<Ret, true>
39+
{
40+
static Ret call(const std::vector<Const_Proxy_Function> &t_funcs,
41+
const std::vector<Boxed_Value> &params, const Dynamic_Cast_Conversions &t_conversions)
42+
{
43+
return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions)).get_as<Ret>();
44+
}
45+
};
46+
47+
3548
/**
3649
* Specialization for void return types
3750
*/
3851
template<>
39-
struct Function_Caller_Ret<void>
52+
struct Function_Caller_Ret<void, false>
4053
{
4154
static void call(const std::vector<Const_Proxy_Function> &t_funcs,
4255
const std::vector<Boxed_Value> &params, const Dynamic_Cast_Conversions &t_conversions)
@@ -59,11 +72,11 @@ namespace chaiscript
5972

6073
Ret operator()(Param...param)
6174
{
62-
return Function_Caller_Ret<Ret>::call(m_funcs, {
63-
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
64-
}, m_conversions
65-
66-
);
75+
return Function_Caller_Ret<Ret, std::is_arithmetic<Ret>::value>::call(m_funcs, {
76+
(std::is_reference<Param>::value&&!(std::is_same<chaiscript::Boxed_Value, typename std::remove_const<typename std::remove_reference<Param>::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)...
77+
}, m_conversions
78+
79+
);
6780

6881
}
6982

include/chaiscript/dispatchkit/proxy_functions.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace chaiscript
2323
class Boxed_Number;
2424
struct AST_Node;
2525

26-
typedef std::shared_ptr<struct AST_Node> AST_NodePtr;
26+
typedef std::shared_ptr<AST_Node> AST_NodePtr;
2727

2828
namespace dispatch
2929
{

0 commit comments

Comments
 (0)