This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C frontend cpplib integration patch
- To: Jason Merrill <jason at cygnus dot com>
- Subject: Re: C frontend cpplib integration patch
- From: Dave Brolley <brolley at cygnus dot com>
- Date: Wed, 28 Jul 1999 01:50:05 -0400
- CC: gavin at cygnus dot com, Zack Weinberg <zack at rabi dot columbia dot edu>, gcc-patches at gcc dot gnu dot org
- Organization: Cygnus Solutions Canada Ltd
- References: <199907240037.RAA08824@yorick.cygnus.com>
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: