cpphash.h (_cpp_lex_identifier_trad): Remove.
authorNeil Booth <neil@daikokuya.demon.co.uk>
Thu, 13 Jun 2002 21:16:00 +0000 (21:16 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Thu, 13 Jun 2002 21:16:00 +0000 (21:16 +0000)
* 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

gcc/ChangeLog
gcc/cpphash.h
gcc/cpplib.c
gcc/cppmain.c
gcc/cpptrad.c

index 7c08d424ea8f3dcc45f297223f67049c703cee1a..d5270c8fbf7668186068e3dc18ccae0894066dec 100644 (file)
@@ -1,3 +1,21 @@
+2002-06-13  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * 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.
+
 Thu Jun 13 20:18:38 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
        * config.gcc: Add support for sh[234]*-*-elf*, sh[2346lbe]*-*-linux*.
index ae6a4f2301da0f1568f93362cfae0b5b7bc0430e..24b5ef7fcccbc797f7df695e27b7e96752c2068f 100644 (file)
@@ -522,7 +522,6 @@ extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *));
 extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
                                         size_t));
 extern void _cpp_remove_overlay PARAMS ((cpp_reader *));
-extern cpp_hashnode *_cpp_lex_identifier_trad PARAMS ((cpp_reader *));
 extern void _cpp_set_trad_context PARAMS ((cpp_reader *));
 extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *));
 extern bool _cpp_expansions_different_trad PARAMS ((const cpp_macro *,
index acc71e7120a6ae208336ead67ae146b74a60a1a0..aecfbaf0edd8862edec5f5991b791d3f2d572ecd 100644 (file)
@@ -256,14 +256,11 @@ end_directive (pfile, skip_line)
 {
   if (CPP_OPTION (pfile, traditional))
     {
-      if (!pfile->directive || pfile->directive == &dtable[T_DEFINE])
-       skip_line = false;
-      else
+      if (pfile->directive != &dtable[T_DEFINE])
        _cpp_remove_overlay (pfile);
     }
-
   /* We don't skip for an assembler #.  */
-  if (skip_line)
+  else if (skip_line)
     {
       skip_rest_of_line (pfile);
       if (!pfile->keep_tokens)
@@ -289,7 +286,8 @@ prepare_directive_trad (pfile)
     CUR (pfile->context) = pfile->buffer->cur;
   else
     {
-      bool no_expand = ! (pfile->directive->flags & EXPAND);
+      bool no_expand = (pfile->directive
+                       && ! (pfile->directive->flags & EXPAND));
       bool was_skipping = pfile->state.skipping;
 
       pfile->state.skipping = false;
@@ -382,6 +380,10 @@ _cpp_handle_directive (pfile, indented)
                   "style of line directive is a GCC extension");
     }
 
+  pfile->directive = dir;
+  if (CPP_OPTION (pfile, traditional))
+    prepare_directive_trad (pfile);
+
   if (dir)
     {
       /* If we have a directive that is not an opening conditional,
@@ -441,9 +443,6 @@ _cpp_handle_directive (pfile, indented)
        pfile->state.save_comments =
          ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
 
-      pfile->directive = dir;
-      if (CPP_OPTION (pfile, traditional))
-       prepare_directive_trad (pfile);
       (*pfile->directive->handler) (pfile);
     }
   else if (skip == 0)
index 0edc3d2b25b86387b88d005a71c9ea377e2e6b43..7ebc1ad2c5aea82b9fd8dfac9185f668cd90a7fb 100644 (file)
@@ -43,7 +43,7 @@ static void setup_callbacks PARAMS ((cpp_reader *));
 /* General output routines.  */
 static void scan_translation_unit PARAMS ((cpp_reader *));
 static void scan_translation_unit_trad PARAMS ((cpp_reader *));
-static void check_multiline_token PARAMS ((const cpp_string *));
+static void account_for_newlines PARAMS ((const uchar *, size_t));
 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
 
 static void print_line PARAMS ((const struct line_map *, unsigned int,
@@ -208,19 +208,18 @@ scan_translation_unit (pfile)
       cpp_output_token (token, print.outf);
 
       if (token->type == CPP_COMMENT)
-       check_multiline_token (&token->val.str);
+       account_for_newlines (token->val.str.text, token->val.str.len);
     }
 }
 
-/* Adjust print.line for newlines embedded in tokens.  */
+/* Adjust print.line for newlines embedded in output.  */
 static void
-check_multiline_token (str)
-     const cpp_string *str;
+account_for_newlines (str, len)
+     const uchar *str;
+     size_t len;
 {
-  unsigned int i;
-
-  for (i = 0; i < str->len; i++)
-    if (str->text[i] == '\n')
+  while (len--)
+    if (*str++ == '\n')
       print.line++;
 }
 
@@ -239,6 +238,8 @@ scan_translation_unit_trad (pfile)
       maybe_print_line (print.map, pfile->out.first_line);
       fwrite (pfile->out.base, 1, len, print.outf);
       print.printed = 1;
+      if (!CPP_OPTION (pfile, discard_comments))
+       account_for_newlines (pfile->out.base, len);
     }
 }
 
index 03ee0e893a68a384e74acf5e8eec5b944521ff3f..4765be2273afc51f18a22c349da90cd459e4bb8a 100644 (file)
@@ -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;