From 6a0c98d54e748117417a2b607f99378f47544787 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 13 Oct 2015 15:15:03 +0200 Subject: [PATCH] Work around strange interrogate issues --- dtool/src/cppparser/cppExpression.cxx | 26 ++++++++++++++++++++----- dtool/src/cppparser/cppPreprocessor.cxx | 15 ++++++++------ dtool/src/cppparser/cppScope.cxx | 4 ---- dtool/src/dtoolutil/filename.I | 10 ++++++++++ dtool/src/dtoolutil/filename.h | 3 ++- dtool/src/parser-inc/string | 2 +- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/dtool/src/cppparser/cppExpression.cxx b/dtool/src/cppparser/cppExpression.cxx index fe28c3a044..430f9388d8 100644 --- a/dtool/src/cppparser/cppExpression.cxx +++ b/dtool/src/cppparser/cppExpression.cxx @@ -617,23 +617,39 @@ evaluate() const { // long as we can evaluate the second one *and* that comes out // to be true. if (_u._op._operator == OROR && r2._type == RT_integer && - r2.as_integer() != 0) { + r2.as_boolean()) { return r2; } // Ditto for the operator being && and the second one coming out // false. if (_u._op._operator == ANDAND && r2._type == RT_integer && - r2.as_integer() == 0) { + !r2.as_boolean()) { return r2; } + // Also for the operator being [] and the operand being a string. + if (_u._op._operator == '[' && r2._type == RT_integer && + (_u._op._op1->_type == T_string || + _u._op._op1->_type == T_u8string)) { + + int index = r2.as_integer(); + if (index == _u._op._op1->_str.size()) { + return Result(0); + } else if (index >= 0 && index < _u._op._op1->_str.size()) { + return Result(_u._op._op1->_str[index]); + } else { + cerr << "array index " << index << " out of bounds of string literal " + << *_u._op._op1 << "\n"; + } + } + return r1; } switch (_u._op._operator) { case UNARY_NOT: - return Result(!r1.as_integer()); + return Result(!r1.as_boolean()); case UNARY_NEGATE: return Result(~r1.as_integer()); @@ -683,14 +699,14 @@ evaluate() const { return Result(r1.as_integer() & r2.as_integer()); case OROR: - if (r1.as_integer()) { + if (r1.as_boolean()) { return r1; } else { return r2; } case ANDAND: - if (r1.as_integer()) { + if (r1.as_boolean()) { return r2; } else { return r1; diff --git a/dtool/src/cppparser/cppPreprocessor.cxx b/dtool/src/cppparser/cppPreprocessor.cxx index e09c7bfeec..4def9695ae 100644 --- a/dtool/src/cppparser/cppPreprocessor.cxx +++ b/dtool/src/cppparser/cppPreprocessor.cxx @@ -904,7 +904,7 @@ expand_manifests(const string &input_expr, bool expand_undefined) { CPPExpression *CPPPreprocessor:: parse_expr(const string &input_expr, CPPScope *current_scope, CPPScope *global_scope) { - string expr = expand_manifests(input_expr, true); + string expr = expand_manifests(input_expr, false); CPPExpressionParser ep(current_scope, global_scope); ep._verbose = 0; @@ -1552,15 +1552,18 @@ handle_ifndef_directive(const string &args, const YYLTYPE &loc) { //////////////////////////////////////////////////////////////////// void CPPPreprocessor:: handle_if_directive(const string &args, const YYLTYPE &loc) { - CPPExpression *expr = parse_expr(args, global_scope, global_scope); + // When expanding manifests, we should replace unknown macros + // with 0. + string expr = expand_manifests(args, true); int expression_result = 0; - - if (expr != (CPPExpression *)NULL) { - CPPExpression::Result result = expr->evaluate(); + CPPExpressionParser ep(current_scope, global_scope); + ep._verbose = 0; + if (ep.parse_expr(expr, *this)) { + CPPExpression::Result result = ep._expr->evaluate(); if (result._type == CPPExpression::RT_error) { ostringstream strm; - strm << *expr; + strm << *ep._expr; warning("Ignoring invalid expression " + strm.str(), loc); } else { expression_result = result.as_integer(); diff --git a/dtool/src/cppparser/cppScope.cxx b/dtool/src/cppparser/cppScope.cxx index 3a514a4648..3e346394cb 100644 --- a/dtool/src/cppparser/cppScope.cxx +++ b/dtool/src/cppparser/cppScope.cxx @@ -1059,10 +1059,6 @@ copy_substitute_decl(CPPScope *to_scope, CPPDeclaration::SubstDecl &subst, (*vi).second->substitute_decl(subst, to_scope, global_scope)->as_instance(); to_scope->_variables.insert(Variables::value_type((*vi).first, inst)); if (inst != (*vi).second) { - // I don't know if this _native_scope assignment is right, but it - // fixes some issues with variables in instantiated template scopes - // being printed out with an uninstantiated template scope prefix. ~rdb - inst->_ident->_native_scope = to_scope; anything_changed = true; } } diff --git a/dtool/src/dtoolutil/filename.I b/dtool/src/dtoolutil/filename.I index f8fa8fff4e..130eaf2973 100644 --- a/dtool/src/dtoolutil/filename.I +++ b/dtool/src/dtoolutil/filename.I @@ -337,6 +337,16 @@ operator [] (size_t n) const { return _filename[n]; } +//////////////////////////////////////////////////////////////////// +// Function: Filename::substr +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE string Filename:: +substr(size_t begin) const { + return _filename.substr(begin); +} + //////////////////////////////////////////////////////////////////// // Function: Filename::substr // Access: Published diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 127e9dcbcc..2058d3f45c 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -125,7 +125,8 @@ PUBLISHED: EXTENSION(PyObject *__repr__() const); - INLINE string substr(size_t begin, size_t end = string::npos) const; + INLINE string substr(size_t begin) const; + INLINE string substr(size_t begin, size_t end) const; INLINE void operator += (const string &other); INLINE Filename operator + (const string &other) const; diff --git a/dtool/src/parser-inc/string b/dtool/src/parser-inc/string index 52098c3f51..0372b88f5a 100644 --- a/dtool/src/parser-inc/string +++ b/dtool/src/parser-inc/string @@ -26,7 +26,7 @@ template class basic_string { public: typedef typename size_t size_type; - static const size_t npos; + static const size_t npos = -1; basic_string(); basic_string(const basic_string ©);