cpphash.h (CPP_RESERVE, [...]): Delete.
authorNeil Booth <neilb@earthling.net>
Sat, 23 Sep 2000 21:41:41 +0000 (21:41 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Sat, 23 Sep 2000 21:41:41 +0000 (21:41 +0000)
* cpphash.h (CPP_RESERVE, CPP_PUTS_Q, CPP_PUTS, CPP_PUTC_Q,
CPP_PUTC, DUMMY_TOKEN, NO_DUMMY_TOKEN): Delete.
* cpplex.c (_cpp_expand_token_space, _cpp_init_toklist,
_cpp_free_toklist): No need to worry about extra dummy token
at the start of token lists any more.
(trigraph_ok): Only warn outside comments.
(skip_block_comment): Set and clear lexing_comment.
(skip_line_comment): Take a cpp_reader not cpp_buffer.
Set and clear lexing_comment.
(parse_number): Handle leading '.' indicated by pfile->seen_dot.
(check_long_token): Delete.
(lex_percent, lex_dot): New subroutines of lex_token to
handle lexing of '.' and '%' without lookback.
(lex_token): Use lex_dot and lex_percent.
(lex_line): Don't check for LIST_OFFSET.
(_cpp_init_input_buffer): Update for new _cpp_init_toklist.
* cpplib.c (_cpp_parse_assertion): Similarly.
(cpp_push_buffer): Initialize extra_char.
* cpplib.h (LIST_OFFSET): Delete.
(struct cpp_buffer): New member extra_char.
(struct lexer_state): New members lexing_comment and seen_dot.

From-SVN: r36582

gcc/ChangeLog
gcc/cpphash.h
gcc/cpplex.c
gcc/cpplib.c
gcc/cpplib.h

index efe588a7ad7c7d2cbadb773e9a7190b52cfa2249..6b29754e911d112ae7fad9554d14c64615272298 100644 (file)
@@ -1,3 +1,27 @@
+Sat 23-Sep-2000 22:39:18 BST  Neil Booth  <NeilB@earthling.net>
+
+       * cpphash.h (CPP_RESERVE, CPP_PUTS_Q, CPP_PUTS, CPP_PUTC_Q,
+       CPP_PUTC, DUMMY_TOKEN, NO_DUMMY_TOKEN): Delete.
+       * cpplex.c (_cpp_expand_token_space, _cpp_init_toklist,
+       _cpp_free_toklist): No need to worry about extra dummy token
+       at the start of token lists any more.
+       (trigraph_ok): Only warn outside comments.
+       (skip_block_comment): Set and clear lexing_comment.
+       (skip_line_comment): Take a cpp_reader not cpp_buffer.
+       Set and clear lexing_comment.
+       (parse_number): Handle leading '.' indicated by pfile->seen_dot.
+       (check_long_token): Delete.
+       (lex_percent, lex_dot): New subroutines of lex_token to
+       handle lexing of '.' and '%' without lookback.
+       (lex_token): Use lex_dot and lex_percent.
+       (lex_line): Don't check for LIST_OFFSET.
+       (_cpp_init_input_buffer): Update for new _cpp_init_toklist.
+       * cpplib.c (_cpp_parse_assertion): Similarly.
+       (cpp_push_buffer): Initialize extra_char.
+       * cpplib.h (LIST_OFFSET): Delete.
+       (struct cpp_buffer): New member extra_char.
+       (struct lexer_state): New members lexing_comment and seen_dot.
+
 2000-09-23  Jason Merrill  <jason@redhat.com>
 
        * config/rs6000/x-aix41 (CLIB): Define here.
index 08d3209d7bc96f73da54373d5c670fafb6926801..8f569e7404d6dc73c7af2832f6ec4401e90c273d 100644 (file)
@@ -183,22 +183,6 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
 
 /* Macros.  */
 
-/* Make sure PFILE->token_buffer has space for at least N more characters. */
-#define CPP_RESERVE(PFILE, N) \
-  (CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
-   && (_cpp_grow_token_buffer (PFILE, N), 0))
-
-/* Append string STR (of length N) to PFILE's output buffer.
-   Assume there is enough space. */
-#define CPP_PUTS_Q(PFILE, STR, N) \
-  (memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
-/* Append string STR (of length N) to PFILE's output buffer.  Make space. */
-#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
-/* Append character CH to PFILE's output buffer.  Assume sufficient space. */
-#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
-/* Append character CH to PFILE's output buffer.  Make space if need be. */
-#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
-
 #define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
 #define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
 #define CPP_IN_SYSTEM_HEADER(PFILE) \
@@ -213,10 +197,6 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
    parse_name.  */
 #define HASHSTEP(r, c) ((r) * 67 + (c - 113));
 
-/* Flags for _cpp_init_toklist.  */
-#define DUMMY_TOKEN     0
-#define NO_DUMMY_TOKEN 1
-
 /* In cpperror.c  */
 enum error_type { WARNING = 0, PEDWARN, ERROR, FATAL, ICE };
 extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type,
index c0bf875aaff06a9e713d66872803214388e198d4..a7a6f99098c4a4bb7500b6af66f6eb763e0ed87c 100644 (file)
@@ -103,7 +103,7 @@ static cppchar_t skip_escaped_newlines PARAMS ((cpp_buffer *, cppchar_t));
 static cppchar_t get_effective_char PARAMS ((cpp_buffer *));
 
 static int skip_block_comment PARAMS ((cpp_reader *));
-static int skip_line_comment PARAMS ((cpp_buffer *));
+static int skip_line_comment PARAMS ((cpp_reader *));
 static void adjust_column PARAMS ((cpp_reader *));
 static void skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
 static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *, cppchar_t));
