summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@gmail.com>2012-01-04 15:40:37 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-09 19:10:21 -0300
commit744d018dd857543f93f3961cf9e7f70adcc7ce65 (patch)
tree7b9056bb151d950bbfe2cb665894b136d71b5a7f
parent002efe18aa6208dca588a8da737c87c0e13a8a76 (diff)
Fix BUG #1086 - "generatorrunner segfault processing #include..."
Boost headers typically include the character '#' at the beginning of any line and just do nothing elese with that unnamed directive. So as that's not actually an error, rather that's just a just-do-nothing directive we'll ignore this situtation. There's still a problem when using #include directives and passing macros as arguments rather than a path to the header file. Instead of asserting this issue we'll print a warning message about this issue. One can also include a path between brackets (for e.g., when defining a macro or so) so that we cannot simply ignore that. So we need to handle this kind of stuff as well. See http://bugs.pyside.org/show_bug.cgi?id=1086. Signed-off-by: Paulo Alcantara <pcacjr@gmail.com> Reviewed-by: Hugo Parente Lima <hugo.pl@gmail.com> Reviewed-by: Marcelo Lira <marcelo.lira@openbossa.org>
-rw-r--r--parser/rpp/pp-engine-bits.h60
-rw-r--r--parser/rpp/pp-engine.h1
2 files changed, 55 insertions, 6 deletions
diff --git a/parser/rpp/pp-engine-bits.h b/parser/rpp/pp-engine-bits.h
index 7594ab7..a79df43 100644
--- a/parser/rpp/pp-engine-bits.h
+++ b/parser/rpp/pp-engine-bits.h
@@ -153,6 +153,8 @@ bool pp::find_header_protection(_InputIterator __first, _InputIterator __last, s
inline pp::PP_DIRECTIVE_TYPE pp::find_directive(char const *__directive, std::size_t __size) const
{
switch (__size) {
+ case 0:
+ return PP_UNNAMED_DIRECTIVE;
case 2:
if (__directive[0] == 'i'
&& __directive[1] == 'f')
@@ -307,6 +309,14 @@ _InputIterator pp::handle_directive(char const *__directive, std::size_t __size,
PP_DIRECTIVE_TYPE d = find_directive(__directive, __size);
switch (d) {
+ case PP_UNNAMED_DIRECTIVE:
+ /* There are many boost headers that include the character '#'
+ * at the beginning of any line and just do nothing else with
+ * that unnamed directive. Well, as that's not an error so
+ * we'll just ignore this unnamed directive for now.
+ */
+ ++__last;
+ return ++__first;
case PP_DEFINE:
if (! skipping())
return handle_define(__first, __last);
@@ -358,7 +368,15 @@ _InputIterator pp::handle_include(bool __skip_current_path, _InputIterator __fir
name.reserve(255);
expand_include(__first, __last, std::back_inserter(name));
std::string::iterator it = skip_blanks(name.begin(), name.end());
- assert(it != name.end() && (*it == '<' || *it == '"'));
+ if (it != name.end() && (*it != '<' || *it != '"')) {
+ std::cerr << "** WARNING APIExtractor does not support the use "
+ "of #include directives without passing either "
+ "\"<path/to/header.h>\" or \"./path/to/header.h\", "
+ "for example. Invalid use at " << env.current_file
+ << ":" << env.current_line << "." << std::endl;
+ return __last;
+ }
+
handle_include(__skip_current_path, it, name.end(), __result);
return __first;
}
@@ -576,10 +594,36 @@ _InputIterator pp::handle_define(_InputIterator __first, _InputIterator __last)
__first = skip_blanks(__first, __last);
+ /* Note: Sometimes one can include a path between brackets (for
+ * e.g., when defining a macro or so) so that we cannot simply
+ * ignore that. The in_path variable will handle this situation.
+ */
+ bool in_path = false;
while (__first != __last && *__first != '\n') {
+ if ((*__first == '<' || *__first == '"') &&
+ (*(__first + 1) != '*' && *(__first + 1) != '/')) {
+ in_path = true;
+ goto skip_path;
+ }
+
+ if (in_path) {
+ if (*__first == '>' || *__first == '"') {
+ in_path = false;
+ goto skip_path;
+ } else if (*__first == ',' || *__first == ' ' || *__first == '\\') {
+ in_path = false;
+ continue;
+ }
+ }
+
if (*__first == '/') {
- __first = skip_comment_or_divop(__first, __last);
- env.current_line += skip_comment_or_divop.lines;
+ if (*(__first + 1) != '*' && *(__first + 1) != '/') {
+ in_path = true;
+ goto skip_path;
+ } else {
+ __first = skip_comment_or_divop(__first, __last);
+ env.current_line += skip_comment_or_divop.lines;
+ }
}
if (*__first == '\\') {
@@ -594,6 +638,7 @@ _InputIterator pp::handle_define(_InputIterator __first, _InputIterator __last)
}
}
+skip_path:
definition += *__first++;
}
@@ -712,10 +757,13 @@ _InputIterator pp::eval_primary(_InputIterator __first, _InputIterator __last, V
__first = eval_constant_expression(__first, __last, result);
next_token(__first, __last, &token);
- if (token != ')')
- std::cerr << "** WARNING expected ``)'' = " << token << std::endl;
- else
+ if (token != ')') {
+ std::cerr << "** WARNING expected ``)'' = " << token << " (at "
+ << env.current_file << ":" << env.current_line
+ << ")." << std::endl;
+ } else {
__first = next_token(__first, __last, &token);
+ }
break;
default:
diff --git a/parser/rpp/pp-engine.h b/parser/rpp/pp-engine.h
index 894dca2..bc1d02e 100644
--- a/parser/rpp/pp-engine.h
+++ b/parser/rpp/pp-engine.h
@@ -143,6 +143,7 @@ class pp
enum PP_DIRECTIVE_TYPE {
PP_UNKNOWN_DIRECTIVE,
+ PP_UNNAMED_DIRECTIVE,
PP_DEFINE,
PP_INCLUDE,
PP_INCLUDE_NEXT,