This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: C frontend cpplib integration patch


Zack,

Can I get you to review this? I'm on vacation until August 4.

Dave

Jason Merrill wrote:

> In the interest of keeping C and C++ synchronized, here's a patch to
> implement the same cpplib integration that I recently checked in for the
> C++ frontend.  It also removes a few other divergences; the significant one
> being changing to handling #-directives on a token-by-token basis rather
> than character-by-character, using a new variable 'linemode' to avoid
> crossing end-of-line when reading the next token.  This makes check_newline
> much simpler.
>
> Fri Jul 23 17:15:10 1999  Jason Merrill  <jason@yorick.cygnus.com>
>
>         * c-lex.c: Sync with C++ frontend.
>         (linemode): New variable.
>         (parse_float): imag, conversion_errno, and type are output only.
>         (yylex): Adjust.  Move initial '.' case into main switch.
>         Use linemode.
>         (handle_generic_pragma): Just deal with tokens.
>         (readescape): Use ISXDIGIT and ISGRAPH.
>         * c-parse.in: Add END_OF_LINE token.
>
>         * c-lex.c (lang_init): Generalize.
>         (nextchar): Remove.  Replace uses with UNGETC.
>         (skip_white_space): Handle linemode here.  Optimize for cpplib.
>         (skip_white_space_on_line): Remove.
>         (extend_token_buffer_to): New fn.
>         (extend_token_buffer): Use it.
>         (read_line_number, check_newline): Just deal with tokens.
>         (token_getch, token_put_back): New fns.
>         (yylex): Use them.  More cpplib optimizations.  Simplify.
>
> Fri Jul 23 17:15:10 1999  Michael Tiemann  <tiemann@holodeck.cygnus.com>
>                           Jason Merrill  <jason@yorick.cygnus.com>
>
>         * c-lex.c (init_parse): Set cpp_token to CPP_DIRECTIVE.
>         (consume_string): Make this smart about USE_CPPLIB.
>         (check_newline): Rewrite to be intelligent about USE_CPPLIB.
>         (yylex): Rewrite to be intelligent about USE_CPPLIB.
>         Also, clean up cases where we redundantly set token_buffer[0].
>         (read_line_number): New fn.
>         (ignore_escape_flag): New variable.
>
> Index: c-parse.in
> ===================================================================
> RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-parse.in,v
> retrieving revision 1.16
> diff -c -p -r1.16 c-parse.in
> *** c-parse.in  1999/04/26 22:35:50     1.16
> --- c-parse.in  1999/07/24 00:27:16
> *************** end ifc
> *** 138,143 ****
> --- 138,146 ----
>   %token ATTRIBUTE EXTENSION LABEL
>   %token REALPART IMAGPART
>
> + /* Used in c-lex.c for parsing pragmas.  */
> + %token END_OF_LINE
> +
>   /* Add precedence rules to solve dangling else s/r conflict */
>   %nonassoc IF
>   %nonassoc ELSE
> Index: c-lex.c
> ===================================================================
> RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-lex.c,v
> retrieving revision 1.54
> diff -c -p -r1.54 c-lex.c
> *** c-lex.c     1999/07/21 12:48:05     1.54
> --- c-lex.c     1999/07/24 00:27:16
> ***************
> *** 1,5 ****
>   /* Lexical analyzer for C and Objective C.
> !    Copyright (C) 1987, 88, 89, 92, 94-97, 1998 Free Software Foundation, Inc.
>
>   This file is part of GNU CC.
>
> --- 1,5 ----
>   /* Lexical analyzer for C and Objective C.
> !    Copyright (C) 1987, 88, 89, 92, 94-98, 1999 Free Software Foundation, Inc.
>
>   This file is part of GNU CC.
>
> *************** tree ridpointers[(int) RID_MAX];
> *** 67,72 ****
> --- 67,73 ----
>
>   #if USE_CPPLIB
>   extern unsigned char *yy_cur, *yy_lim;
> + extern enum cpp_token cpp_token;
>
>   extern int yy_get_token ();
>
> *************** put_back (ch)
> *** 114,119 ****
> --- 115,122 ----
>   }
>   #endif /* ! USE_CPPLIB */
>
> + int linemode;
> +
>   /* the declaration found for the last IDENTIFIER token read in.
>      yylex must look this up to detect typedefs, which get token type TYPENAME,
>      so it is left around in case the identifier is not a typedef but is
> *************** static int maxtoken;            /* Current nominal
> *** 144,166 ****
>   char *token_buffer;   /* Pointer to token buffer.
>                            Actual allocated length is maxtoken + 2.
>                            This is not static because objc-parse.y uses it.  */
>
> ! static int indent_level = 0;        /* Number of { minus number of }. */
>
>   /* Nonzero if end-of-file has been seen on input.  */
>   static int end_of_file;
>
> - #if !USE_CPPLIB
> - /* Buffered-back input character; faster than using ungetc.  */
> - static int nextchar = -1;
> - #endif
> -
>   #ifdef HANDLE_GENERIC_PRAGMAS
>   static int handle_generic_pragma      PROTO((int));
>   #endif /* HANDLE_GENERIC_PRAGMAS */
>   static int whitespace_cr              PROTO((int));
>   static int skip_white_space           PROTO((int));
> - static int skip_white_space_on_line   PROTO((void));
>   static char *extend_token_buffer      PROTO((const char *));
>   static int readescape                 PROTO((int *));
>   static void parse_float                       PROTO((PTR));
> --- 147,166 ----
>   char *token_buffer;   /* Pointer to token buffer.
>                            Actual allocated length is maxtoken + 2.
>                            This is not static because objc-parse.y uses it.  */
> +
> + static int indent_level;        /* Number of { minus number of }. */
>
> ! /* Nonzero tells yylex to ignore \ in string constants.  */
> ! static int ignore_escape_flag;
>
>   /* Nonzero if end-of-file has been seen on input.  */
>   static int end_of_file;
>
>   #ifdef HANDLE_GENERIC_PRAGMAS
>   static int handle_generic_pragma      PROTO((int));
>   #endif /* HANDLE_GENERIC_PRAGMAS */
>   static int whitespace_cr              PROTO((int));
>   static int skip_white_space           PROTO((int));
>   static char *extend_token_buffer      PROTO((const char *));
>   static int readescape                 PROTO((int *));
>   static void parse_float                       PROTO((PTR));
> *************** init_parse (filename)
> *** 247,252 ****
> --- 247,253 ----
>        token buffer.  We must arrange to read it out here. */
>     yy_cur = parse_in.token_buffer;
>     yy_lim = CPP_PWRITTEN (&parse_in);
> +   cpp_token = CPP_DIRECTIVE;
>   #endif
>
>     init_lex ();
> *************** skip_white_space (c)
> *** 435,440 ****
> --- 436,446 ----
>              Also, there's no need, since cpp removes all comments.  */
>
>         case '\n':
> +         if (linemode)
> +           {
> +             UNGETC (c);
> +             return EOF;
> +           }
>           c = check_newline ();
>           break;
>
> *************** skip_white_space (c)
> *** 443,449 ****
>         case '\f':
>         case '\v':
>         case '\b':
> !         c = GETC();
>           break;
>
>         case '\r':
> --- 449,462 ----
>         case '\f':
>         case '\v':
>         case '\b':
> ! #if USE_CPPLIB
> !         /* While processing a # directive we don't get CPP_HSPACE
> !            tokens, so we also need to handle whitespace the normal way.  */
> !         if (cpp_token == CPP_HSPACE)
> !           c = yy_get_token ();
> !         else
> ! #endif
> !           c = GETC();
>           break;
>
>         case '\r':
> *************** skip_white_space (c)
> *** 466,535 ****
>       }
>   }
>
> ! /* Skips all of the white space at the current location in the input file.
> !    Must use and reset nextchar if it has the next character.  */
>
>   void
>   position_after_white_space ()
>   {
>     register int c;
>
> ! #if !USE_CPPLIB
> !   if (nextchar != -1)
> !     c = nextchar, nextchar = -1;
> !   else
> ! #endif
> !     c = GETC();
>
>     UNGETC (skip_white_space (c));
>   }
>
> - /* Like skip_white_space, but don't advance beyond the end of line.
> -    Moreover, we don't get passed a character to start with.  */
> - static int
> - skip_white_space_on_line ()
> - {
> -   register int c;
> -
> -   while (1)
> -     {
> -       c = GETC();
> -       switch (c)
> -       {
> -       case '\n':
> -       default:
> -         break;
> -
> -       case ' ':
> -       case '\t':
> -       case '\f':
> -       case '\v':
> -       case '\b':
> -         continue;
> -
> -       case '\r':
> -         whitespace_cr (c);
> -         continue;
> -       }
> -       break;
> -     }
> -   return c;
> - }
> -
>   /* Make the token buffer longer, preserving the data in it.
>      P should point to just beyond the last valid character in the old buffer.
>      The value we return is a pointer to the new buffer
>      at a place corresponding to P.  */
>
>   static char *
>   extend_token_buffer (p)
>        const char *p;
>   {
>     int offset = p - token_buffer;
> !
> !   maxtoken = maxtoken * 2 + 10;
> !   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
> !
>     return token_buffer + offset;
>   }
>
> --- 479,517 ----
>       }
>   }
>
> ! /* Skips all of the white space at the current location in the input file.  */
>
>   void
>   position_after_white_space ()
>   {
>     register int c;
>
> !   c = GETC();
>
>     UNGETC (skip_white_space (c));
>   }
>
>   /* Make the token buffer longer, preserving the data in it.
>      P should point to just beyond the last valid character in the old buffer.
>      The value we return is a pointer to the new buffer
>      at a place corresponding to P.  */
>
> + static void
> + extend_token_buffer_to (size)
> +      int size;
> + {
> +   do
> +     maxtoken = maxtoken * 2 + 10;
> +   while (maxtoken < size);
> +   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
> + }
> +
>   static char *
>   extend_token_buffer (p)
>        const char *p;
>   {
>     int offset = p - token_buffer;
> !   extend_token_buffer_to (offset);
>     return token_buffer + offset;
>   }
>
> *************** pragma_ungetc (arg)
> *** 549,900 ****
>   }
>   #endif
>
>   /* At the beginning of a line, increment the line number
>      and process any #-directive on this line.
>      If the line is a #-directive, read the entire line and return a newline.
> !    Otherwise, return the line's first non-whitespace character.  */
>
>   int
>   check_newline ()
>   {
>     register int c;
>     register int token;
> !
> !   lineno++;
>
>     /* Read first nonwhite char on the line.  */
>
> !   c = GETC();
> !   while (c == ' ' || c == '\t')
> !     c = GETC();
>
>     if (c != '#')
>       {
>         /* If not #, return it so caller will use it.  */
>         return c;
>       }
> -
> -   /* Read first nonwhite char after the `#'.  */
>
> !   c = GETC();
> !   while (c == ' ' || c == '\t')
> !     c = GETC();
>
> !   /* If a letter follows, then if the word here is `line', skip
> !      it and ignore it; otherwise, ignore the line, with an error
> !      if the word isn't `pragma', `ident', `define', or `undef'.  */
>
> !   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
>       {
> !       if (c == 'p')
> !       {
> !         if (GETC() == 'r'
> !             && GETC() == 'a'
> !             && GETC() == 'g'
> !             && GETC() == 'm'
> !             && GETC() == 'a'
> !             && ((c = GETC()) == ' ' || c == '\t' || c == '\n'
> !                  || whitespace_cr (c) ))
> !           {
> !             while (c == ' ' || c == '\t' || whitespace_cr (c))
> !               c = GETC ();
> !             if (c == '\n')
> !               return c;
> !
> ! #if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS
> !             UNGETC (c);
> !             token = yylex ();
> !             if (token != IDENTIFIER)
> !               goto skipline;
> ! #endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */
>
> ! #ifdef HANDLE_PRAGMA
> !             /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if
> !                both are defined), in order to give the back end a chance to
> !                override the interpretation of generic style pragmas.  */
> ! #if !USE_CPPLIB
> !             if (nextchar >= 0)
> !               {
> !                 c = nextchar, nextchar = -1;
> !                 UNGETC (c);
> !               }
> ! #endif /* !USE_CPPLIB */
>
> !             if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
> !               goto skipline;
>
> !             if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
> !                                IDENTIFIER_POINTER (yylval.ttype)))
> !               return GETC ();
>   #endif /* HANDLE_PRAGMA */
> !
>   #ifdef HANDLE_GENERIC_PRAGMAS
> !             if (handle_generic_pragma (token))
> !               return GETC ();
>   #endif /* HANDLE_GENERIC_PRAGMAS */
>
> !             /* Issue a warning message if we have been asked to do so.
> !                Ignoring unknown pragmas in system header file unless
> !                an explcit -Wunknown-pragmas has been given. */
> !             if (warn_unknown_pragmas > 1
> !                 || (warn_unknown_pragmas && ! in_system_header))
> !               warning ("ignoring pragma: %s", token_buffer);
>
> !             goto skipline;
> !           }
>         }
> !
> !       else if (c == 'd')
>         {
> !         if (GETC() == 'e'
> !             && GETC() == 'f'
> !             && GETC() == 'i'
> !             && GETC() == 'n'
> !             && GETC() == 'e'
> !             && ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
> !           {
> !             if (c != '\n')
> !               debug_define (lineno, GET_DIRECTIVE_LINE ());
> !             goto skipline;
> !           }
>         }
> !       else if (c == 'u')
>         {
> !         if (GETC() == 'n'
> !             && GETC() == 'd'
> !             && GETC() == 'e'
> !             && GETC() == 'f'
> !             && ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
> !           {
> !             if (c != '\n')
> !               debug_undef (lineno, GET_DIRECTIVE_LINE ());
> !             goto skipline;
> !           }
>         }
> !       else if (c == 'l')
>         {
> !         if (GETC() == 'i'
> !             && GETC() == 'n'
> !             && GETC() == 'e'
> !             && ((c = GETC()) == ' ' || c == '\t'))
> !           goto linenum;
>         }
> !       else if (c == 'i')
>         {
> !         if (GETC() == 'd'
> !             && GETC() == 'e'
> !             && GETC() == 'n'
> !             && GETC() == 't'
> !             && ((c = GETC()) == ' ' || c == '\t'))
> !           {
> !             /* #ident.  The pedantic warning is now in cccp.c.  */
> !
> !             /* Here we have just seen `#ident '.
> !                A string constant should follow.  */
> !
> !             c = skip_white_space_on_line ();
>
> !             /* If no argument, ignore the line.  */
> !             if (c == '\n')
> !               return c;
>
> !             UNGETC (c);
> !             token = yylex ();
> !             if (token != STRING
> !                 || TREE_CODE (yylval.ttype) != STRING_CST)
> !               {
> !                 error ("invalid #ident");
> !                 goto skipline;
> !               }
>
> !             if (!flag_no_ident)
> !               {
>   #ifdef ASM_OUTPUT_IDENT
> !                 ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
>   #endif
> -               }
> -
> -             /* Skip the rest of this line.  */
> -             goto skipline;
>             }
>         }
>
> !       error ("undefined or invalid # directive");
>         goto skipline;
>       }
>
>   linenum:
>     /* Here we have either `#line' or `# <nonletter>'.
>        In either case, it should be a line number; a digit should follow.  */
>
> !   /* Can't use skip_white_space here, but must handle all whitespace
> !      that is not '\n', lest we get a recursion for '\r' '\n' when
> !      calling yylex.  */
> !   UNGETC (c);
> !   c = skip_white_space_on_line ();
>
> !   /* If the # is the only nonwhite char on the line,
> !      just ignore it.  Check the new newline.  */
> !   if (c == '\n')
> !     return c;
>
> !   /* Something follows the #; read a token.  */
>
> !   UNGETC (c);
> !   token = yylex ();
>
> !   if (token == CONSTANT
> !       && TREE_CODE (yylval.ttype) == INTEGER_CST)
>       {
> !       int old_lineno = lineno;
> !       int used_up = 0;
> !       /* subtract one, because it is the following line that
> !        gets the specified number */
> !
> !       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
>
> !       /* Is this the last nonwhite stuff on the line?  */
> !       c = skip_white_space_on_line ();
> !       if (c == '\n')
> !       {
> !         /* No more: store the line number and check following line.  */
> !         lineno = l;
> !         return c;
> !       }
> !       UNGETC (c);
>
> !       /* More follows: it must be a string constant (filename).  */
>
> !       /* Read the string constant.  */
> !       token = yylex ();
>
> !       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
> !       {
> !         error ("invalid #line");
> !         goto skipline;
> !       }
>
>         input_filename
>         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
>         strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
> !       lineno = l;
> !
> !       /* Each change of file name
> !        reinitializes whether we are now in a system header.  */
> !       in_system_header = 0;
> !
> !       if (main_input_filename == 0)
> !       main_input_filename = input_filename;
> !
> !       /* Is this the last nonwhite stuff on the line?  */
> !       c = skip_white_space_on_line ();
> !       if (c == '\n')
> !       {
> !         /* Update the name in the top element of input_file_stack.  */
> !         if (input_file_stack)
> !           input_file_stack->name = input_filename;
> !
> !         return c;
> !       }
> !       UNGETC (c);
> !
> !       token = yylex ();
> !       used_up = 0;
>
> !       /* `1' after file name means entering new file.
> !        `2' after file name means just left a file.  */
>
> !       if (token == CONSTANT
> !         && TREE_CODE (yylval.ttype) == INTEGER_CST)
> !       {
> !         if (TREE_INT_CST_LOW (yylval.ttype) == 1)
> !           {
> !             /* Pushing to a new file.  */
> !             struct file_stack *p
> !               = (struct file_stack *) xmalloc (sizeof (struct file_stack));
> !             input_file_stack->line = old_lineno;
> !             p->next = input_file_stack;
> !             p->name = input_filename;
> !             p->indent_level = indent_level;
> !             input_file_stack = p;
> !             input_file_stack_tick++;
> !             debug_start_source_file (input_filename);
> !             used_up = 1;
> !           }
> !         else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
> !           {
> !             /* Popping out of a file.  */
> !             if (input_file_stack->next)
> !               {
> !                 struct file_stack *p = input_file_stack;
> !                 if (indent_level != p->indent_level)
> !                   {
> !                     warning_with_file_and_line
> !                       (p->name, old_lineno,
> !                        "This file contains more `%c's than `%c's.",
> !                        indent_level > p->indent_level ? '{' : '}',
> !                        indent_level > p->indent_level ? '}' : '{');
> !                   }
> !                 input_file_stack = p->next;
> !                 free (p);
> !                 input_file_stack_tick++;
> !                 debug_end_source_file (input_file_stack->line);
> !               }
> !             else
> !               error ("#-lines for entering and leaving files don't match");
>
> !             used_up = 1;
> !           }
> !       }
>
> !       /* Now that we've pushed or popped the input stack,
> !        update the name in the top element.  */
>         if (input_file_stack)
>         input_file_stack->name = input_filename;
>
> !       /* If we have handled a `1' or a `2',
> !        see if there is another number to read.  */
> !       if (used_up)
> !       {
> !         /* Is this the last nonwhite stuff on the line?  */
> !         c = skip_white_space_on_line ();
> !         if (c == '\n')
> !           return c;
> !         UNGETC (c);
>
> !         token = yylex ();
> !         used_up = 0;
> !       }
> !
>         /* `3' after file name means this is a system header file.  */
>
> !       if (token == CONSTANT
> !         && TREE_CODE (yylval.ttype) == INTEGER_CST
> !         && TREE_INT_CST_LOW (yylval.ttype) == 3)
> !       in_system_header = 1, used_up = 1;
>
> !       if (used_up)
>         {
> !         /* Is this the last nonwhite stuff on the line?  */
> !         c = skip_white_space_on_line ();
> !         if (c == '\n')
> !           return c;
> !         UNGETC (c);
>         }
> !
> !       warning ("unrecognized text at end of #line");
>       }
> -   else
> -     error ("invalid #-line");
>
>     /* skip the rest of this line.  */
>    skipline:
> ! #if !USE_CPPLIB
> !   if (c != '\n' && c != EOF && nextchar >= 0)
> !     c = nextchar, nextchar = -1;
> ! #endif
> !   while (c != '\n' && c != EOF)
>       c = GETC();
>     return c;
>   }
>
> --- 531,857 ----
>   }
>   #endif
>
> + static int
> + read_line_number (num)
> +      int *num;
> + {
> +   register int token = yylex ();
> +
> +   if (token == CONSTANT
> +       && TREE_CODE (yylval.ttype) == INTEGER_CST)
> +     {
> +       *num = TREE_INT_CST_LOW (yylval.ttype);
> +       return 1;
> +     }
> +   else
> +     {
> +       if (token != END_OF_LINE)
> +       error ("invalid #-line");
> +       return 0;
> +     }
> + }
> +
>   /* At the beginning of a line, increment the line number
>      and process any #-directive on this line.
>      If the line is a #-directive, read the entire line and return a newline.
> !    Otherwise, return the line's first non-whitespace character.
> !
> !    Note that in the case of USE_CPPLIB, we get the whole line as one
> !    CPP_DIRECTIVE token.  */
>
>   int
>   check_newline ()
>   {
>     register int c;
>     register int token;
> !   int saw_line;
> !   enum { act_none, act_push, act_pop } action;
> !   int old_lineno, action_number, l;
>
> +  restart:
>     /* Read first nonwhite char on the line.  */
>
> ! #ifdef USE_CPPLIB
> !   c = GETC ();
> !   /* In some cases where we're leaving an include file, we can get multiple
> !      CPP_HSPACE tokens in a row, so we need to loop.  */
> !   while (cpp_token == CPP_HSPACE)
> !     c = yy_get_token ();
> ! #else
> !   do
> !     c = GETC ();
> !   while (c == ' ' || c == '\t');
> ! #endif
>
> +   lineno++;
> +
>     if (c != '#')
>       {
> +       /* Sequences of multiple newlines are very common; optimize them.  */
> +       if (c == '\n')
> +       goto restart;
> +
>         /* If not #, return it so caller will use it.  */
>         return c;
>       }
>
> !   /* Don't read beyond this line.  */
> !   saw_line = 0;
> !   linemode = 1;
> !
> ! #if USE_CPPLIB
> !   if (cpp_token == CPP_VSPACE)
> !     {
> !       /* Format is "<space> <line number> <filename> <newline>".
> !        Only the line number is interesting, and even that
> !        we can get more efficiently than scanning the line.  */
> !       yy_cur = yy_lim - 1;
> !       lineno = parse_in.lineno - 1;
> !       goto skipline;
> !     }
> ! #endif
>
> !   token = yylex ();
>
> !   if (token == IDENTIFIER)
>       {
> !       /* If a letter follows, then if the word here is `line', skip
> !        it and ignore it; otherwise, ignore the line, with an error
> !        if the word isn't `pragma'.  */
>
> !       const char *name = IDENTIFIER_POINTER (yylval.ttype);
>
> !       if (!strcmp (name, "pragma"))
> !       {
> !         token = yylex ();
> !         if (token != IDENTIFIER
> !             || TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
> !           goto skipline;
>
> ! #ifdef HANDLE_PRAGMA
> !         /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS
> !            (if both are defined), in order to give the back
> !            end a chance to override the interpretation of
> !            SYSV style pragmas.  */
> !         if (HANDLE_PRAGMA (getch, put_back,
> !                            IDENTIFIER_POINTER (yylval.ttype)))
> !           goto skipline;
>   #endif /* HANDLE_PRAGMA */
> !
>   #ifdef HANDLE_GENERIC_PRAGMAS
> !         if (handle_generic_pragma (token))
> !           goto skipline;
>   #endif /* HANDLE_GENERIC_PRAGMAS */
>
> !         /* Issue a warning message if we have been asked to do so.
> !            Ignoring unknown pragmas in system header file unless
> !            an explcit -Wunknown-pragmas has been given. */
> !         if (warn_unknown_pragmas > 1
> !             || (warn_unknown_pragmas && ! in_system_header))
> !           warning ("ignoring pragma: %s", token_buffer);
>
> !         goto skipline;
>         }
> !       else if (!strcmp (name, "define"))
>         {
> !         debug_define (lineno, GET_DIRECTIVE_LINE ());
> !         goto skipline;
>         }
> !       else if (!strcmp (name, "undef"))
>         {
> !         debug_undef (lineno, GET_DIRECTIVE_LINE ());
> !         goto skipline;
>         }
> !       else if (!strcmp (name, "line"))
>         {
> !         saw_line = 1;
> !         token = yylex ();
> !         goto linenum;
>         }
> !       else if (!strcmp (name, "ident"))
>         {
> !         /* #ident.  The pedantic warning is now in cccp.c.  */
>
> !         /* Here we have just seen `#ident '.
> !            A string constant should follow.  */
>
> !         token = yylex ();
> !         if (token == END_OF_LINE)
> !           goto skipline;
> !         if (token != STRING
> !             || TREE_CODE (yylval.ttype) != STRING_CST)
> !           {
> !             error ("invalid #ident");
> !             goto skipline;
> !           }
>
> !         if (! flag_no_ident)
> !           {
>   #ifdef ASM_OUTPUT_IDENT
> !             ASM_OUTPUT_IDENT (asm_out_file,
> !                               TREE_STRING_POINTER (yylval.ttype));
>   #endif
>             }
> +
> +         /* Skip the rest of this line.  */
> +         goto skipline;
>         }
>
> !       error ("undefined or invalid # directive `%s'", name);
>         goto skipline;
>       }
>
> +   /* If the # is the only nonwhite char on the line,
> +      just ignore it.  Check the new newline.  */
> +   if (token == END_OF_LINE)
> +     goto skipline;
> +
>   linenum:
>     /* Here we have either `#line' or `# <nonletter>'.
>        In either case, it should be a line number; a digit should follow.  */
>
> !   if (token != CONSTANT
> !       || TREE_CODE (yylval.ttype) != INTEGER_CST)
> !     {
> !       error ("invalid #-line");
> !       goto skipline;
> !     }
>
> !   /* subtract one, because it is the following line that
> !      gets the specified number */
>
> !   l = TREE_INT_CST_LOW (yylval.ttype) - 1;
>
> !   /* More follows: it must be a string constant (filename).
> !      It would be neat to use cpplib to quickly process the string, but
> !      (1) we don't have a handy tokenization of the string, and
> !      (2) I don't know how well that would work in the presense
> !      of filenames that contain wide characters.  */
>
> !   if (saw_line)
>       {
> !       /* Don't treat \ as special if we are processing #line 1 "...".
> !        If you want it to be treated specially, use # 1 "...".  */
> !       ignore_escape_flag = 1;
> !     }
>
> !   /* Read the string constant.  */
> !   token = yylex ();
>
> !   ignore_escape_flag = 0;
>
> !   if (token == END_OF_LINE)
> !     {
> !       /* No more: store the line number and check following line.  */
> !       lineno = l;
> !       goto skipline;
> !     }
>
> !   if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
> !     {
> !       error ("invalid #line");
> !       goto skipline;
> !     }
>
> +   if (!TREE_PERMANENT (yylval.ttype))
> +     {
>         input_filename
>         = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
>         strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
> !     }
> !   else
> !     input_filename = TREE_STRING_POINTER (yylval.ttype);
>
> !   if (main_input_filename == 0)
> !     main_input_filename = input_filename;
>
> !   old_lineno = lineno;
> !   action = act_none;
> !   action_number = 0;
> !   lineno = l;
>
> !   /* Each change of file name
> !      reinitializes whether we are now in a system header.  */
> !   in_system_header = 0;
>
> !   if (!read_line_number (&action_number))
> !     {
> !       /* Update the name in the top element of input_file_stack.  */
>         if (input_file_stack)
>         input_file_stack->name = input_filename;
> +     }
>
> !   /* `1' after file name means entering new file.
> !      `2' after file name means just left a file.  */
>
> !   if (action_number == 1)
> !     {
> !       action = act_push;
> !       read_line_number (&action_number);
> !     }
> !   else if (action_number == 2)
> !     {
> !       action = act_pop;
> !       read_line_number (&action_number);
> !     }
> !   if (action_number == 3)
> !     {
>         /* `3' after file name means this is a system header file.  */
> +       in_system_header = 1;
> +       read_line_number (&action_number);
> +     }
>
> !   /* Do the actions implied by the preceding numbers.  */
>
> !   if (action == act_push)
> !     {
> !       /* Pushing to a new file.  */
> !       struct file_stack *p
> !       = (struct file_stack *) xmalloc (sizeof (struct file_stack));
> !       input_file_stack->line = old_lineno;
> !       p->next = input_file_stack;
> !       p->name = input_filename;
> !       p->indent_level = indent_level;
> !       input_file_stack = p;
> !       input_file_stack_tick++;
> !       debug_start_source_file (input_filename);
> !     }
> !   else if (action == act_pop)
> !     {
> !       /* Popping out of a file.  */
> !       if (input_file_stack->next)
>         {
> !         struct file_stack *p = input_file_stack;
> !         if (indent_level != p->indent_level)
> !           {
> !             warning_with_file_and_line
> !               (p->name, old_lineno,
> !                "This file contains more `%c's than `%c's.",
> !                indent_level > p->indent_level ? '{' : '}',
> !                indent_level > p->indent_level ? '}' : '{');
> !           }
> !         input_file_stack = p->next;
> !         free (p);
> !         input_file_stack_tick++;
> !         debug_end_source_file (input_file_stack->line);
>         }
> !       else
> !       error ("#-lines for entering and leaving files don't match");
>       }
>
> +   /* Now that we've pushed or popped the input stack,
> +      update the name in the top element.  */
> +   if (input_file_stack)
> +     input_file_stack->name = input_filename;
> +
>     /* skip the rest of this line.  */
>    skipline:
> !   linemode = 0;
> !   end_of_file = 0;
> !
> !   do
>       c = GETC();
> +   while (c != '\n' && c != EOF);
>     return c;
>   }
>
> *************** handle_generic_pragma (token)
> *** 923,944 ****
>         case CONSTANT:
>           handle_pragma_token (token_buffer, yylval.ttype);
>           break;
>         default:
>           handle_pragma_token (token_buffer, NULL);
>         }
> - #if !USE_CPPLIB
> -       if (nextchar >= 0)
> -       c = nextchar, nextchar = -1;
> -       else
> - #endif
> -       c = GETC ();
> -
> -       while (c == ' ' || c == '\t')
> -       c = GETC ();
> -       UNGETC (c);
> -
> -       if (c == '\n' || c == EOF)
> -       return handle_pragma_token (NULL, NULL);
>
>         token = yylex ();
>       }
> --- 880,892 ----
>         case CONSTANT:
>           handle_pragma_token (token_buffer, yylval.ttype);
>           break;
> +
> +       case END_OF_LINE:
> +         return handle_pragma_token (NULL_PTR, NULL_TREE);
> +
>         default:
>           handle_pragma_token (token_buffer, NULL);
>         }
>
>         token = yylex ();
>       }
> *************** readescape (ignore_ptr)
> *** 976,984 ****
>         while (1)
>         {
>           c = GETC();
> !         if (!(c >= 'a' && c <= 'f')
> !             && !(c >= 'A' && c <= 'F')
> !             && !(c >= '0' && c <= '9'))
>             {
>               UNGETC (c);
>               break;
> --- 924,930 ----
>         while (1)
>         {
>           c = GETC();
> !         if (! ISXDIGIT (c))
>             {
>               UNGETC (c);
>               break;
> *************** readescape (ignore_ptr)
> *** 1005,1011 ****
>         ;
>         else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
>                || (count > 1
> !                  && (((unsigned)1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
>                        <= firstdig)))
>         pedwarn ("hex escape out of range");
>         return code;
> --- 951,959 ----
>         ;
>         else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
>                || (count > 1
> !                  && (((unsigned)1
> !                       << (TYPE_PRECISION (integer_type_node)
> !                           - (count - 1) * 4))
>                        <= firstdig)))
>         pedwarn ("hex escape out of range");
>         return code;
> *************** readescape (ignore_ptr)
> *** 1076,1085 ****
>         /* `\%' is used to prevent SCCS from getting confused.  */
>       case '%':
>         if (pedantic)
> !       pedwarn ("non-ANSI escape sequence `\\%c'", c);
>         return c;
>       }
> !   if (c >= 040 && c < 0177)
>       pedwarn ("unknown escape sequence `\\%c'", c);
>     else
>       pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
> --- 1024,1033 ----
>         /* `\%' is used to prevent SCCS from getting confused.  */
>       case '%':
>         if (pedantic)
> !       pedwarn ("unknown escape sequence `\\%c'", c);
>         return c;
>       }
> !   if (ISGRAPH (c))
>       pedwarn ("unknown escape sequence `\\%c'", c);
>     else
>       pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
> *************** struct pf_args
> *** 1136,1145 ****
>     char * p;
>     /* I/O */
>     int c;
>     int imag;
>     tree type;
>     int conversion_errno;
> -   /* Output */
>     REAL_VALUE_TYPE value;
>   };
>
> --- 1084,1093 ----
>     char * p;
>     /* I/O */
>     int c;
> +   /* Output */
>     int imag;
>     tree type;
>     int conversion_errno;
>     REAL_VALUE_TYPE value;
>   };
>
> *************** parse_float (data)
> *** 1154,1159 ****
> --- 1102,1110 ----
>        REAL_VALUE_ATOF may not work any more.  */
>     char *copy = (char *) alloca (args->p - token_buffer + 1);
>     bcopy (token_buffer, copy, args->p - token_buffer + 1);
> +   args->imag = 0;
> +   args->conversion_errno = 0;
> +   args->type = double_type_node;
>
>     while (1)
>       {
> *************** parse_float (data)
> *** 1243,1248 ****
> --- 1194,1229 ----
>       }
>   }
>
> + /* Get the next character, staying within the current token if possible.
> +    If we're lexing a token, we don't want to look beyond the end of the
> +    token cpplib has prepared for us; otherwise, we end up reading in the
> +    next token, which screws up feed_input.  So just return a null
> +    character.  */
> +
> + inline int
> + token_getch ()
> + {
> + #if USE_CPPLIB
> +   if (yy_cur == yy_lim)
> +     return '\0';
> + #endif
> +   return GETC ();
> + }
> +
> + inline void
> + token_put_back (ch)
> +      int ch;
> + {
> + #if USE_CPPLIB
> +   if (ch == '\0')
> +     return;
> + #endif
> +   UNGETC (ch);
> + }
> +
> + /* Read a single token from the input stream, and assign it lexical
> +    semantics.  */
> +
>   int
>   yylex ()
>   {
> *************** yylex ()
> *** 1252,1263 ****
>     int wide_flag = 0;
>     int objc_flag = 0;
>
> ! #if !USE_CPPLIB
> !   if (nextchar >= 0)
> !     c = nextchar, nextchar = -1;
> !   else
> ! #endif
> !     c = GETC();
>
>     /* Effectively do c = skip_white_space (c)
>        but do it faster in the usual cases.  */
> --- 1233,1239 ----
>     int wide_flag = 0;
>     int objc_flag = 0;
>
> !   c = GETC();
>
>     /* Effectively do c = skip_white_space (c)
>        but do it faster in the usual cases.  */
> *************** yylex ()
> *** 1269,1275 ****
>         case '\f':
>         case '\v':
>         case '\b':
> !       c = GETC();
>         break;
>
>         case '\r':
> --- 1245,1256 ----
>         case '\f':
>         case '\v':
>         case '\b':
> ! #if USE_CPPLIB
> !       if (cpp_token == CPP_HSPACE)
> !         c = yy_get_token ();
> !       else
> ! #endif
> !         c = GETC();
>         break;
>
>         case '\r':
> *************** yylex ()
> *** 1294,1306 ****
>       case EOF:
>         end_of_file = 1;
>         token_buffer[0] = 0;
> !       value = ENDFILE;
>         break;
>
>       case 'L':
>         /* Capital L may start a wide-string or wide-character constant.  */
>         {
> !       register int c = GETC();
>         if (c == '\'')
>           {
>             wide_flag = 1;
> --- 1275,1294 ----
>       case EOF:
>         end_of_file = 1;
>         token_buffer[0] = 0;
> !       if (linemode)
> !       value = END_OF_LINE;
> !       else
> !       value = ENDFILE;
>         break;
>
>       case 'L':
> + #if USE_CPPLIB
> +       if (cpp_token == CPP_NAME)
> +       goto letter;
> + #endif
>         /* Capital L may start a wide-string or wide-character constant.  */
>         {
> !       register int c = token_getch();
>         if (c == '\'')
>           {
>             wide_flag = 1;
> *************** yylex ()
> *** 1311,1317 ****
>             wide_flag = 1;
>             goto string_constant;
>           }
> !       UNGETC (c);
>         }
>         goto letter;
>
> --- 1299,1305 ----
>             wide_flag = 1;
>             goto string_constant;
>           }
> !       token_put_back (c);
>         }
>         goto letter;
>
> *************** yylex ()
> *** 1324,1336 ****
>         else
>         {
>           /* '@' may start a constant string object.  */
> !         register int c = GETC ();
>           if (c == '"')
>             {
>               objc_flag = 1;
>               goto string_constant;
>             }
> !         UNGETC (c);
>           /* Fall through to treat '@' as the start of an identifier.  */
>         }
>
> --- 1312,1324 ----
>         else
>         {
>           /* '@' may start a constant string object.  */
> !         register int c = token_getch ();
>           if (c == '"')
>             {
>               objc_flag = 1;
>               goto string_constant;
>             }
> !         token_put_back (c);
>           /* Fall through to treat '@' as the start of an identifier.  */
>         }
>
> *************** yylex ()
> *** 1349,1379 ****
>       case '_':
>       case '$':
>       letter:
> !       p = token_buffer;
> !       while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
>         {
> !         /* Make sure this char really belongs in an identifier.  */
> !         if (c == '$')
>             {
> !             if (! dollars_in_ident)
> !               error ("`$' in identifier");
> !             else if (pedantic)
> !               pedwarn ("`$' in identifier");
> !           }
>
> !         if (p >= token_buffer + maxtoken)
> !           p = extend_token_buffer (p);
>
> !         *p++ = c;
> !         c = GETC();
> !       }
>
> !       *p = 0;
> ! #if USE_CPPLIB
> !       UNGETC (c);
> ! #else
> !       nextchar = c;
> ! #endif
>
>         value = IDENTIFIER;
>         yylval.itype = 0;
> --- 1337,1381 ----
>       case '_':
>       case '$':
>       letter:
> ! #if USE_CPPLIB
> !       if (cpp_token == CPP_NAME)
> !       {
> !         /* Note that one character has already been read from
> !            yy_cur into token_buffer.  Also, cpplib complains about
> !            $ in identifiers, so we don't have to.  */
> !
> !         int len = yy_lim - yy_cur + 1;
> !         if (len >= maxtoken)
> !           extend_token_buffer_to (len + 1);
> !         memcpy (token_buffer + 1, yy_cur, len);
> !         p = token_buffer + len;
> !         yy_cur = yy_lim;
> !       }
> !       else
> ! #endif
>         {
> !         p = token_buffer;
> !         while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
>             {
> !             /* Make sure this char really belongs in an identifier.  */
> !             if (c == '$')
> !               {
> !                 if (! dollars_in_ident)
> !                   error ("`$' in identifier");
> !                 else if (pedantic)
> !                   pedwarn ("`$' in identifier");
> !               }
>
> !             if (p >= token_buffer + maxtoken)
> !               p = extend_token_buffer (p);
>
> !             *p++ = c;
> !             c = token_getch();
> !           }
>
> !         *p = 0;
> !         token_put_back (c);
> !       }
>
>         value = IDENTIFIER;
>         yylval.itype = 0;
> *************** yylex ()
> *** 1453,1468 ****
>
>         break;
>
>       case '0':  case '1':
>         {
> !       int next_c;
> !       /* Check first for common special case:  single-digit 0 or 1.  */
>
> !       next_c = GETC ();
> !       UNGETC (next_c);        /* Always undo this lookahead.  */
> !       if (!ISALNUM (next_c) && next_c != '.')
>           {
> -           token_buffer[0] = (char)c,  token_buffer[1] = '\0';
>             yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;
>             value = CONSTANT;
>             break;
> --- 1455,1507 ----
>
>         break;
>
> +     case '.':
> + #if USE_CPPLIB
> +       if (yy_cur < yy_lim)
> + #endif
> +       {
> +         /* It's hard to preserve tokenization on '.' because
> +            it could be a symbol by itself, or it could be the
> +            start of a floating point number and cpp won't tell us.  */
> +         register int c1 = token_getch ();
> +         token_buffer[1] = c1;
> +         if (c1 == '.')
> +           {
> +             c1 = token_getch ();
> +             if (c1 == '.')
> +               {
> +                 token_buffer[2] = c1;
> +                 token_buffer[3] = 0;
> +                 value = ELLIPSIS;
> +                 goto done;
> +               }
> +             error ("parse error at `..'");
> +           }
> +         if (ISDIGIT (c1))
> +           {
> +             token_put_back (c1);
> +             goto number;
> +           }
> +         token_put_back (c1);
> +       }
> +       value = '.';
> +       token_buffer[1] = 0;
> +       break;
> +
>       case '0':  case '1':
> +       /* Optimize for most frequent case.  */
>         {
> !       register int cond;
>
> ! #if USE_CPPLIB
> !       cond = (yy_cur == yy_lim);
> ! #else
> !       register int c1 = token_getch ();
> !       token_put_back (c1);
> !       cond = (! ISALNUM (c1) && c1 != '.');
> ! #endif
> !       if (cond)
>           {
>             yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;
>             value = CONSTANT;
>             break;
> *************** yylex ()
> *** 1471,1477 ****
>         }
>       case '2':  case '3':  case '4':
>       case '5':  case '6':  case '7':  case '8':  case '9':
> !     case '.':
>         {
>         int base = 10;
>         int count = 0;
> --- 1510,1516 ----
>         }
>       case '2':  case '3':  case '4':
>       case '5':  case '6':  case '7':  case '8':  case '9':
> !     number:
>         {
>         int base = 10;
>         int count = 0;
> *************** yylex ()
> *** 1490,1496 ****
>   #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2)
>         unsigned int parts[TOTAL_PARTS];
>
> !       enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON}
>           floatflag = NOT_FLOAT;
>
>         for (count = 0; count < TOTAL_PARTS; count++)
> --- 1529,1535 ----
>   #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2)
>         unsigned int parts[TOTAL_PARTS];
>
> !       enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON }
>           floatflag = NOT_FLOAT;
>
>         for (count = 0; count < TOTAL_PARTS; count++)
> *************** yylex ()
> *** 1501,1511 ****
>
>         if (c == '0')
>           {
> !           *p++ = (c = GETC());
>             if ((c == 'x') || (c == 'X'))
>               {
>                 base = 16;
> !               *p++ = (c = GETC());
>               }
>             /* Leading 0 forces octal unless the 0 is the only digit.  */
>             else if (c >= '0' && c <= '9')
> --- 1540,1550 ----
>
>         if (c == '0')
>           {
> !           *p++ = (c = token_getch());
>             if ((c == 'x') || (c == 'X'))
>               {
>                 base = 16;
> !               *p++ = (c = token_getch());
>               }
>             /* Leading 0 forces octal unless the 0 is the only digit.  */
>             else if (c >= '0' && c <= '9')
> *************** yylex ()
> *** 1528,1534 ****
>             if (c == '.')
>               {
>                 if (base == 16 && pedantic)
> !                 error ("floating constant may not be in radix 16");
>                 if (floatflag == TOO_MANY_POINTS)
>                   /* We have already emitted an error.  Don't need another.  */
>                   ;
> --- 1567,1573 ----
>             if (c == '.')
>               {
>                 if (base == 16 && pedantic)
> !                 pedwarn ("floating constant may not be in radix 16");
>                 if (floatflag == TOO_MANY_POINTS)
>                   /* We have already emitted an error.  Don't need another.  */
>                   ;
> *************** yylex ()
> *** 1545,1573 ****
>
>                 if (base == 8)
>                   base = 10;
> !               *p++ = c = GETC();
>                 /* Accept '.' as the start of a floating-point number
> !                  only when it is followed by a digit.
> !                  Otherwise, unread the following non-digit
> !                  and use the '.' as a structural token.  */
>                 if (p == token_buffer + 2 && !ISDIGIT (c))
> !                 {
> !                   if (c == '.')
> !                     {
> !                       c = GETC();
> !                       if (c == '.')
> !                         {
> !                           *p++ = c;
> !                           *p = 0;
> !                           return ELLIPSIS;
> !                         }
> !                       error ("parse error at `..'");
> !                     }
> !                   UNGETC (c);
> !                   token_buffer[1] = 0;
> !                   value = '.';
> !                   goto done;
> !                 }
>               }
>             else
>               {
> --- 1584,1594 ----
>
>                 if (base == 8)
>                   base = 10;
> !               *p++ = c = token_getch();
>                 /* Accept '.' as the start of a floating-point number
> !                  only when it is followed by a digit.  */
>                 if (p == token_buffer + 2 && !ISDIGIT (c))
> !                 abort ();
>               }
>             else
>               {
> *************** yylex ()
> *** 1619,1625 ****
>                     else
>                       parts[0] += c;
>                   }
> !
>                 /* If the highest-order part overflows (gets larger than
>                    a host char will hold) then the whole number has
>                    overflowed.  Record this and truncate the highest-order
> --- 1640,1646 ----
>                     else
>                       parts[0] += c;
>                   }
> !
>                 /* If the highest-order part overflows (gets larger than
>                    a host char will hold) then the whole number has
>                    overflowed.  Record this and truncate the highest-order
> *************** yylex ()
> *** 1632,1655 ****
>
>                 if (p >= token_buffer + maxtoken - 3)
>                   p = extend_token_buffer (p);
> !               *p++ = (c = GETC());
>               }
>           }
>
>         if (numdigits == 0)
> !         error ("numeric constant with no digits");
>
>         if (largest_digit >= base)
>           error ("numeric constant contains digits beyond the radix");
>
> !       /* Remove terminating char from the token buffer and delimit the string */
>         *--p = 0;
>
>         if (floatflag != NOT_FLOAT)
>           {
> !           tree type = double_type_node;
> !           int imag = 0;
> !           int conversion_errno = 0;
>             REAL_VALUE_TYPE value;
>             struct pf_args args;
>
> --- 1653,1676 ----
>
>                 if (p >= token_buffer + maxtoken - 3)
>                   p = extend_token_buffer (p);
> !               *p++ = (c = token_getch());
>               }
>           }
>
>         if (numdigits == 0)
> !         abort ();
>
>         if (largest_digit >= base)
>           error ("numeric constant contains digits beyond the radix");
>
> !       /* Remove terminating char from the token buffer and delimit the
> !            string.  */
>         *--p = 0;
>
>         if (floatflag != NOT_FLOAT)
>           {
> !           tree type;
> !           int imag, conversion_errno;
>             REAL_VALUE_TYPE value;
>             struct pf_args args;
>
> *************** yylex ()
> *** 1661,1671 ****
>                 if (p >= token_buffer + maxtoken - 3)
>                   p = extend_token_buffer (p);
>                 *p++ = c;
> !               c = GETC();
>                 if ((c == '+') || (c == '-'))
>                   {
>                     *p++ = c;
> !                   c = GETC();
>                   }
>                 /* Exponent is decimal, even if string is a hex float.  */
>                 if (! ISDIGIT (c))
> --- 1682,1692 ----
>                 if (p >= token_buffer + maxtoken - 3)
>                   p = extend_token_buffer (p);
>                 *p++ = c;
> !               c = token_getch();
>                 if ((c == '+') || (c == '-'))
>                   {
>                     *p++ = c;
> !                   c = token_getch();
>                   }
>                 /* Exponent is decimal, even if string is a hex float.  */
>                 if (! ISDIGIT (c))
> *************** yylex ()
> *** 1675,1681 ****
>                     if (p >= token_buffer + maxtoken - 3)
>                       p = extend_token_buffer (p);
>                     *p++ = c;
> !                   c = GETC();
>                   }
>               }
>             if (base == 16 && floatflag != AFTER_EXPON)
> --- 1696,1702 ----
>                     if (p >= token_buffer + maxtoken - 3)
>                       p = extend_token_buffer (p);
>                     *p++ = c;
> !                   c = token_getch ();
>                   }
>               }
>             if (base == 16 && floatflag != AFTER_EXPON)
> *************** yylex ()
> *** 1687,1695 ****
>             args.base = base;
>             args.p = p;
>             args.c = c;
> -           args.imag = imag;
> -           args.type = type;
> -           args.conversion_errno = conversion_errno;
>
>             /* Convert string to a double, checking for overflow.  */
>             if (do_float_handler (parse_float, (PTR) &args))
> --- 1708,1713 ----
> *************** yylex ()
> *** 1777,1783 ****
>                 if (p >= token_buffer + maxtoken - 3)
>                   p = extend_token_buffer (p);
>                 *p++ = c;
> !               c = GETC();
>               }
>
>             /* If the literal overflowed, pedwarn about it now. */
> --- 1795,1801 ----
>                 if (p >= token_buffer + maxtoken - 3)
>                   p = extend_token_buffer (p);
>                 *p++ = c;
> !               c = token_getch();
>               }
>
>             /* If the literal overflowed, pedwarn about it now. */
> *************** yylex ()
> *** 1930,1936 ****
>               pedwarn ("integer constant is larger than the maximum value for its type");
>           }
>
> !       UNGETC (c);
>         *p = 0;
>
>         if (ISALNUM (c) || c == '.' || c == '_' || c == '$'
> --- 1948,1954 ----
>               pedwarn ("integer constant is larger than the maximum value for its type");
>           }
>
> !       token_put_back (c);
>         *p = 0;
>
>         if (ISALNUM (c) || c == '.' || c == '_' || c == '$'
> *************** yylex ()
> *** 1951,1957 ****
>         int max_chars;
>   #ifdef MULTIBYTE_CHARS
>         int longest_char = local_mb_cur_max ();
> !       (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
>   #endif
>
>         max_chars = TYPE_PRECISION (integer_type_node) / width;
> --- 1969,1975 ----
>         int max_chars;
>   #ifdef MULTIBYTE_CHARS
>         int longest_char = local_mb_cur_max ();
> !       local_mbtowc (NULL_PTR, NULL_PTR, 0);
>   #endif
>
>         max_chars = TYPE_PRECISION (integer_type_node) / width;
> *************** yylex ()
> *** 1961,1967 ****
>         while (1)
>           {
>           tryagain:
> !           c = GETC();
>
>             if (c == '\'' || c == EOF)
>               break;
> --- 1979,1985 ----
>         while (1)
>           {
>           tryagain:
> !           c = token_getch();
>
>             if (c == '\'' || c == EOF)
>               break;
> *************** yylex ()
> *** 2004,2016 ****
>                                              i);
>                     if (char_len != -1)
>                       break;
> !                   c = GETC ();
>                   }
>                 if (char_len > 1)
>                   {
>                     /* mbtowc sometimes needs an extra char before accepting */
>                     if (char_len < i)
> !                     UNGETC (c);
>                     if (! wide_flag)
>                       {
>                         /* Merge character into result; ignore excess chars.  */
> --- 2022,2034 ----
>                                              i);
>                     if (char_len != -1)
>                       break;
> !                   c = token_getch ();
>                   }
>                 if (char_len > 1)
>                   {
>                     /* mbtowc sometimes needs an extra char before accepting */
>                     if (char_len < i)
> !                     token_put_back (c);
>                     if (! wide_flag)
>                       {
>                         /* Merge character into result; ignore excess chars.  */
> *************** yylex ()
> *** 2037,2043 ****
>                         warning ("Ignoring invalid multibyte character");
>                         /* Replace all but the first byte.  */
>                         for (--i; i > 1; --i)
> !                         UNGETC (token_buffer[i]);
>                         wc = token_buffer[1];
>                       }
>   #ifdef MAP_CHARACTER
> --- 2055,2061 ----
>                         warning ("Ignoring invalid multibyte character");
>                         /* Replace all but the first byte.  */
>                         for (--i; i > 1; --i)
> !                         token_put_back (token_buffer[i]);
>                         wc = token_buffer[1];
>                       }
>   #ifdef MAP_CHARACTER
> *************** yylex ()
> *** 2120,2133 ****
>                                    : TYPE_PRECISION (char_type_node);
>   #ifdef MULTIBYTE_CHARS
>         int longest_char = local_mb_cur_max ();
> !       (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
>   #endif
> !       c = GETC ();
>         p = token_buffer + 1;
>
> !       while (c != '"' && c >= 0)
>           {
> !           if (c == '\\')
>               {
>                 int ignore = 0;
>                 c = readescape (&ignore);
> --- 2138,2153 ----
>                                    : TYPE_PRECISION (char_type_node);
>   #ifdef MULTIBYTE_CHARS
>         int longest_char = local_mb_cur_max ();
> !       local_mbtowc (NULL_PTR, NULL_PTR, 0);
>   #endif
> !
> !       c = token_getch ();
>         p = token_buffer + 1;
>
> !       while (c != '"' && c != EOF)
>           {
> !           /* ignore_escape_flag is set for reading the filename in #line.  */
> !           if (!ignore_escape_flag && c == '\\')
>               {
>                 int ignore = 0;
>                 c = readescape (&ignore);
> *************** yylex ()
> *** 2158,2181 ****
>                     char_len = local_mbtowc (& wc, p, i + 1);
>                     if (char_len != -1)
>                       break;
> !                   c = GETC ();
>                   }
>                 if (char_len == -1)
>                   {
>                     warning ("Ignoring invalid multibyte character");
>                     /* Replace all except the first byte.  */
> !                   UNGETC (c);
>                     for (--i; i > 0; --i)
> !                     UNGETC (p[i]);
>                     char_len = 1;
>                   }
>                 /* mbtowc sometimes needs an extra char before accepting */
>                 if (char_len <= i)
> !                 UNGETC (c);
>                 if (! wide_flag)
>                   {
>                     p += (i + 1);
> !                   c = GETC ();
>                     continue;
>                   }
>                 c = wc;
> --- 2178,2201 ----
>                     char_len = local_mbtowc (& wc, p, i + 1);
>                     if (char_len != -1)
>                       break;
> !                   c = token_getch ();
>                   }
>                 if (char_len == -1)
>                   {
>                     warning ("Ignoring invalid multibyte character");
>                     /* Replace all except the first byte.  */
> !                   token_put_back (c);
>                     for (--i; i > 0; --i)
> !                     token_put_back (p[i]);
>                     char_len = 1;
>                   }
>                 /* mbtowc sometimes needs an extra char before accepting */
>                 if (char_len <= i)
> !                 token_put_back (c);
>                 if (! wide_flag)
>                   {
>                     p += (i + 1);
> !                   c = token_getch ();
>                     continue;
>                   }
>                 c = wc;
> *************** yylex ()
> *** 2215,2221 ****
>               }
>
>           skipnewline:
> !           c = GETC ();
>           }
>
>         /* Terminate the string value, either with a single byte zero
> --- 2235,2241 ----
>               }
>
>           skipnewline:
> !           c = token_getch ();
>           }
>
>         /* Terminate the string value, either with a single byte zero
> *************** yylex ()
> *** 2234,2240 ****
>             *p++ = 0;
>           }
>
> !       if (c < 0)
>           error ("Unterminated string constant");
>
>         /* We have read the entire constant.
> --- 2254,2260 ----
>             *p++ = 0;
>           }
>
> !       if (c == EOF)
>           error ("Unterminated string constant");
>
>         /* We have read the entire constant.
> *************** yylex ()
> *** 2312,2318 ****
>             yylval.code = GT_EXPR; break;
>           }
>
> !       token_buffer[1] = c1 = GETC();
>         token_buffer[2] = 0;
>
>         if (c1 == '=')
> --- 2332,2338 ----
>             yylval.code = GT_EXPR; break;
>           }
>
> !       token_buffer[1] = c1 = token_getch();
>         token_buffer[2] = 0;
>
>         if (c1 == '=')
> *************** yylex ()
> *** 2355,2360 ****
> --- 2375,2382 ----
>               if (c1 == '>')
>                 { value = POINTSAT; goto done; }
>               break;
> +
> +             /* digraphs */
>             case ':':
>               if (c1 == '>')
>                 { value = ']'; goto done; }
> *************** yylex ()
> *** 2370,2382 ****
>                 { value = '}'; indent_level--; goto done; }
>               break;
>             }
> !       UNGETC (c1);
>         token_buffer[1] = 0;
>
>         if ((c == '<') || (c == '>'))
>           value = ARITHCOMPARE;
>         else value = c;
> !       goto done;
>         }
>
>       case 0:
> --- 2392,2405 ----
>                 { value = '}'; indent_level--; goto done; }
>               break;
>             }
> !
> !       token_put_back (c1);
>         token_buffer[1] = 0;
>
>         if ((c == '<') || (c == '>'))
>           value = ARITHCOMPARE;
>         else value = c;
> !       break;
>         }
>
>       case 0:





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]