@@ -112,11 +112,9 @@ static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
 static void unterminated PARAMS ((cpp_reader *, unsigned int, int));
 static int trigraph_ok PARAMS ((cpp_reader *, cppchar_t));
 static void save_comment PARAMS ((cpp_reader *, cpp_token *, const U_CHAR *));
+static void lex_percent PARAMS ((cpp_buffer *, cpp_token *));
+static void lex_dot PARAMS ((cpp_reader *, cpp_token *));
 static void lex_line PARAMS ((cpp_reader *, cpp_toklist *));
-static void check_long_token PARAMS ((cpp_buffer *,
-                                     cpp_token *,
-                                     cppchar_t,
-                                     enum cpp_ttype));
 static void lex_token PARAMS ((cpp_reader *, cpp_token *));
 static int lex_next PARAMS ((cpp_reader *, int));
 
@@ -453,50 +451,35 @@ _cpp_expand_token_space (list, count)
      cpp_toklist *list;
      unsigned int count;
 {
-  unsigned int n;
-
   list->tokens_cap += count;
-  n = list->tokens_cap;
-  if (list->flags & LIST_OFFSET)
-    list->tokens--, n++;
   list->tokens = (cpp_token *)
-    xrealloc (list->tokens, n * sizeof (cpp_token));
-  if (list->flags & LIST_OFFSET)
-    list->tokens++;            /* Skip the dummy.  */
+    xrealloc (list->tokens, list->tokens_cap * sizeof (cpp_token));
 }
 
-/* Initialize a token list.  If flags is DUMMY_TOKEN, we allocate
-   an extra token in front of the token list, as this allows the lexer
-   to always peek at the previous token without worrying about
-   underflowing the list, and some initial space.  Otherwise, no
-   token- or name-space is allocated, and there is no dummy token.  */
+/* Initialize a token list.  If EMPTY is false, some token and name
+   space is provided.  */
 void
-_cpp_init_toklist (list, flags)
+_cpp_init_toklist (list, empty)
      cpp_toklist *list;
-     int flags;
+     int empty;
 {
-  if (flags == NO_DUMMY_TOKEN)
+  if (empty)
     {
       list->tokens_cap = 0;
       list->tokens = 0;
       list->name_cap = 0;
       list->namebuf = 0;
-      list->flags = 0;
     }
   else
     {
-      /* Initialize token space.  Put a dummy token before the start
-        that will fail matches.  */
+      /* Initialize token space.  */
       list->tokens_cap = 256;  /* 4K's worth.  */
       list->tokens = (cpp_token *)
        xmalloc ((list->tokens_cap + 1) * sizeof (cpp_token));
-      list->tokens[0].type = CPP_EOF;
-      list->tokens++;
 
       /* Initialize name space.  */
       list->name_cap = 1024;
       list->namebuf = (unsigned char *) xmalloc (list->name_cap);
-      list->flags = LIST_OFFSET;
     }
 
   _cpp_clear_toklist (list);
@@ -512,7 +495,7 @@ _cpp_clear_toklist (list)
   list->directive = 0;
   list->paramc = 0;
   list->params_len = 0;
-  list->flags &= LIST_OFFSET;  /* clear all but that one */
+  list->flags = 0;
 }
 
 /* Free a token list.  Does not free the list itself, which may be
@@ -521,10 +504,7 @@ void
 _cpp_free_toklist (list)
      const cpp_toklist *list;
 {
-  if (list->flags & LIST_OFFSET)
-    free (list->tokens - 1);   /* Backup over dummy token.  */
-  else
-    free (list->tokens);
+  free (list->tokens);
   free (list->namebuf);
 }
 
