diff options
author | Neil Booth <neil@daikokuya.demon.co.uk> | 2002-06-13 21:16:00 +0000 |
---|---|---|
committer | Neil Booth <neil@gcc.gnu.org> | 2002-06-13 21:16:00 +0000 |
commit | b66377c173ecd444f4fb4f9737ee10a97084ad9a (patch) | |
tree | 84d2f1068a69ffbe2208c366f6d8d1f3c43b05d2 /gcc/cpptrad.c | |
parent | 8bc6e1018593f8525674f79fac6a80d23cb25efb (diff) | |
download | gcc-b66377c173ecd444f4fb4f9737ee10a97084ad9a.zip gcc-b66377c173ecd444f4fb4f9737ee10a97084ad9a.tar.gz gcc-b66377c173ecd444f4fb4f9737ee10a97084ad9a.tar.bz2 |
cpphash.h (_cpp_lex_identifier_trad): Remove.
* cpphash.h (_cpp_lex_identifier_trad): Remove.
* cpplib.c (end_directive): Don't skip, always remove overlay
apart from #define.
(prepare_directive_trad): Handle NULL pfile->directive.
(_cpp_handle_directive): Always call prepare_directive_trad
if traditional.
* cppmain.c (check_multiline_token): Rename account_for_newlines,
generalize inputs.
(scan_translation_unit_trad): Use it.
* cpptrad.c (skip_comment): Rename copy_comment, copy comment to
output, get escaped newline in comment close correct.
(check_output_buffer, skip_whitespace): Update.
(_cpp_lex_identifier_trad): Remove.
(scan_out_logical_line): Handle -C and comments in directives
properly.
From-SVN: r54599
Diffstat (limited to 'gcc/cpptrad.c')
-rw-r--r-- | gcc/cpptrad.c | 116 |
1 files changed, 69 insertions, 47 deletions
diff --git a/gcc/cpptrad.c b/gcc/cpptrad.c index 03ee0e8..4765be2 100644 --- a/gcc/cpptrad.c +++ b/gcc/cpptrad.c @@ -22,17 +22,13 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "cpphash.h" /* The replacement text of a function-like macro is stored as a - contiguous sequence of aligned blocks. Each block represents the - portion of text from the start of the previous block (or the start - of the macro replacement text in the case of the first block) to - the next parameter, or the end of the replacement list if there - are none left. - - Each block consists of an unsigned int, which is the length of text - contained in the third part, an unsigned short, which is the + contiguous sequence of aligned blocks, each representing the text + between subsequent parameters in that text. + + Each block comprises the length of text contained therein, the one-based index of the argument that immediately follows that text, and the text itself. The final block in the macro expansion is - recognizable as it has an argument index of zero. */ + easily recognizable as it has an argument index of zero. */ struct block { @@ -67,17 +63,16 @@ struct fun_macro unsigned int argc; }; -/* Lexing TODO: Handle -C, maybe -CC, and space in escaped newlines. - Stop cpplex.c from recognizing comments and directives during its - lexing pass. Get rid of line_base usage - seems pointless? Do we - get escaped newline at EOF correct? */ +/* Lexing TODO: Maybe handle -CC and space in escaped newlines. Stop + cpplex.c from recognizing comments and directives during its lexing + pass. Get rid of line_base usage - seems pointless? */ static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *)); static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *, const uchar *)); static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *)); static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *)); -static const uchar *skip_comment PARAMS ((cpp_reader *, const uchar *)); +static const uchar *copy_comment PARAMS ((cpp_reader *, const uchar *)); static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *)); static void check_output_buffer PARAMS ((cpp_reader *, size_t)); static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *)); @@ -99,6 +94,10 @@ check_output_buffer (pfile, n) cpp_reader *pfile; size_t n; { + /* We might need two bytes to terminate an unterminated comment, and + one more to terminate with a NUL. */ + n += 2 + 1; + if (n > (size_t) (pfile->out.limit - pfile->out.cur)) { size_t size = pfile->out.cur - pfile->out.base; @@ -134,45 +133,70 @@ skip_escaped_newlines (pfile, cur) cpp_reader *pfile; const uchar *cur; { - while (*cur == '\\' && is_vspace (cur[1])) - cur = handle_newline (pfile, cur + 1); + if (*cur == '\\' && is_vspace (cur[1])) + { + do + cur = handle_newline (pfile, cur + 1); + while (*cur == '\\' && is_vspace (cur[1])); + + if (cur == RLIMIT (pfile->context)) + cpp_error (pfile, DL_PEDWARN, + "backslash-newline at end of file"); + } return cur; } /* CUR points to the character after the asterisk introducing a - comment. Returns the position after the comment. */ + comment in the input buffer. The remaining comment is copied to + the buffer pointed to by pfile->out.cur, which must be of + sufficient size, and pfile->out.cur is updated. Unterminated + comments are diagnosed, and correctly terminated in the output. + + Returns a pointer to the first character after the comment in the + input buffer. */ static const uchar * -skip_comment (pfile, cur) +copy_comment (pfile, cur) cpp_reader *pfile; const uchar *cur; { unsigned int from_line = pfile->line; - unsigned int c = 0, prevc = 0; const uchar *limit = RLIMIT (pfile->context); + uchar *out = pfile->out.cur; while (cur < limit) { - prevc = c; - c = *cur++; + unsigned int c = *cur++; + *out++ = c; if (c == '/') { - if (prevc == '*') - break; + /* An immediate slash does not terminate the comment. */ + if (out[-2] == '*' && out > pfile->out.cur + 1) + goto done; + if (*cur == '*' && cur[1] != '/' && CPP_OPTION (pfile, warn_comments)) cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0, "\"/*\" within comment"); } else if (is_vspace (c)) - cur = handle_newline (pfile, cur - 1); + { + cur = handle_newline (pfile, cur - 1); + /* Canonicalize newline sequences and skip escaped ones. */ + if (out[-2] == '\\') + out -= 2; + else + out[-1] = '\n'; + } } - if (c != '/' || prevc != '*') - cpp_error_with_line (pfile, DL_ERROR, from_line, 0, - "unterminated comment"); + cpp_error_with_line (pfile, DL_ERROR, from_line, 0, "unterminated comment"); + *out++ = '*'; + *out++ = '/'; + done: + pfile->out.cur = out; return cur; } @@ -206,7 +230,7 @@ skip_whitespace (pfile, cur) tmp = skip_escaped_newlines (pfile, cur + 1); if (*tmp == '*') { - cur = skip_comment (pfile, tmp + 1); + cur = copy_comment (pfile, tmp + 1); continue; } } @@ -246,23 +270,6 @@ lex_identifier (pfile, cur) return result; } -/* Reads an identifier, returning its hashnode. If the next token is - not an identifier, returns NULL. */ -cpp_hashnode * -_cpp_lex_identifier_trad (pfile) - cpp_reader *pfile; -{ - const uchar *cur = skip_whitespace (pfile, CUR (pfile->context)); - - if (!is_idstart (*cur)) - { - CUR (pfile->context) = cur; - return NULL; - } - - return lex_identifier (pfile, cur); -} - /* Overlays the true file buffer temporarily with text of length LEN starting at START. The true buffer is restored upon calling restore_buff(). */ @@ -381,7 +388,7 @@ scan_out_logical_line (pfile, macro) { cpp_context *context; const uchar *cur; - unsigned int c, paren_depth, quote = 0; + unsigned int c, paren_depth = 0, quote = 0; uchar *out; struct fun_macro fmacro; @@ -466,7 +473,22 @@ scan_out_logical_line (pfile, macro) { cur = skip_escaped_newlines (pfile, cur); if (*cur == '*') - out--, cur = skip_comment (pfile, cur + 1); + { + *out = '*'; + pfile->out.cur = out + 1; + cur = copy_comment (pfile, cur + 1); + + /* Comments in directives become spaces so that + tokens are properly separated when the ISO + preprocessor re-lexes the line. The exception + is #define. */ + if (pfile->state.in_directive && !macro) + out[-1] = ' '; + else if (CPP_OPTION (pfile, discard_comments)) + out -= 1; + else + out = pfile->out.cur; + } } break; |