diff options
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 10 | ||||
-rw-r--r-- | libcpp/directives.c | 81 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 2 |
3 files changed, 83 insertions, 10 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index faf6b93..731b1c6 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,13 @@ +2005-10-04 Ian Lance Taylor <ian@airs.com> + + PR preprocessor/13726 + * directives.c (check_eol_return_comments): New static function. + (parse_include): Add buf parameter. Change all callers. + (do_include_common): If not discard comments, turn on + save_comments. Pass collected comments to include callback. + * include/cpplib.h (struct cpp_callbacks): Add new parameter to + include callback: cpp_token list. + 2005-09-20 Joseph S. Myers <joseph@codesourcery.com> * include/cpplib.h (struct cpp_options): Add extended_identifiers. diff --git a/libcpp/directives.c b/libcpp/directives.c index 7e1167d..7159f07 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -95,7 +95,7 @@ static void end_directive (cpp_reader *, int); static void directive_diagnostics (cpp_reader *, const directive *, int); static void run_directive (cpp_reader *, int, const char *, size_t); static char *glue_header_name (cpp_reader *); -static const char *parse_include (cpp_reader *, int *); +static const char *parse_include (cpp_reader *, int *, const cpp_token ***); static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); static unsigned int read_flag (cpp_reader *, unsigned int); static int strtoul_for_line (const uchar *, unsigned int, unsigned long *); @@ -220,6 +220,46 @@ check_eol (cpp_reader *pfile) pfile->directive->name); } +/* Ensure there are no stray tokens other than comments at the end of + a directive, and gather the comments. */ +static const cpp_token ** +check_eol_return_comments (cpp_reader *pfile) +{ + size_t c; + size_t capacity = 8; + const cpp_token **buf; + + buf = XNEWVEC (const cpp_token *, capacity); + c = 0; + if (! SEEN_EOL ()) + { + while (1) + { + const cpp_token *tok; + + tok = _cpp_lex_token (pfile); + if (tok->type == CPP_EOF) + break; + if (tok->type != CPP_COMMENT) + cpp_error (pfile, CPP_DL_PEDWARN, + "extra tokens at end of #%s directive", + pfile->directive->name); + else + { + if (c + 1 >= capacity) + { + capacity *= 2; + buf = XRESIZEVEC (const cpp_token *, buf, capacity); + } + buf[c] = tok; + ++c; + } + } + } + buf[c] = NULL; + return buf; +} + /* Called when entering a directive, _Pragma or command-line directive. */ static void start_directive (cpp_reader *pfile) @@ -624,7 +664,8 @@ glue_header_name (cpp_reader *pfile) #pragma dependency. The string is malloced and the caller should free it. Returns NULL on error. */ static const char * -parse_include (cpp_reader *pfile, int *pangle_brackets) +parse_include (cpp_reader *pfile, int *pangle_brackets, + const cpp_token ***buf) { char *fname; const cpp_token *header; @@ -657,7 +698,15 @@ parse_include (cpp_reader *pfile, int *pangle_brackets) return NULL; } - check_eol (pfile); + if (buf == NULL || CPP_OPTION (pfile, discard_comments)) + check_eol (pfile); + else + { + /* If we are not discarding comments, then gather them while + doing the eol check. */ + *buf = check_eol_return_comments (pfile); + } + return fname; } @@ -667,16 +716,27 @@ do_include_common (cpp_reader *pfile, enum include_type type) { const char *fname; int angle_brackets; + const cpp_token **buf = NULL; - fname = parse_include (pfile, &angle_brackets); + /* Re-enable saving of comments if requested, so that the include + callback can dump comments which follow #include. */ + pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + + fname = parse_include (pfile, &angle_brackets, &buf); if (!fname) - return; + { + if (buf) + XDELETEVEC (buf); + return; + } if (!*fname) { cpp_error (pfile, CPP_DL_ERROR, "empty filename in #%s", pfile->directive->name); - free ((void *) fname); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); return; } @@ -690,12 +750,15 @@ do_include_common (cpp_reader *pfile, enum include_type type) if (pfile->cb.include) pfile->cb.include (pfile, pfile->directive_line, - pfile->directive->name, fname, angle_brackets); + pfile->directive->name, fname, angle_brackets, + buf); _cpp_stack_include (pfile, fname, angle_brackets, type); } - free ((void *) fname); + XDELETEVEC (fname); + if (buf) + XDELETEVEC (buf); } static void @@ -1322,7 +1385,7 @@ do_pragma_dependency (cpp_reader *pfile) const char *fname; int angle_brackets, ordering; - fname = parse_include (pfile, &angle_brackets); + fname = parse_include (pfile, &angle_brackets, NULL); if (!fname) return; diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index c84f624..3c4d0d6 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -459,7 +459,7 @@ struct cpp_callbacks void (*dir_change) (cpp_reader *, const char *); void (*include) (cpp_reader *, unsigned int, const unsigned char *, - const char *, int); + const char *, int, const cpp_token **); void (*define) (cpp_reader *, unsigned int, cpp_hashnode *); void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *); void (*ident) (cpp_reader *, unsigned int, const cpp_string *); |