@@ -633,7 +613,8 @@ trigraph_ok (pfile, from_char)
 {
   int accept = CPP_OPTION (pfile, trigraphs);
   
-  if (CPP_OPTION (pfile, warn_trigraphs))
+  /* Don't warn about trigraphs in comments.  */
+  if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
     {
       cpp_buffer *buffer = pfile->buffer;
       if (accept)
@@ -768,6 +749,7 @@ skip_block_comment (pfile)
   cpp_buffer *buffer = pfile->buffer;
   cppchar_t c = EOF, prevc;
 
+  pfile->state.lexing_comment = 1;
   while (buffer->cur != buffer->rlimit)
     {
       prevc = c, c = *buffer->cur++;
@@ -812,6 +794,7 @@ skip_block_comment (pfile)
        adjust_column (pfile);
     }
 
+  pfile->state.lexing_comment = 0;
   buffer->read_ahead = EOF;
   return c != '/' || prevc != '*';
 }
@@ -820,12 +803,14 @@ skip_block_comment (pfile)
    non-zero if a multiline comment.  The following new line, if any,
    is left in buffer->read_ahead.  */
 static int
-skip_line_comment (buffer)
-     cpp_buffer *buffer;
+skip_line_comment (pfile)
+     cpp_reader *pfile;
 {
+  cpp_buffer *buffer = pfile->buffer;
   unsigned int orig_lineno = buffer->lineno;
   cppchar_t c;
 
+  pfile->state.lexing_comment = 1;
   do
     {
       c = EOF;
@@ -838,6 +823,7 @@ skip_line_comment (buffer)
     }
   while (!is_vspace (c));
 
+  pfile->state.lexing_comment = 0;
   buffer->read_ahead = c;      /* Leave any newline for caller.  */
   return orig_lineno != buffer->lineno;
 }
@@ -966,11 +952,15 @@ parse_number (pfile, number, c)
   cpp_buffer *buffer = pfile->buffer;
   unsigned int orig_used = pfile->token_list.name_used;
 
+  /* Reserve space for a leading period.  */
+  if (pfile->state.seen_dot)
+    pfile->token_list.name_used++;
+
   do
     {
       do
        {
-         if (pfile->token_list.name_used == pfile->token_list.name_cap)
+         if (pfile->token_list.name_used >= pfile->token_list.name_cap)
            _cpp_expand_name_space (&pfile->token_list,
                                    pfile->token_list.name_used + 256);
          pfile->token_list.namebuf[pfile->token_list.name_used++] = c;
@@ -991,6 +981,10 @@ parse_number (pfile, number, c)
     }
   while (is_numchar (c) || c == '.' || VALID_SIGN (c, prevc));
 
+  /* Put any leading period in place, now we have the room.  */
+  if (pfile->state.seen_dot)
+    pfile->token_list.namebuf[orig_used] = '.';
+
   /* Remember the next character.  */
   buffer->read_ahead = c;
 
@@ -1144,27 +1138,99 @@ save_comment (pfile, token, from)
   memcpy (buffer, from, len - COMMENT_START_LEN);
 }
 
-/* A helper routine for lex_token.  With some long tokens, we need
-   to read ahead to see if that is the token we have, but back-track
-   if not.  */
+/* Subroutine of lex_token to handle '%'.  A little tricky, since we
+   want to avoid stepping back when lexing %:%X.  */
 static void
-check_long_token (buffer, result, wanted, type)
+lex_percent (buffer, result)
      cpp_buffer *buffer;
      cpp_token *result;
-     cppchar_t wanted;
-     enum cpp_ttype type;
 {
-  const unsigned char *saved_cur;
-  cppchar_t c = buffer->read_ahead;
+  cppchar_t c;
+
+  result->type = CPP_MOD;
+  /* Parsing %:%X could leave an extra character.  */
+  if (buffer->extra_char == EOF)
+    c = get_effective_char (buffer);
+  else
+    {
+      c = buffer->read_ahead = buffer->extra_char;
+      buffer->extra_char = EOF;
+    }
+
+  if (c == '=')
+    ACCEPT_CHAR (CPP_MOD_EQ);
+  else if (CPP_OPTION (buffer->pfile, digraphs))
+    {
+      if (c == ':')
+       {
+         result->flags |= DIGRAPH;
+         ACCEPT_CHAR (CPP_HASH);
+         if (get_effective_char (buffer) == '%')
+           {
+             buffer->extra_char = get_effective_char (buffer);
+             if (buffer->extra_char == ':')
+               {
+                 buffer->extra_char = EOF;
+                 ACCEPT_CHAR (CPP_PASTE);
+               }
+             else
+               /* We'll catch the extra_char when we're called back.  */
+               buffer->read_ahead = '%';
+           }
+       }
+      else if (c == '>')
+       {
+         result->flags |= DIGRAPH;
+         ACCEPT_CHAR (CPP_CLOSE_BRACE);
+       }
+    }
+}
+
+/* Subroutine of lex_token to handle '.'.  This is tricky, since we
+   want to avoid stepping back when lexing '...' or '.123'.  In the
+   latter case we should also set a flag for parse_number.  */
+static void
+lex_dot (pfile, result)
+     cpp_reader *pfile;
+     cpp_token *result;
+{
+  cpp_buffer *buffer = pfile->buffer;
+  cppchar_t c;
+
+  /* Parsing ..X could leave an extra character.  */
+  if (buffer->extra_char == EOF)
+    c = get_effective_char (buffer);
+  else
+    {
+      c = buffer->read_ahead = buffer->extra_char;
+      buffer->extra_char = EOF;
+    }
 
-  SAVE_STATE ();
-  if (get_effective_char (buffer) == wanted)
-    ACCEPT_CHAR (type);
+  /* All known character sets have 0...9 contiguous.  */
+  if (c >= '0' && c <= '9')
+    {
+      result->type = CPP_NUMBER;
+      buffer->pfile->state.seen_dot = 1;
+      parse_number (pfile, &result->val.str, c);
+      buffer->pfile->state.seen_dot = 0;
+    }
   else
     {
-      /* Restore state.  */
-      RESTORE_STATE ();
-      buffer->read_ahead = c;
+      result->type = CPP_DOT;
+      if (c == '.')
+       {
+         buffer->extra_char = get_effective_char (buffer);
+         if (buffer->extra_char == '.')
+           {
+             buffer->extra_char = EOF;
+             ACCEPT_CHAR (CPP_ELLIPSIS);
+           }
+         else
+           /* We'll catch the extra_char when we're called back.  */
+           buffer->read_ahead = '.';
+       }
+      else if (c == '*' && CPP_OPTION (pfile, cplusplus))
+       ACCEPT_CHAR (CPP_DOT_STAR);
     }
 }
 
@@ -1245,7 +1311,6 @@ lex_token (pfile, result)
       }
       break;
 
-    make_number:
     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
       result->type = CPP_NUMBER;
@@ -1342,7 +1407,7 @@ lex_token (pfile, result)
              comment_start = buffer->cur;
 
              /* Skip_line_comment updates buffer->read_ahead.  */
-             if (skip_line_comment (buffer))
+             if (skip_line_comment (pfile))
                cpp_warning_with_line (pfile, result->line, result->col,
                                       "multi-line comment");
 
@@ -1413,57 +1478,12 @@ lex_token (pfile, result)
        }
       break;
 
-    case '.':
-      {
-       const unsigned char *saved_cur;
-       cppchar_t c1;
-
-       /* Save state to avoid needing to pass 2 chars to parse_number.  */
-       SAVE_STATE ();
-       c1 = get_effective_char (buffer);
-       /* All known character sets have 0...9 contiguous.  */
-       if (c1 >= '0' && c1 <= '9')
-         {
-           RESTORE_STATE ();
-           goto make_number;
-         }
-
-       result->type = CPP_DOT;
-       if (c1 == '.')
-         {
-           if (get_effective_char (buffer) == '.')
-             ACCEPT_CHAR (CPP_ELLIPSIS);
-           else
-             {
-               buffer->read_ahead = EOF;
-               RESTORE_STATE ();
-             }
-         }
-       else if (c1 == '*' && CPP_OPTION (pfile, cplusplus))
-         ACCEPT_CHAR (CPP_DOT_STAR);
-      }
+    case '%':
+      lex_percent (buffer, result);
       break;
 
-    case '%':
-      result->type = CPP_MOD;
-      c = get_effective_char (buffer);
-      if (c == '=')
-       ACCEPT_CHAR (CPP_MOD_EQ);
-      else if (CPP_OPTION (pfile, digraphs))
-       {
-         if (c == ':')
-           {
-             result->flags |= DIGRAPH;
-             ACCEPT_CHAR (CPP_HASH);
-             if (get_effective_char (buffer) == '%')
-               check_long_token (buffer, result, ':', CPP_PASTE);
-           }
-         else if (c == '>')
-           {
-             result->flags |= DIGRAPH;
-             ACCEPT_CHAR (CPP_CLOSE_BRACE);
-           }
-       }
+    case '.':
+      lex_dot (pfile, result);
       break;
 
     case '+':
@@ -1610,9 +1630,6 @@ lex_line (pfile, list)
   cpp_token *cur_token, *first;
   cpp_buffer *buffer = pfile->buffer;
 
-  if (!(list->flags & LIST_OFFSET))
-    (abort) ();
-
   pfile->state.in_lex_line = 1;
   if (pfile->buffer->cur == pfile->buffer->buf)
     list->flags |= BEG_OF_FILE;
@@ -3397,7 +3414,7 @@ _cpp_init_input_buffer (pfile)
 {
   cpp_context *base;
 
-  _cpp_init_toklist (&pfile->token_list, DUMMY_TOKEN);
+  _cpp_init_toklist (&pfile->token_list, 0);
   pfile->no_expand_level = UINT_MAX;
   pfile->context_cap = 20;
   pfile->cur_context = 0;
index 31064863cac20f075ddb370aac202d91150e02d6..8c61ab0c222c4a9b9b63e1bc11d9bea9241c9e83 100644 (file)
@@ -1247,7 +1247,7 @@ _cpp_parse_assertion (pfile, answerp)
   /* Allocate a struct answer, and copy the answer to it.  */
   answer = (struct answer *) xmalloc (sizeof (struct answer));
   list = &answer->list;
-  _cpp_init_toklist (list, NO_DUMMY_TOKEN);
+  _cpp_init_toklist (list, 1); /* Empty.  */
 
   for (;;)
     {
@@ -1516,7 +1516,9 @@ cpp_push_buffer (pfile, buffer, length)
   new->rlimit = buffer + length;
   new->prev = buf;
   new->pfile = pfile;
+  /* No read ahead or extra char initially.  */
   new->read_ahead = EOF;
+  new->extra_char = EOF;
 
   CPP_BUFFER (pfile) = new;
   return new;
index 75115375664cb8ee9a9cb1b5214f5cb092f17e6d..15c30abc67d56abfa8de2207f589fcd7ab993ab8 100644 (file)
@@ -182,9 +182,8 @@ struct cpp_token
 };
 
 /* cpp_toklist flags.  */
-#define LIST_OFFSET     (1 << 0)
-#define VAR_ARGS       (1 << 1)
-#define BEG_OF_FILE    (1 << 2)
+#define VAR_ARGS       (1 << 0)
+#define BEG_OF_FILE    (1 << 1)
 
 struct directive;              /* These are deliberately incomplete.  */
 struct answer;
@@ -225,6 +224,7 @@ struct cpp_buffer
   const unsigned char *rlimit; /* end of valid data */
   const unsigned char *line_base; /* start of current line */
   cppchar_t read_ahead;                /* read ahead character */
+  cppchar_t extra_char;                /* extra read-ahead for long tokens.  */
 
   struct cpp_reader *pfile;    /* Owns this buffer.  */
   struct cpp_buffer *prev;
@@ -460,8 +460,14 @@ struct lexer_state
   /* Nonzero to get force the lexer to skip newlines.  */
   unsigned char skip_newlines;
 
-  /* If we're in the subroutine lex_line.  */
+  /* Nonzero if we're in the subroutine lex_line.  */
   unsigned char in_lex_line;
+
+  /* Nonzero if we're mid-comment.  */
+  unsigned char lexing_comment;
+
+  /* Tells parse_number we saw a leading period.  */
+  unsigned char seen_dot;
 };
 #define IN_DIRECTIVE(pfile) (pfile->state.in_directive)
 #define KNOWN_DIRECTIVE(list) (list->directive != 0)