cpphash.c (CPP_IS_MACRO_BUFFER, [...]): Delete.
* cpphash.c (CPP_IS_MACRO_BUFFER, FORWARD, PEEKC): Delete. (macro_cleanup): No need to cast pbuf->macro. (collect_expansion): Use _cpp_get_define_token. Goto done if it returns VSPACE. Remove check for trailing space after CPP_COMMENT. (_cpp_create_definition): Don't diddle flags here. Return directly on error. (unsafe_chars): Handle c1 being EOF. (push_macro_expansion): Use unsafe_chars for both accidental-paste checks. Don't push the buffer till after we're done with them. * cpplex.c (PEEKBUF, GETBUF, FORWARDBUF): New. (PEEKN, FORWARD, GETC, PEEKC): Use them. (cpp_push_buffer): Don't set new->alimit. Set new->mark appropriately. (_cpp_parse_assertion): Don't NUL terminate. (_cpp_lex_token): Fix -traditional macro handling. Don't skip hspace before calling _cpp_parse_assertion. Remove all sets of only_seen_white. Treat '\f' as hspace. Don't do anything special with '\n' here. (maybe_macroexpand): Handle T_EMPTY hash entries without pushing a buffer at all. (cpp_get_token): Handle clearing only_seen_white here. Handle incrementing the line number here. Clear potential_control_macro as well as only_seen_white, if appropriate. (cpp_get_non_space_token): Don't eat CPP_POP tokens. (_cpp_get_define_token): New function, basically like _cpp_get_directive_token was but doesn't eat horizontal space. Don't do anything with only_seen_white here. (_cpp_get_directive_token): Just call _cpp_get_define_token repeatedly till it returns non-hspace. * cpplib.c (PEEKN, FORWARD, GETC, PEEKC): Delete. (conditional_skip, skip_if_group): Return int. (DIRECTIVE_TABLE): Change origin of all conditional directives to "COND". (TRAD_DIRECT_P): New macro. (_cpp_handle_directive): Use _cpp_get_directive_token. Issue an error for a bogus directive, unless -lang-asm. Use TRAD_DIRECT_P. Loop calling handler functions till one returns zero. (get_macro_name): Don't diddle flags here. (do_define): Diddle flags here. Use _cpp_get_directive_token. Create T_EMPTY nodes for #define macro /* nothing */. (do_undef): Don't copy the name. Use _cpp_get_directive_token. Use hp->name when calling pass_thru_directive. (do_if, do_else, do_elif, do_ifdef, do_ifndef, conditional_skip): Return the result of conditional_skip and/or skip_if_group. Don't call _cpp_output_line_command. (consider_directive_while_skipping): Use _cpp_get_directive_token. Issue -Wtraditional warnings as appropriate. Don't complain about unrecognized directives. If we are to stop skipping, return the number of the directive that ended the skip. (skip_if_group): Use _cpp_get_directive_token. Turn off macro expansion and line commands while skipping. Return the result of consider_directive_while_skipping, if nonzero. (do_endif): Just set potential_control_macro here. (validate_else): Use _cpp_get_directive_token. (do_assert, do_unassert): Don't save pointers into the token_buffer across calls to the lexer. Use _cpp_get_directive_token. * cpplib.h (cpp_buffer): Remove alimit and colno. Make mark a pointer, not an offset. Replace 'data', which was a generic pointer, with 'macro', which points to a struct hashnode. (cpp_reader): Add 'potential_control_macro' pointer. * cpphash.h (T_UNUSED): Replace with T_EMPTY. (CPP_BUF_GET, CPP_FORWARD): Delete. (CPP_IN_COLUMN_1, ADJACENT_TO_MARK): New macros. (CPP_IS_MACRO_BUFFER, CPP_SET_BUF_MARK, CPP_GOTO_BUF_MARK, ACTIVE_MARK_P): Update. (_cpp_get_define_token): New internal function. * cppfiles.c (read_include_file): Don't set fp->alimit or fp->colno. From-SVN: r32965
This commit is contained in:
parent
edea368266
commit
ff2b53efb1
@ -1,3 +1,80 @@
|
||||
2000-04-06 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* cpphash.c (CPP_IS_MACRO_BUFFER, FORWARD, PEEKC): Delete.
|
||||
(macro_cleanup): No need to cast pbuf->macro.
|
||||
(collect_expansion): Use _cpp_get_define_token. Goto done if
|
||||
it returns VSPACE. Remove check for trailing space after
|
||||
CPP_COMMENT.
|
||||
(_cpp_create_definition): Don't diddle flags here. Return
|
||||
directly on error.
|
||||
(unsafe_chars): Handle c1 being EOF.
|
||||
(push_macro_expansion): Use unsafe_chars for both accidental-paste
|
||||
checks. Don't push the buffer till after we're done with
|
||||
them.
|
||||
* cpplex.c (PEEKBUF, GETBUF, FORWARDBUF): New.
|
||||
(PEEKN, FORWARD, GETC, PEEKC): Use them.
|
||||
(cpp_push_buffer): Don't set new->alimit. Set new->mark
|
||||
appropriately.
|
||||
(_cpp_parse_assertion): Don't NUL terminate.
|
||||
(_cpp_lex_token): Fix -traditional macro handling. Don't skip
|
||||
hspace before calling _cpp_parse_assertion. Remove all sets
|
||||
of only_seen_white. Treat '\f' as hspace. Don't do anything
|
||||
special with '\n' here.
|
||||
(maybe_macroexpand): Handle T_EMPTY hash entries without
|
||||
pushing a buffer at all.
|
||||
(cpp_get_token): Handle clearing only_seen_white here. Handle
|
||||
incrementing the line number here. Clear
|
||||
potential_control_macro as well as only_seen_white, if
|
||||
appropriate.
|
||||
(cpp_get_non_space_token): Don't eat CPP_POP tokens.
|
||||
(_cpp_get_define_token): New function, basically like
|
||||
_cpp_get_directive_token was but doesn't eat horizontal space.
|
||||
Don't do anything with only_seen_white here.
|
||||
(_cpp_get_directive_token): Just call _cpp_get_define_token
|
||||
repeatedly till it returns non-hspace.
|
||||
|
||||
* cpplib.c (PEEKN, FORWARD, GETC, PEEKC): Delete.
|
||||
(conditional_skip, skip_if_group): Return int.
|
||||
(DIRECTIVE_TABLE): Change origin of all conditional directives
|
||||
to "COND".
|
||||
(TRAD_DIRECT_P): New macro.
|
||||
(_cpp_handle_directive): Use _cpp_get_directive_token. Issue
|
||||
an error for a bogus directive, unless -lang-asm. Use
|
||||
TRAD_DIRECT_P. Loop calling handler functions till one returns
|
||||
zero.
|
||||
(get_macro_name): Don't diddle flags here.
|
||||
(do_define): Diddle flags here. Use _cpp_get_directive_token.
|
||||
Create T_EMPTY nodes for #define macro /* nothing */.
|
||||
(do_undef): Don't copy the name. Use _cpp_get_directive_token.
|
||||
Use hp->name when calling pass_thru_directive.
|
||||
(do_if, do_else, do_elif, do_ifdef, do_ifndef, conditional_skip):
|
||||
Return the result of conditional_skip and/or skip_if_group.
|
||||
Don't call _cpp_output_line_command.
|
||||
(consider_directive_while_skipping): Use _cpp_get_directive_token.
|
||||
Issue -Wtraditional warnings as appropriate. Don't complain
|
||||
about unrecognized directives. If we are to stop skipping,
|
||||
return the number of the directive that ended the skip.
|
||||
(skip_if_group): Use _cpp_get_directive_token. Turn off macro
|
||||
expansion and line commands while skipping. Return the result
|
||||
of consider_directive_while_skipping, if nonzero.
|
||||
(do_endif): Just set potential_control_macro here.
|
||||
(validate_else): Use _cpp_get_directive_token.
|
||||
(do_assert, do_unassert): Don't save pointers into the
|
||||
token_buffer across calls to the lexer. Use
|
||||
_cpp_get_directive_token.
|
||||
|
||||
* cpplib.h (cpp_buffer): Remove alimit and colno. Make mark a
|
||||
pointer, not an offset. Replace 'data', which was a generic
|
||||
pointer, with 'macro', which points to a struct hashnode.
|
||||
(cpp_reader): Add 'potential_control_macro' pointer.
|
||||
* cpphash.h (T_UNUSED): Replace with T_EMPTY.
|
||||
(CPP_BUF_GET, CPP_FORWARD): Delete.
|
||||
(CPP_IN_COLUMN_1, ADJACENT_TO_MARK): New macros.
|
||||
(CPP_IS_MACRO_BUFFER, CPP_SET_BUF_MARK, CPP_GOTO_BUF_MARK,
|
||||
ACTIVE_MARK_P): Update.
|
||||
(_cpp_get_define_token): New internal function.
|
||||
* cppfiles.c (read_include_file): Don't set fp->alimit or fp->colno.
|
||||
|
||||
2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
|
||||
|
||||
* configure.in: And here.
|
||||
|
@ -742,12 +742,11 @@ read_include_file (pfile, fd, ihash)
|
||||
ihash->control_macro = (const U_CHAR *) ""; /* never re-include */
|
||||
|
||||
close (fd);
|
||||
fp->rlimit = fp->alimit = fp->buf + length;
|
||||
fp->rlimit = fp->buf + length;
|
||||
fp->cur = fp->buf;
|
||||
if (ihash->foundhere != ABSOLUTE_PATH)
|
||||
fp->system_header_p = ihash->foundhere->sysp;
|
||||
fp->lineno = 1;
|
||||
fp->colno = 1;
|
||||
fp->line_base = fp->buf;
|
||||
fp->cleanup = file_cleanup;
|
||||
|
||||
|
113
gcc/cpphash.c
113
gcc/cpphash.c
@ -45,10 +45,6 @@ static enum cpp_token macarg PARAMS ((cpp_reader *, int));
|
||||
static struct tm *timestamp PARAMS ((cpp_reader *));
|
||||
static void special_symbol PARAMS ((HASHNODE *, cpp_reader *));
|
||||
|
||||
#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
|
||||
#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
|
||||
#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
|
||||
|
||||
/* Initial hash table size. (It can grow if necessary - see hashtab.c.) */
|
||||
#define HASHSIZE 500
|
||||
|
||||
@ -266,7 +262,7 @@ macro_cleanup (pbuf, pfile)
|
||||
cpp_buffer *pbuf;
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
{
|
||||
HASHNODE *macro = (HASHNODE *) pbuf->data;
|
||||
HASHNODE *macro = pbuf->macro;
|
||||
if (macro->type == T_DISABLED)
|
||||
macro->type = T_MACRO;
|
||||
if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
|
||||
@ -314,26 +310,18 @@ collect_expansion (pfile, arglist)
|
||||
last -= 2; /* two extra chars for the leading escape */
|
||||
for (;;)
|
||||
{
|
||||
/* We use cpp_get_token because _cpp_get_directive_token would
|
||||
discard whitespace and we can't cope with that yet. Macro
|
||||
expansion is off, so we are guaranteed not to see POP or EOF. */
|
||||
|
||||
while (PEEKC () == '\r')
|
||||
{
|
||||
FORWARD (1);
|
||||
CPP_BUMP_LINE (pfile);
|
||||
}
|
||||
if (PEEKC () == '\n')
|
||||
goto done;
|
||||
/* Macro expansion is off, so we are guaranteed not to see POP
|
||||
or EOF. */
|
||||
here = CPP_WRITTEN (pfile);
|
||||
token = cpp_get_token (pfile);
|
||||
token = _cpp_get_define_token (pfile);
|
||||
tok = pfile->token_buffer + here;
|
||||
switch (token)
|
||||
{
|
||||
case CPP_POP:
|
||||
case CPP_EOF:
|
||||
cpp_ice (pfile, "EOF in collect_expansion");
|
||||
/* fall through */
|
||||
case CPP_VSPACE:
|
||||
cpp_ice (pfile, "EOF or VSPACE in collect_expansion");
|
||||
goto done;
|
||||
|
||||
case CPP_HSPACE:
|
||||
@ -386,16 +374,14 @@ collect_expansion (pfile, arglist)
|
||||
case CPP_COMMENT:
|
||||
/* We must be in -traditional mode. Pretend this was a
|
||||
token paste, but only if there was no leading or
|
||||
trailing space and it's in the middle of the line. */
|
||||
trailing space and it's in the middle of the line.
|
||||
_cpp_lex_token won't return a COMMENT if there was trailing
|
||||
space. */
|
||||
CPP_SET_WRITTEN (pfile, here);
|
||||
if (last_token == START)
|
||||
break;
|
||||
if (is_hspace (pfile->token_buffer[here-1]))
|
||||
break;
|
||||
if (is_hspace (PEEKC ()))
|
||||
break;
|
||||
if (PEEKC () == '\n')
|
||||
break;
|
||||
if (last_token == ARG)
|
||||
endpat->raw_after = 1;
|
||||
last_token = PASTE;
|
||||
@ -738,38 +724,21 @@ _cpp_create_definition (pfile, funlike)
|
||||
cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
|
||||
file = CPP_BUFFER (pfile)->nominal_fname;
|
||||
|
||||
pfile->no_macro_expand++;
|
||||
pfile->parsing_define_directive++;
|
||||
CPP_OPTION (pfile, discard_comments)++;
|
||||
CPP_OPTION (pfile, no_line_commands)++;
|
||||
|
||||
if (funlike)
|
||||
{
|
||||
args = collect_formal_parameters (pfile);
|
||||
if (args == 0)
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
defn = collect_expansion (pfile, args);
|
||||
if (defn == 0)
|
||||
goto err;
|
||||
return 0;
|
||||
|
||||
defn->line = line;
|
||||
defn->file = file;
|
||||
defn->col = col;
|
||||
|
||||
pfile->no_macro_expand--;
|
||||
pfile->parsing_define_directive--;
|
||||
CPP_OPTION (pfile, discard_comments)--;
|
||||
CPP_OPTION (pfile, no_line_commands)--;
|
||||
return defn;
|
||||
|
||||
err:
|
||||
pfile->no_macro_expand--;
|
||||
pfile->parsing_define_directive--;
|
||||
CPP_OPTION (pfile, discard_comments)--;
|
||||
CPP_OPTION (pfile, no_line_commands)--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1446,6 +1415,18 @@ unsafe_chars (pfile, c1, c2)
|
||||
{
|
||||
switch (c1)
|
||||
{
|
||||
case EOF:
|
||||
/* We don't know what the previous character was. We do know
|
||||
that it can't have been an idchar (or else it would have been
|
||||
pasted with the idchars of the macro name), and there are a
|
||||
number of second characters for which it doesn't matter what
|
||||
the first was. */
|
||||
if (is_idchar (c2) || c2 == '\'' || c2 == '\"'
|
||||
|| c2 == '(' || c2 == '[' || c2 == '{'
|
||||
|| c2 == ')' || c2 == ']' || c2 == '}')
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case '+': case '-':
|
||||
if (c2 == c1 || c2 == '=')
|
||||
return 1;
|
||||
@ -1488,17 +1469,14 @@ unsafe_chars (pfile, c1, c2)
|
||||
}
|
||||
|
||||
static void
|
||||
push_macro_expansion (pfile, xbuf, xbuf_len, hp)
|
||||
push_macro_expansion (pfile, xbuf, len, hp)
|
||||
cpp_reader *pfile;
|
||||
register U_CHAR *xbuf;
|
||||
int xbuf_len;
|
||||
int len;
|
||||
HASHNODE *hp;
|
||||
{
|
||||
register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len);
|
||||
if (mbuf == NULL)
|
||||
return;
|
||||
mbuf->cleanup = macro_cleanup;
|
||||
mbuf->data = hp;
|
||||
cpp_buffer *mbuf;
|
||||
int advance_cur = 0;
|
||||
|
||||
/* The first chars of the expansion should be a "\r " added by
|
||||
collect_expansion. This is to prevent accidental token-pasting
|
||||
@ -1507,34 +1485,31 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp)
|
||||
|
||||
We would like to avoid adding unneeded spaces (for the sake of
|
||||
tools that use cpp, such as imake). In some common cases we can
|
||||
tell that it is safe to omit the space.
|
||||
|
||||
The character before the macro invocation cannot have been an
|
||||
idchar (or else it would have been pasted with the idchars of
|
||||
the macro name). Therefore, if the first non-space character
|
||||
of the expansion is an idchar, we do not need the extra space
|
||||
to prevent token pasting.
|
||||
|
||||
Also, we don't need the extra space if the first char is '(',
|
||||
or some other (less common) characters. */
|
||||
tell that it is safe to omit the space. */
|
||||
|
||||
if (xbuf[0] == '\r' && xbuf[1] == ' '
|
||||
&& (is_idchar(xbuf[2]) || xbuf[2] == '(' || xbuf[2] == '\''
|
||||
|| xbuf[2] == '\"'))
|
||||
mbuf->cur += 2;
|
||||
&& !unsafe_chars (pfile, EOF, xbuf[2]))
|
||||
advance_cur = 1;
|
||||
|
||||
/* Likewise, avoid the extra space at the end of the macro expansion
|
||||
if this is safe. We can do a better job here since we can know
|
||||
what the next char will be. */
|
||||
if (xbuf_len >= 3
|
||||
&& mbuf->rlimit[-2] == '\r'
|
||||
&& mbuf->rlimit[-1] == ' ')
|
||||
if (len >= 3
|
||||
&& xbuf[len-2] == '\r'
|
||||
&& xbuf[len-1] == ' ')
|
||||
{
|
||||
int c1 = mbuf->rlimit[-3];
|
||||
int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile)));
|
||||
if (c2 == EOF || !unsafe_chars (pfile, c1, c2))
|
||||
mbuf->rlimit -= 2;
|
||||
int c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
|
||||
if (c == EOF || !unsafe_chars (pfile, xbuf[len-3], c))
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
mbuf = cpp_push_buffer (pfile, xbuf, len);
|
||||
if (mbuf == NULL)
|
||||
return;
|
||||
if (advance_cur)
|
||||
mbuf->cur += 2;
|
||||
mbuf->cleanup = macro_cleanup;
|
||||
mbuf->macro = hp;
|
||||
}
|
||||
|
||||
/* Return zero if two DEFINITIONs are isomorphic. */
|
||||
|
@ -98,7 +98,7 @@ enum node_type
|
||||
T_MACRO, /* macro defined by `#define' */
|
||||
T_DISABLED, /* macro temporarily turned off for rescan */
|
||||
T_POISON, /* macro defined with `#pragma poison' */
|
||||
T_UNUSED /* Used for something not defined. */
|
||||
T_EMPTY /* macro defined to nothing */
|
||||
};
|
||||
|
||||
/* different kinds of things that can appear in the value field
|
||||
@ -192,11 +192,11 @@ extern unsigned char _cpp_IStable[256];
|
||||
|
||||
/* Macros. */
|
||||
|
||||
/* One character lookahead in the input buffer. Note that if this
|
||||
returns EOF, it does *not* necessarily mean the file's end has been
|
||||
reached. */
|
||||
#define CPP_BUF_PEEK(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
|
||||
#define CPP_BUF_GET(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
|
||||
#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N))
|
||||
|
||||
/* Make sure PFILE->token_buffer has space for at least N more characters. */
|
||||
#define CPP_RESERVE(PFILE, N) \
|
||||
@ -223,6 +223,11 @@ extern unsigned char _cpp_IStable[256];
|
||||
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
|
||||
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
|
||||
|
||||
/* Are we in column 1 right now? Used mainly for -traditional handling
|
||||
of directives. */
|
||||
#define CPP_IN_COLUMN_1(PFILE) \
|
||||
(CPP_BUFFER (PFILE)->cur - CPP_BUFFER (PFILE)->line_base == 1)
|
||||
|
||||
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
|
||||
#define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional)
|
||||
#define CPP_PEDANTIC(PFILE) \
|
||||
@ -232,7 +237,7 @@ extern unsigned char _cpp_IStable[256];
|
||||
|
||||
/* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion.
|
||||
(Note that it is false while we're expanding macro *arguments*.) */
|
||||
#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
|
||||
#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->macro != NULL)
|
||||
|
||||
/* Remember the current position of PFILE so it may be returned to
|
||||
after looking ahead a bit.
|
||||
@ -241,14 +246,18 @@ extern unsigned char _cpp_IStable[256];
|
||||
may not forget about it and continue parsing. You may not pop a
|
||||
buffer with an active mark. You may not call CPP_BUMP_LINE while a
|
||||
mark is active. */
|
||||
#define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur - (IP)->buf)
|
||||
#define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->buf + (IP)->mark, \
|
||||
(IP)->mark = -1)
|
||||
#define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur)
|
||||
#define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->mark, (IP)->mark = 0)
|
||||
#define CPP_SET_MARK(PFILE) CPP_SET_BUF_MARK(CPP_BUFFER(PFILE))
|
||||
#define CPP_GOTO_MARK(PFILE) CPP_GOTO_BUF_MARK(CPP_BUFFER(PFILE))
|
||||
|
||||
/* ACTIVE_MARK_P is true if there's a live mark in the buffer. */
|
||||
#define ACTIVE_MARK_P(PFILE) (CPP_BUFFER (PFILE)->mark != -1)
|
||||
#define ACTIVE_MARK_P(PFILE) (CPP_BUFFER (PFILE)->mark != 0)
|
||||
|
||||
/* Are mark and point adjacent characters? Used mostly to deal with
|
||||
the somewhat annoying semantic of #define. */
|
||||
#define ADJACENT_TO_MARK(PFILE) \
|
||||
(CPP_BUFFER(PFILE)->cur - CPP_BUFFER(PFILE)->mark == 1)
|
||||
|
||||
/* Last arg to output_line_command. */
|
||||
enum file_change_code {same_file, rename_file, enter_file, leave_file};
|
||||
@ -296,6 +305,8 @@ extern void _cpp_init_input_buffer PARAMS ((cpp_reader *));
|
||||
extern void _cpp_grow_token_buffer PARAMS ((cpp_reader *, long));
|
||||
extern enum cpp_token _cpp_get_directive_token
|
||||
PARAMS ((cpp_reader *));
|
||||
extern enum cpp_token _cpp_get_define_token
|
||||
PARAMS ((cpp_reader *));
|
||||
|
||||
/* In cpplib.c */
|
||||
extern int _cpp_handle_directive PARAMS ((cpp_reader *));
|
||||
|
197
gcc/cpplex.c
197
gcc/cpplex.c
@ -25,11 +25,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "cpplib.h"
|
||||
#include "cpphash.h"
|
||||
|
||||
#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \
|
||||
? CPP_BUFFER (pfile)->cur[N] : EOF)
|
||||
#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
|
||||
#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile))
|
||||
#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
|
||||
#define PEEKBUF(BUFFER, N) \
|
||||
((BUFFER)->rlimit - (BUFFER)->cur > (N) ? (BUFFER)->cur[N] : EOF)
|
||||
#define GETBUF(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
|
||||
#define FORWARDBUF(BUFFER, N) ((BUFFER)->cur += (N))
|
||||
|
||||
#define PEEKN(N) PEEKBUF (CPP_BUFFER (pfile), N)
|
||||
#define FORWARD(N) FORWARDBUF (CPP_BUFFER (pfile), (N))
|
||||
#define GETC() GETBUF (CPP_BUFFER (pfile))
|
||||
#define PEEKC() PEEKBUF (CPP_BUFFER (pfile), 0)
|
||||
|
||||
static void skip_block_comment PARAMS ((cpp_reader *));
|
||||
static void skip_line_comment PARAMS ((cpp_reader *));
|
||||
@ -87,9 +92,9 @@ cpp_push_buffer (pfile, buffer, length)
|
||||
new->if_stack = pfile->if_stack;
|
||||
new->cleanup = null_cleanup;
|
||||
new->buf = new->cur = buffer;
|
||||
new->alimit = new->rlimit = buffer + length;
|
||||
new->rlimit = buffer + length;
|
||||
new->prev = buf;
|
||||
new->mark = -1;
|
||||
new->mark = NULL;
|
||||
new->line_base = NULL;
|
||||
|
||||
CPP_BUFFER (pfile) = new;
|
||||
@ -667,7 +672,6 @@ _cpp_parse_assertion (pfile)
|
||||
else
|
||||
CPP_PUTC (pfile, ')');
|
||||
|
||||
CPP_NUL_TERMINATE (pfile);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -702,8 +706,16 @@ _cpp_lex_token (pfile)
|
||||
|
||||
/* Comments are equivalent to spaces.
|
||||
For -traditional, a comment is equivalent to nothing. */
|
||||
if (CPP_TRADITIONAL (pfile) || !CPP_OPTION (pfile, discard_comments))
|
||||
if (!CPP_OPTION (pfile, discard_comments))
|
||||
return CPP_COMMENT;
|
||||
else if (CPP_TRADITIONAL (pfile)
|
||||
&& ! is_space (PEEKC ()))
|
||||
{
|
||||
if (pfile->parsing_define_directive)
|
||||
return CPP_COMMENT;
|
||||
else
|
||||
goto get_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPP_PUTC (pfile, c);
|
||||
@ -713,7 +725,6 @@ _cpp_lex_token (pfile)
|
||||
case '#':
|
||||
if (pfile->parsing_if_directive)
|
||||
{
|
||||
_cpp_skip_hspace (pfile);
|
||||
if (_cpp_parse_assertion (pfile))
|
||||
return CPP_ASSERTION;
|
||||
goto randomchar;
|
||||
@ -740,7 +751,6 @@ _cpp_lex_token (pfile)
|
||||
case '\"':
|
||||
case '\'':
|
||||
parse_string (pfile, c);
|
||||
pfile->only_seen_white = 0;
|
||||
return c == '\'' ? CPP_CHAR : CPP_STRING;
|
||||
|
||||
case '$':
|
||||
@ -787,7 +797,6 @@ _cpp_lex_token (pfile)
|
||||
{
|
||||
/* In C++, there's a ->* operator. */
|
||||
token = CPP_OTHER;
|
||||
pfile->only_seen_white = 0;
|
||||
CPP_RESERVE (pfile, 4);
|
||||
CPP_PUTC_Q (pfile, c);
|
||||
CPP_PUTC_Q (pfile, GETC ());
|
||||
@ -851,7 +860,6 @@ _cpp_lex_token (pfile)
|
||||
if (c3 == '=')
|
||||
CPP_PUTC_Q (pfile, GETC ());
|
||||
CPP_NUL_TERMINATE_Q (pfile);
|
||||
pfile->only_seen_white = 0;
|
||||
return CPP_OTHER;
|
||||
|
||||
case '.':
|
||||
@ -876,14 +884,12 @@ _cpp_lex_token (pfile)
|
||||
CPP_PUTC_Q (pfile, '.');
|
||||
FORWARD (2);
|
||||
CPP_NUL_TERMINATE_Q (pfile);
|
||||
pfile->only_seen_white = 0;
|
||||
return CPP_3DOTS;
|
||||
}
|
||||
goto randomchar;
|
||||
|
||||
op2:
|
||||
token = CPP_OTHER;
|
||||
pfile->only_seen_white = 0;
|
||||
CPP_RESERVE(pfile, 3);
|
||||
CPP_PUTC_Q (pfile, c);
|
||||
CPP_PUTC_Q (pfile, GETC ());
|
||||
@ -897,7 +903,6 @@ _cpp_lex_token (pfile)
|
||||
CPP_PUTC (pfile, c);
|
||||
c = GETC ();
|
||||
parse_string (pfile, c);
|
||||
pfile->only_seen_white = 0;
|
||||
return c == '\'' ? CPP_WCHAR : CPP_WSTRING;
|
||||
}
|
||||
goto letter;
|
||||
@ -923,13 +928,11 @@ _cpp_lex_token (pfile)
|
||||
c2= c;
|
||||
}
|
||||
CPP_NUL_TERMINATE_Q (pfile);
|
||||
pfile->only_seen_white = 0;
|
||||
return CPP_NUMBER;
|
||||
case 'b': case 'c': case 'd': case 'h': case 'o':
|
||||
case 'B': case 'C': case 'D': case 'H': case 'O':
|
||||
if (CPP_OPTION (pfile, chill) && PEEKC () == '\'')
|
||||
{
|
||||
pfile->only_seen_white = 0;
|
||||
CPP_RESERVE (pfile, 2);
|
||||
CPP_PUTC_Q (pfile, c);
|
||||
CPP_PUTC_Q (pfile, '\'');
|
||||
@ -970,11 +973,10 @@ _cpp_lex_token (pfile)
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
letter:
|
||||
pfile->only_seen_white = 0;
|
||||
_cpp_parse_name (pfile, c);
|
||||
return CPP_MACRO;
|
||||
|
||||
case ' ': case '\t': case '\v':
|
||||
case ' ': case '\t': case '\v': case '\f':
|
||||
for (;;)
|
||||
{
|
||||
CPP_PUTC (pfile, c);
|
||||
@ -998,6 +1000,8 @@ _cpp_lex_token (pfile)
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
/* "\r " means a space, but only if necessary to prevent
|
||||
accidental token concatenation. */
|
||||
CPP_RESERVE (pfile, 2);
|
||||
if (pfile->output_escapes)
|
||||
CPP_PUTC_Q (pfile, '\r');
|
||||
@ -1019,15 +1023,6 @@ _cpp_lex_token (pfile)
|
||||
|
||||
case '\n':
|
||||
CPP_PUTC (pfile, c);
|
||||
if (pfile->only_seen_white == 0)
|
||||
pfile->only_seen_white = 1;
|
||||
CPP_BUMP_LINE (pfile);
|
||||
if (! CPP_OPTION (pfile, no_line_commands))
|
||||
{
|
||||
pfile->lineno++;
|
||||
if (CPP_BUFFER (pfile)->lineno != pfile->lineno)
|
||||
_cpp_output_line_command (pfile, same_file);
|
||||
}
|
||||
return CPP_VSPACE;
|
||||
|
||||
case '(': token = CPP_LPAREN; goto char1;
|
||||
@ -1041,7 +1036,6 @@ _cpp_lex_token (pfile)
|
||||
default:
|
||||
token = CPP_OTHER;
|
||||
char1:
|
||||
pfile->only_seen_white = 0;
|
||||
CPP_PUTC (pfile, c);
|
||||
return token;
|
||||
}
|
||||
@ -1075,6 +1069,13 @@ maybe_macroexpand (pfile, written)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (hp->type == T_EMPTY)
|
||||
{
|
||||
/* Special case optimization: macro expands to nothing. */
|
||||
CPP_SET_WRITTEN (pfile, written);
|
||||
CPP_PUTC_Q (pfile, ' ');
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If macro wants an arglist, verify that a '(' follows. */
|
||||
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
|
||||
@ -1146,9 +1147,28 @@ cpp_get_token (pfile)
|
||||
switch (token)
|
||||
{
|
||||
default:
|
||||
pfile->potential_control_macro = 0;
|
||||
pfile->only_seen_white = 0;
|
||||
return token;
|
||||
|
||||
case CPP_VSPACE:
|
||||
if (pfile->only_seen_white == 0)
|
||||
pfile->only_seen_white = 1;
|
||||
CPP_BUMP_LINE (pfile);
|
||||
if (! CPP_OPTION (pfile, no_line_commands))
|
||||
{
|
||||
pfile->lineno++;
|
||||
if (CPP_BUFFER (pfile)->lineno != pfile->lineno)
|
||||
_cpp_output_line_command (pfile, same_file);
|
||||
}
|
||||
return token;
|
||||
|
||||
case CPP_HSPACE:
|
||||
case CPP_COMMENT:
|
||||
return token;
|
||||
|
||||
case CPP_DIRECTIVE:
|
||||
pfile->potential_control_macro = 0;
|
||||
if (_cpp_handle_directive (pfile))
|
||||
return CPP_DIRECTIVE;
|
||||
pfile->only_seen_white = 0;
|
||||
@ -1156,6 +1176,8 @@ cpp_get_token (pfile)
|
||||
return CPP_OTHER;
|
||||
|
||||
case CPP_MACRO:
|
||||
pfile->potential_control_macro = 0;
|
||||
pfile->only_seen_white = 0;
|
||||
if (! pfile->no_macro_expand
|
||||
&& maybe_macroexpand (pfile, written))
|
||||
goto get_next;
|
||||
@ -1192,57 +1214,96 @@ cpp_get_non_space_token (pfile)
|
||||
for (;;)
|
||||
{
|
||||
enum cpp_token token = cpp_get_token (pfile);
|
||||
if (token != CPP_COMMENT && token != CPP_POP
|
||||
&& token != CPP_HSPACE && token != CPP_VSPACE)
|
||||
if (token != CPP_COMMENT && token != CPP_HSPACE && token != CPP_VSPACE)
|
||||
return token;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
}
|
||||
}
|
||||
|
||||
/* Like cpp_get_token, except that it does not read past end-of-line.
|
||||
Also, horizontal space is skipped, and macros are popped. */
|
||||
/* Like cpp_get_token, except that it does not execute directives,
|
||||
does not consume vertical space, and automatically pops off macro
|
||||
buffers.
|
||||
|
||||
XXX This function will exist only till collect_expansion doesn't
|
||||
need to see whitespace anymore, then it'll be merged with
|
||||
_cpp_get_directive_token (below). */
|
||||
enum cpp_token
|
||||
_cpp_get_define_token (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
long old_written;
|
||||
enum cpp_token token;
|
||||
|
||||
get_next:
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
token = _cpp_lex_token (pfile);
|
||||
switch (token)
|
||||
{
|
||||
default:
|
||||
return token;
|
||||
|
||||
case CPP_VSPACE:
|
||||
/* Put it back and return VSPACE. */
|
||||
FORWARD(-1);
|
||||
CPP_ADJUST_WRITTEN (pfile, -1);
|
||||
return CPP_VSPACE;
|
||||
|
||||
case CPP_HSPACE:
|
||||
if (CPP_PEDANTIC (pfile))
|
||||
{
|
||||
U_CHAR *p, *limit;
|
||||
p = pfile->token_buffer + old_written;
|
||||
limit = CPP_PWRITTEN (pfile);
|
||||
while (p < limit)
|
||||
{
|
||||
if (*p == '\v' || *p == '\f')
|
||||
cpp_pedwarn (pfile, "%s in preprocessing directive",
|
||||
*p == '\f' ? "formfeed" : "vertical tab");
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return CPP_HSPACE;
|
||||
|
||||
case CPP_DIRECTIVE:
|
||||
/* Don't execute the directive, but don't smash it to OTHER either. */
|
||||
CPP_PUTC (pfile, '#');
|
||||
return CPP_DIRECTIVE;
|
||||
|
||||
case CPP_MACRO:
|
||||
if (! pfile->no_macro_expand
|
||||
&& maybe_macroexpand (pfile, old_written))
|
||||
goto get_next;
|
||||
return CPP_NAME;
|
||||
|
||||
case CPP_EOF:
|
||||
if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
|
||||
{
|
||||
cpp_pop_buffer (pfile);
|
||||
goto get_next;
|
||||
}
|
||||
else
|
||||
/* This can happen for files that don't end with a newline,
|
||||
and for cpp_define and friends. Pretend they do, so
|
||||
callers don't have to deal. A warning will be issued by
|
||||
someone else, if necessary. */
|
||||
return CPP_VSPACE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just like _cpp_get_define_token except that it discards horizontal
|
||||
whitespace. */
|
||||
|
||||
enum cpp_token
|
||||
_cpp_get_directive_token (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
enum cpp_token token;
|
||||
|
||||
int old_written = CPP_WRITTEN (pfile);
|
||||
for (;;)
|
||||
{
|
||||
_cpp_skip_hspace (pfile);
|
||||
if (PEEKC () == '\n')
|
||||
return CPP_VSPACE;
|
||||
|
||||
token = cpp_get_token (pfile);
|
||||
/* token could be hspace at the beginning of a macro. */
|
||||
if (token == CPP_HSPACE || token == CPP_COMMENT)
|
||||
{
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* token cannot be vspace, it would have been caught above. */
|
||||
if (token == CPP_VSPACE)
|
||||
{
|
||||
cpp_ice (pfile, "VSPACE in get_directive_token");
|
||||
return token;
|
||||
}
|
||||
|
||||
/* token cannot be POP unless the buffer is a macro buffer. */
|
||||
if (token != CPP_POP)
|
||||
enum cpp_token token = _cpp_get_define_token (pfile);
|
||||
if (token != CPP_COMMENT && token != CPP_HSPACE)
|
||||
return token;
|
||||
|
||||
if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
|
||||
{
|
||||
cpp_ice (pfile, "POP of file buffer in get_directive_token");
|
||||
return token;
|
||||
}
|
||||
|
||||
/* We must pop the buffer by hand, or else cpp_get_token might
|
||||
hand us white space or newline on the next invocation. */
|
||||
cpp_pop_buffer (pfile);
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
}
|
||||
}
|
||||
|
||||
|
575
gcc/cpplib.c
575
gcc/cpplib.c
@ -28,12 +28,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "intl.h"
|
||||
#include "symcat.h"
|
||||
|
||||
#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \
|
||||
? CPP_BUFFER (pfile)->cur[N] : EOF)
|
||||
#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
|
||||
#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile))
|
||||
#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
|
||||
|
||||
/* `struct directive' defines one #-directive, including how to handle it. */
|
||||
|
||||
struct directive
|
||||
@ -63,9 +57,9 @@ typedef struct if_stack IF_STACK;
|
||||
static void validate_else PARAMS ((cpp_reader *, const char *));
|
||||
static int parse_ifdef PARAMS ((cpp_reader *, const char *));
|
||||
static unsigned int parse_include PARAMS ((cpp_reader *, const char *));
|
||||
static void conditional_skip PARAMS ((cpp_reader *, int, int,
|
||||
static int conditional_skip PARAMS ((cpp_reader *, int, int,
|
||||
U_CHAR *));
|
||||
static void skip_if_group PARAMS ((cpp_reader *));
|
||||
static int skip_if_group PARAMS ((cpp_reader *));
|
||||
static void pass_thru_directive PARAMS ((const U_CHAR *, size_t,
|
||||
cpp_reader *, int));
|
||||
static int read_line_number PARAMS ((cpp_reader *, int *));
|
||||
@ -74,8 +68,14 @@ static int consider_directive_while_skipping
|
||||
PARAMS ((cpp_reader *, IF_STACK *));
|
||||
static int get_macro_name PARAMS ((cpp_reader *));
|
||||
|
||||
/* Values for the "origin" field of the table below. */
|
||||
enum { KANDR = 0, STDC89, EXTENSION };
|
||||
/* Values for the "origin" field of the table below. KANDR and COND
|
||||
directives come from traditional (K&R) C. The difference is, if we
|
||||
care about it while skipping a failed conditional block, its origin
|
||||
is COND. STDC89 directives come from the 1989 C standard.
|
||||
EXTENSION directives are extensions, with origins noted below. */
|
||||
enum { KANDR = 0, COND, STDC89, EXTENSION };
|
||||
|
||||
#define TRAD_DIRECT_P(x) ((x) == KANDR || (x) == COND)
|
||||
|
||||
/* This is the table of directive handlers. It is ordered by
|
||||
frequency of occurrence; the numbers at the end are directive
|
||||
@ -95,16 +95,16 @@ enum { KANDR = 0, STDC89, EXTENSION };
|
||||
#endif
|
||||
|
||||
#define DIRECTIVE_TABLE \
|
||||
D(define, T_DEFINE, KANDR) /* 270554 */ \
|
||||
D(define, T_DEFINE = 0, KANDR) /* 270554 */ \
|
||||
D(include, T_INCLUDE, KANDR) /* 52262 */ \
|
||||
D(endif, T_ENDIF, KANDR) /* 45855 */ \
|
||||
D(ifdef, T_IFDEF, KANDR) /* 22000 */ \
|
||||
D(if, T_IF, KANDR) /* 18162 */ \
|
||||
D(else, T_ELSE, KANDR) /* 9863 */ \
|
||||
D(ifndef, T_IFNDEF, KANDR) /* 9675 */ \
|
||||
D(endif, T_ENDIF, COND) /* 45855 */ \
|
||||
D(ifdef, T_IFDEF, COND) /* 22000 */ \
|
||||
D(if, T_IF, COND) /* 18162 */ \
|
||||
D(else, T_ELSE, COND) /* 9863 */ \
|
||||
D(ifndef, T_IFNDEF, COND) /* 9675 */ \
|
||||
D(undef, T_UNDEF, KANDR) /* 4837 */ \
|
||||
D(line, T_LINE, KANDR) /* 2465 */ \
|
||||
D(elif, T_ELIF, KANDR) /* 610 */ \
|
||||
D(elif, T_ELIF, COND) /* 610 */ \
|
||||
D(error, T_ERROR, STDC89) /* 475 */ \
|
||||
D(pragma, T_PRAGMA, STDC89) /* 195 */ \
|
||||
D(warning, T_WARNING, EXTENSION) /* 22 - GNU */ \
|
||||
@ -152,11 +152,12 @@ int
|
||||
_cpp_handle_directive (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int c, i;
|
||||
int i;
|
||||
int hash_at_bol;
|
||||
unsigned int len;
|
||||
U_CHAR *ident;
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
enum cpp_token tok;
|
||||
|
||||
if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
|
||||
{
|
||||
@ -164,18 +165,25 @@ _cpp_handle_directive (pfile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -traditional directives are recognized only with the # in column 1.
|
||||
XXX Layering violation. */
|
||||
hash_at_bol = (CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base == 1);
|
||||
/* -traditional directives are recognized only with the # in column 1. */
|
||||
hash_at_bol = CPP_IN_COLUMN_1 (pfile);
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
/* Scan the next token, then pretend we didn't. */
|
||||
CPP_SET_MARK (pfile);
|
||||
pfile->no_macro_expand++;
|
||||
tok = _cpp_get_directive_token (pfile);
|
||||
pfile->no_macro_expand--;
|
||||
|
||||
ident = pfile->token_buffer + old_written;
|
||||
len = CPP_PWRITTEN (pfile) - ident;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
CPP_GOTO_MARK (pfile);
|
||||
|
||||
c = PEEKC ();
|
||||
/* # followed by a number is equivalent to #line. Do not recognize
|
||||
this form in assembly language source files. Complain about this
|
||||
form if we're being pedantic, but not if this is regurgitated
|
||||
input (preprocessed or fed back in by the C++ frontend). */
|
||||
if (c >= '0' && c <= '9')
|
||||
if (tok == CPP_NUMBER)
|
||||
{
|
||||
if (CPP_OPTION (pfile, lang_asm))
|
||||
return 0;
|
||||
@ -190,62 +198,86 @@ _cpp_handle_directive (pfile)
|
||||
|
||||
/* If we are rescanning preprocessed input, don't obey any directives
|
||||
other than # nnn. */
|
||||
if (CPP_OPTION (pfile, preprocessed))
|
||||
else if (CPP_OPTION (pfile, preprocessed))
|
||||
return 0;
|
||||
|
||||
/* Now find the directive name. */
|
||||
CPP_PUTC (pfile, '#');
|
||||
_cpp_parse_name (pfile, GETC());
|
||||
ident = pfile->token_buffer + old_written + 1;
|
||||
len = CPP_PWRITTEN (pfile) - ident;
|
||||
if (len == 0)
|
||||
{
|
||||
/* A line of just # becomes blank. A line with something
|
||||
other than an identifier after the # is reparsed as a non-
|
||||
directive line. */
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
return (PEEKC() == '\n');
|
||||
}
|
||||
|
||||
/* Decode the keyword and call the appropriate expansion routine. */
|
||||
for (i = 0; i < N_DIRECTIVES; i++)
|
||||
{
|
||||
if (dtable[i].length == len
|
||||
&& !strncmp (dtable[i].name, ident, len))
|
||||
break;
|
||||
}
|
||||
if (i == N_DIRECTIVES)
|
||||
/* # identifier, but not a legit directive. Pass onward as a
|
||||
CPP_DIRECTIVE token anyway - let the consumer worry about it. */
|
||||
/* A line of just # becomes blank. */
|
||||
else if (tok == CPP_VSPACE)
|
||||
return 1;
|
||||
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
/* A NAME token might in fact be a directive! */
|
||||
else if (tok == CPP_NAME)
|
||||
{
|
||||
for (i = 0; i < N_DIRECTIVES; i++)
|
||||
{
|
||||
if (dtable[i].length == len
|
||||
&& !strncmp (dtable[i].name, ident, len))
|
||||
goto real_directive;
|
||||
}
|
||||
/* Don't complain about invalid directives in assembly source,
|
||||
we don't know where the comments are, and # may introduce
|
||||
assembler pseudo-ops. */
|
||||
if (!CPP_OPTION (pfile, lang_asm))
|
||||
cpp_error (pfile, "invalid preprocessing directive #%s", ident);
|
||||
return 0;
|
||||
}
|
||||
/* And anything else means the # wasn't a directive marker. */
|
||||
else
|
||||
return 0;
|
||||
|
||||
real_directive:
|
||||
|
||||
/* In -traditional mode, a directive is ignored unless its # is in
|
||||
column 1. */
|
||||
if (CPP_TRADITIONAL (pfile) && !hash_at_bol)
|
||||
{
|
||||
if (CPP_WTRADITIONAL (pfile))
|
||||
cpp_warning (pfile, "ignoring #%s because of its indented #",
|
||||
dtable[i].name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* no_directives is set when we are parsing macro arguments. Directives
|
||||
in macro arguments are undefined behavior (C99 6.10.3.11); this
|
||||
implementation chooses to make them hard errors. */
|
||||
if (pfile->no_directives)
|
||||
{
|
||||
cpp_error (pfile, "`#%s' may not be used inside a macro argument",
|
||||
cpp_error (pfile, "#%s may not be used inside a macro argument",
|
||||
dtable[i].name);
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Issue -pedantic warnings for extended directives. */
|
||||
if (CPP_PEDANTIC (pfile) && dtable[i].origin == EXTENSION)
|
||||
cpp_pedwarn (pfile, "ISO C does not allow #%s", dtable[i].name);
|
||||
|
||||
/* -Wtraditional gives warnings about directives with inappropriate
|
||||
indentation of #. */
|
||||
if (CPP_WTRADITIONAL (pfile))
|
||||
{
|
||||
if (!hash_at_bol && dtable[i].origin == KANDR)
|
||||
if (!hash_at_bol && TRAD_DIRECT_P (dtable[i].origin))
|
||||
cpp_warning (pfile, "traditional C ignores #%s with the # indented",
|
||||
dtable[i].name);
|
||||
else if (hash_at_bol && dtable[i].origin != KANDR)
|
||||
else if (hash_at_bol && ! TRAD_DIRECT_P (dtable[i].origin))
|
||||
cpp_warning (pfile,
|
||||
"traditional C rejects #%s unless the # is indented",
|
||||
"suggest hiding #%s from traditional C with an indented #",
|
||||
dtable[i].name);
|
||||
}
|
||||
|
||||
if (CPP_TRADITIONAL (pfile) && !hash_at_bol)
|
||||
return 0;
|
||||
/* Unfortunately, it's necessary to scan the directive name again,
|
||||
now we know we're going to consume it. FIXME. */
|
||||
|
||||
(*dtable[i].func) (pfile);
|
||||
pfile->no_macro_expand++;
|
||||
_cpp_get_directive_token (pfile);
|
||||
pfile->no_macro_expand--;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
|
||||
/* Some directives (e.g. #if) may return a request to execute
|
||||
another directive handler immediately. No directive ever
|
||||
requests that #define be executed immediately, so it is safe for
|
||||
the loop to terminate when some function returns 0 (== T_DEFINE). */
|
||||
while ((i = dtable[i].func (pfile)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -282,7 +314,6 @@ get_macro_name (pfile)
|
||||
long here, len;
|
||||
|
||||
here = CPP_WRITTEN (pfile);
|
||||
pfile->no_macro_expand++;
|
||||
if (_cpp_get_directive_token (pfile) != CPP_NAME)
|
||||
{
|
||||
cpp_error (pfile, "`#define' must be followed by an identifier");
|
||||
@ -296,12 +327,10 @@ get_macro_name (pfile)
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
pfile->no_macro_expand--;
|
||||
return len;
|
||||
|
||||
invalid:
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
pfile->no_macro_expand--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -312,38 +341,52 @@ do_define (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
HASHNODE **slot;
|
||||
DEFINITION *def;
|
||||
DEFINITION *def = 0;
|
||||
long here;
|
||||
unsigned long hash;
|
||||
int len, c;
|
||||
int funlike = 0;
|
||||
int len;
|
||||
int funlike = 0, empty = 0;
|
||||
U_CHAR *sym;
|
||||
enum cpp_token token;
|
||||
|
||||
pfile->no_macro_expand++;
|
||||
pfile->parsing_define_directive++;
|
||||
CPP_OPTION (pfile, discard_comments)++;
|
||||
CPP_OPTION (pfile, no_line_commands)++;
|
||||
|
||||
here = CPP_WRITTEN (pfile);
|
||||
len = get_macro_name (pfile);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
/* Copy out the name so we can pop the token buffer. */
|
||||
len = CPP_WRITTEN (pfile) - here;
|
||||
sym = (U_CHAR *) alloca (len + 1);
|
||||
memcpy (sym, pfile->token_buffer + here, len);
|
||||
sym[len] = '\0';
|
||||
CPP_SET_WRITTEN (pfile, here);
|
||||
|
||||
/* If the next character, with no intervening whitespace, is '(',
|
||||
then this is a function-like macro. */
|
||||
c = PEEKC ();
|
||||
if (c == '(')
|
||||
then this is a function-like macro.
|
||||
XXX Layering violation. */
|
||||
CPP_SET_MARK (pfile);
|
||||
token = _cpp_get_directive_token (pfile);
|
||||
if (token == CPP_VSPACE)
|
||||
empty = 0; /* Empty definition of object like macro. */
|
||||
else if (token == CPP_LPAREN && ADJACENT_TO_MARK (pfile))
|
||||
funlike = 1;
|
||||
else if (c != '\n' && !is_hspace (c))
|
||||
/* Otherwise, C99 requires white space after the name. We treat it
|
||||
as an object-like macro if this happens, with a warning. */
|
||||
else if (ADJACENT_TO_MARK (pfile))
|
||||
/* If this is an object-like macro, C99 requires white space after
|
||||
the name. */
|
||||
cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym);
|
||||
CPP_GOTO_MARK (pfile);
|
||||
CPP_SET_WRITTEN (pfile, here);
|
||||
|
||||
def = _cpp_create_definition (pfile, funlike);
|
||||
if (def == 0)
|
||||
return 0;
|
||||
if (! empty)
|
||||
{
|
||||
def = _cpp_create_definition (pfile, funlike);
|
||||
if (def == 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
slot = _cpp_lookup_slot (pfile, sym, len, 1, &hash);
|
||||
if (*slot)
|
||||
@ -353,7 +396,9 @@ do_define (pfile)
|
||||
|
||||
/* Redefining a macro is ok if the definitions are the same. */
|
||||
if (hp->type == T_MACRO)
|
||||
ok = ! _cpp_compare_defs (pfile, def, hp->value.defn);
|
||||
ok = ! empty && ! _cpp_compare_defs (pfile, def, hp->value.defn);
|
||||
else if (hp->type == T_EMPTY)
|
||||
ok = empty;
|
||||
/* Redefining a constant is ok with -D. */
|
||||
else if (hp->type == T_CONST || hp->type == T_STDC)
|
||||
ok = ! pfile->done_initializing;
|
||||
@ -379,8 +424,16 @@ do_define (pfile)
|
||||
/* Replace the old definition. */
|
||||
if (hp->type == T_MACRO)
|
||||
_cpp_free_definition (hp->value.defn);
|
||||
hp->type = T_MACRO;
|
||||
hp->value.defn = def;
|
||||
if (empty)
|
||||
{
|
||||
hp->type = T_EMPTY;
|
||||
hp->value.defn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hp->type = T_MACRO;
|
||||
hp->value.defn = def;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -396,6 +449,11 @@ do_define (pfile)
|
||||
else if (CPP_OPTION (pfile, dump_macros) == dump_names)
|
||||
pass_thru_directive (sym, len, pfile, T_DEFINE);
|
||||
|
||||
out:
|
||||
pfile->no_macro_expand--;
|
||||
pfile->parsing_define_directive--;
|
||||
CPP_OPTION (pfile, discard_comments)--;
|
||||
CPP_OPTION (pfile, no_line_commands)--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -774,29 +832,21 @@ do_undef (pfile)
|
||||
{
|
||||
int len;
|
||||
HASHNODE **slot;
|
||||
U_CHAR *buf, *name, *limit;
|
||||
int c;
|
||||
U_CHAR *name;
|
||||
long here = CPP_WRITTEN (pfile);
|
||||
enum cpp_token token;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
c = GETC();
|
||||
if (! is_idstart(c))
|
||||
{
|
||||
pfile->no_macro_expand++;
|
||||
token = _cpp_get_directive_token (pfile);
|
||||
pfile->no_macro_expand--;
|
||||
|
||||
if (token != CPP_NAME)
|
||||
{
|
||||
cpp_error (pfile, "token after #undef is not an identifier");
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
_cpp_parse_name (pfile, c);
|
||||
buf = pfile->token_buffer + here;
|
||||
limit = CPP_PWRITTEN(pfile);
|
||||
|
||||
/* Copy out the token so we can pop the token buffer. */
|
||||
len = limit - buf;
|
||||
name = (U_CHAR *) alloca (len + 1);
|
||||
memcpy (name, buf, len);
|
||||
name[len] = '\0';
|
||||
return 0;
|
||||
}
|
||||
len = CPP_WRITTEN (pfile) - here;
|
||||
|
||||
token = _cpp_get_directive_token (pfile);
|
||||
if (token != CPP_VSPACE)
|
||||
@ -804,20 +854,23 @@ do_undef (pfile)
|
||||
cpp_pedwarn (pfile, "junk on line after #undef");
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
}
|
||||
|
||||
name = pfile->token_buffer + here;
|
||||
CPP_SET_WRITTEN (pfile, here);
|
||||
|
||||
slot = _cpp_lookup_slot (pfile, name, len, 0, 0);
|
||||
if (slot)
|
||||
{
|
||||
HASHNODE *hp = *slot;
|
||||
/* If we are generating additional info for debugging (with -g) we
|
||||
need to pass through all effective #undef commands. */
|
||||
if (CPP_OPTION (pfile, debug_output))
|
||||
pass_thru_directive (name, len, pfile, T_UNDEF);
|
||||
if (hp->type == T_POISON)
|
||||
cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name);
|
||||
else
|
||||
{
|
||||
/* If we are generating additional info for debugging (with -g) we
|
||||
need to pass through all effective #undef commands. */
|
||||
if (CPP_OPTION (pfile, debug_output))
|
||||
pass_thru_directive (hp->name, len, pfile, T_UNDEF);
|
||||
|
||||
if (hp->type != T_MACRO)
|
||||
cpp_warning (pfile, "undefining `%s'", hp->name);
|
||||
|
||||
@ -1184,8 +1237,7 @@ do_if (pfile)
|
||||
{
|
||||
U_CHAR *control_macro = detect_if_not_defined (pfile);
|
||||
int value = _cpp_parse_expr (pfile);
|
||||
conditional_skip (pfile, value == 0, T_IF, control_macro);
|
||||
return 0;
|
||||
return conditional_skip (pfile, value == 0, T_IF, control_macro);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1214,17 +1266,11 @@ do_elif (pfile)
|
||||
}
|
||||
|
||||
if (pfile->if_stack->if_succeeded)
|
||||
skip_if_group (pfile);
|
||||
else
|
||||
{
|
||||
if (_cpp_parse_expr (pfile) == 0)
|
||||
skip_if_group (pfile);
|
||||
else
|
||||
{
|
||||
++pfile->if_stack->if_succeeded; /* continue processing input */
|
||||
_cpp_output_line_command (pfile, same_file);
|
||||
}
|
||||
}
|
||||
return skip_if_group (pfile);
|
||||
if (_cpp_parse_expr (pfile) == 0)
|
||||
return skip_if_group (pfile);
|
||||
|
||||
++pfile->if_stack->if_succeeded; /* continue processing input */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1291,8 +1337,7 @@ do_ifdef (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int skip = ! parse_ifdef (pfile, dtable[T_IFDEF].name);
|
||||
conditional_skip (pfile, skip, T_IFDEF, 0);
|
||||
return 0;
|
||||
return conditional_skip (pfile, skip, T_IFDEF, 0);
|
||||
}
|
||||
|
||||
/* #ifndef is a tad more complex, because we need to check for a
|
||||
@ -1311,8 +1356,7 @@ do_ifndef (pfile)
|
||||
if (start_of_file && !skip)
|
||||
control_macro = (U_CHAR *) xstrdup (CPP_PWRITTEN (pfile));
|
||||
|
||||
conditional_skip (pfile, skip, T_IFNDEF, control_macro);
|
||||
return 0;
|
||||
return conditional_skip (pfile, skip, T_IFNDEF, control_macro);
|
||||
}
|
||||
|
||||
/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
|
||||
@ -1320,7 +1364,7 @@ do_ifndef (pfile)
|
||||
CONTROL_MACRO is the macro name tested by the #ifndef.
|
||||
Otherwise, CONTROL_MACRO is 0. */
|
||||
|
||||
static void
|
||||
static int
|
||||
conditional_skip (pfile, skip, type, control_macro)
|
||||
cpp_reader *pfile;
|
||||
int skip;
|
||||
@ -1337,19 +1381,19 @@ conditional_skip (pfile, skip, type, control_macro)
|
||||
|
||||
pfile->if_stack->type = type;
|
||||
|
||||
if (skip != 0) {
|
||||
skip_if_group (pfile);
|
||||
return;
|
||||
} else {
|
||||
++pfile->if_stack->if_succeeded;
|
||||
_cpp_output_line_command (pfile, same_file);
|
||||
}
|
||||
if (skip != 0)
|
||||
return skip_if_group (pfile);
|
||||
|
||||
++pfile->if_stack->if_succeeded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Subroutine of skip_if_group. Examine one preprocessing directive and
|
||||
return 0 if skipping should continue, 1 if it should halt. Also
|
||||
adjusts the if_stack as appropriate.
|
||||
The `#' has been read, but not the identifier. */
|
||||
/* Subroutine of skip_if_group. Examine one preprocessing directive
|
||||
and return 0 if skipping should continue, or the directive number
|
||||
of the directive that ends the block if it should halt.
|
||||
|
||||
Also adjusts the if_stack as appropriate. The `#' has been read,
|
||||
but not the identifier. */
|
||||
|
||||
static int
|
||||
consider_directive_while_skipping (pfile, stack)
|
||||
@ -1357,119 +1401,134 @@ consider_directive_while_skipping (pfile, stack)
|
||||
IF_STACK *stack;
|
||||
{
|
||||
long ident;
|
||||
const struct directive *kt;
|
||||
int i;
|
||||
int i, hash_at_bol;
|
||||
unsigned int len;
|
||||
IF_STACK *temp;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
/* -traditional directives are recognized only with the # in column 1. */
|
||||
hash_at_bol = CPP_IN_COLUMN_1 (pfile);
|
||||
|
||||
ident = CPP_WRITTEN (pfile);
|
||||
_cpp_parse_name (pfile, GETC());
|
||||
if (_cpp_get_directive_token (pfile) != CPP_NAME)
|
||||
return 0;
|
||||
len = CPP_WRITTEN (pfile) - ident;
|
||||
|
||||
CPP_SET_WRITTEN (pfile, ident);
|
||||
|
||||
for (i = 0; i < N_DIRECTIVES; i++)
|
||||
{
|
||||
kt = &dtable[i];
|
||||
if (kt->length == len
|
||||
&& strncmp (pfile->token_buffer + ident, kt->name, kt->length) == 0)
|
||||
switch (i)
|
||||
{
|
||||
case T_IF:
|
||||
case T_IFDEF:
|
||||
case T_IFNDEF:
|
||||
temp = (IF_STACK *) xmalloc (sizeof (IF_STACK));
|
||||
temp->next = pfile->if_stack;
|
||||
pfile->if_stack = temp;
|
||||
temp->type = i;
|
||||
return 0;
|
||||
if (dtable[i].length == len
|
||||
&& !strncmp (dtable[i].name, pfile->token_buffer + ident, len))
|
||||
goto real_directive;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case T_ELSE:
|
||||
if (pfile->if_stack != stack)
|
||||
validate_else (pfile, dtable[i].name);
|
||||
/* fall through */
|
||||
case T_ELIF:
|
||||
if (pfile->if_stack == stack)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
pfile->if_stack->type = i;
|
||||
return 0;
|
||||
}
|
||||
real_directive:
|
||||
|
||||
case T_ENDIF:
|
||||
if (pfile->if_stack != stack)
|
||||
validate_else (pfile, dtable[i].name);
|
||||
/* If it's not a directive of interest to us, return now. */
|
||||
if (dtable[i].origin != COND)
|
||||
return 0;
|
||||
|
||||
if (pfile->if_stack == stack)
|
||||
return 1;
|
||||
/* First, deal with -traditional and -Wtraditional.
|
||||
All COND directives are from K+R. */
|
||||
|
||||
temp = pfile->if_stack;
|
||||
pfile->if_stack = temp->next;
|
||||
free (temp);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (! hash_at_bol)
|
||||
{
|
||||
if (CPP_TRADITIONAL (pfile))
|
||||
{
|
||||
if (CPP_WTRADITIONAL (pfile))
|
||||
cpp_warning (pfile, "ignoring #%s because of its indented #",
|
||||
dtable[i].name);
|
||||
return 0;
|
||||
}
|
||||
if (CPP_WTRADITIONAL (pfile))
|
||||
cpp_warning (pfile, "traditional C ignores %s with the # indented",
|
||||
dtable[i].name);
|
||||
}
|
||||
|
||||
/* Don't let erroneous code go by. */
|
||||
if (!CPP_OPTION (pfile, lang_asm) && CPP_PEDANTIC (pfile))
|
||||
cpp_pedwarn (pfile, "invalid preprocessor directive name");
|
||||
return 0;
|
||||
switch (i)
|
||||
{
|
||||
default:
|
||||
cpp_ice (pfile, "non COND directive in switch in c_d_w_s");
|
||||
return 0;
|
||||
|
||||
case T_IF:
|
||||
case T_IFDEF:
|
||||
case T_IFNDEF:
|
||||
temp = (IF_STACK *) xcalloc (1, sizeof (IF_STACK));
|
||||
temp->lineno = CPP_BUFFER (pfile)->lineno;
|
||||
temp->next = pfile->if_stack;
|
||||
temp->type = i;
|
||||
pfile->if_stack = temp;
|
||||
return 0;
|
||||
|
||||
case T_ELSE:
|
||||
if (pfile->if_stack != stack)
|
||||
validate_else (pfile, dtable[i].name);
|
||||
/* fall through */
|
||||
case T_ELIF:
|
||||
if (pfile->if_stack == stack)
|
||||
return i;
|
||||
|
||||
pfile->if_stack->type = i;
|
||||
return 0;
|
||||
|
||||
case T_ENDIF:
|
||||
if (pfile->if_stack != stack)
|
||||
validate_else (pfile, dtable[i].name);
|
||||
|
||||
if (pfile->if_stack == stack)
|
||||
return i;
|
||||
|
||||
temp = pfile->if_stack;
|
||||
pfile->if_stack = temp->next;
|
||||
free (temp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip to #endif, #else, or #elif. adjust line numbers, etc.
|
||||
* leaves input ptr at the sharp sign found.
|
||||
*/
|
||||
static void
|
||||
/* Skip to #endif, #else, or #elif. Consumes the directive that
|
||||
causes it to stop, but not its argument. Returns the number of
|
||||
that directive, which must be passed back up to
|
||||
_cpp_handle_directive, which will execute it. */
|
||||
static int
|
||||
skip_if_group (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int c;
|
||||
enum cpp_token token;
|
||||
IF_STACK *save_if_stack = pfile->if_stack; /* don't pop past here */
|
||||
const U_CHAR *beg_of_line;
|
||||
long old_written;
|
||||
int ret = 0;
|
||||
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
|
||||
pfile->no_macro_expand++;
|
||||
CPP_OPTION (pfile, no_line_commands)++;
|
||||
for (;;)
|
||||
{
|
||||
beg_of_line = CPP_BUFFER (pfile)->cur;
|
||||
token = _cpp_get_directive_token (pfile);
|
||||
|
||||
if (! CPP_TRADITIONAL (pfile))
|
||||
_cpp_skip_hspace (pfile);
|
||||
c = GETC();
|
||||
if (c == '\n')
|
||||
if (token == CPP_DIRECTIVE)
|
||||
{
|
||||
CPP_BUMP_LINE (pfile);
|
||||
continue;
|
||||
}
|
||||
else if (c == '#')
|
||||
{
|
||||
if (consider_directive_while_skipping (pfile, save_if_stack))
|
||||
ret = consider_directive_while_skipping (pfile, save_if_stack);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
else if (c == EOF)
|
||||
return; /* Caller will issue error. */
|
||||
|
||||
FORWARD(-1);
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
if (token != CPP_VSPACE)
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
|
||||
c = GETC();
|
||||
if (c == EOF)
|
||||
return; /* Caller will issue error. */
|
||||
else
|
||||
CPP_BUMP_LINE (pfile);
|
||||
/* Only cpp_get_token knows how to advance the line number
|
||||
properly. */
|
||||
token = cpp_get_token (pfile);
|
||||
if (token == CPP_POP)
|
||||
break; /* Caller will issue error. */
|
||||
|
||||
else if (token != CPP_VSPACE)
|
||||
cpp_ice (pfile, "cpp_get_token returned %d in skip_if_group", token);
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
}
|
||||
|
||||
/* Back up to the beginning of this line. Caller will process the
|
||||
directive. */
|
||||
CPP_BUFFER (pfile)->cur = beg_of_line;
|
||||
pfile->only_seen_white = 1;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
pfile->no_macro_expand--;
|
||||
CPP_OPTION (pfile, no_line_commands)--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1507,12 +1566,9 @@ do_else (pfile)
|
||||
}
|
||||
|
||||
if (pfile->if_stack->if_succeeded)
|
||||
skip_if_group (pfile);
|
||||
else
|
||||
{
|
||||
++pfile->if_stack->if_succeeded; /* continue processing input */
|
||||
_cpp_output_line_command (pfile, same_file);
|
||||
}
|
||||
return skip_if_group (pfile);
|
||||
|
||||
++pfile->if_stack->if_succeeded; /* continue processing input */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1534,33 +1590,8 @@ do_endif (pfile)
|
||||
IF_STACK *temp = pfile->if_stack;
|
||||
pfile->if_stack = temp->next;
|
||||
if (temp->control_macro != 0)
|
||||
{
|
||||
/* This #endif matched a #ifndef at the start of the file.
|
||||
See if it is at the end of the file. */
|
||||
int c;
|
||||
|
||||
CPP_SET_MARK (pfile);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
_cpp_skip_hspace (pfile);
|
||||
c = GETC ();
|
||||
if (c != '\n')
|
||||
break;
|
||||
}
|
||||
CPP_GOTO_MARK (pfile);
|
||||
|
||||
if (c == EOF)
|
||||
{
|
||||
/* This #endif ends a #ifndef
|
||||
that contains all of the file (aside from whitespace).
|
||||
Arrange not to include the file again
|
||||
if the macro that was tested is defined. */
|
||||
CPP_BUFFER (pfile)->ihash->control_macro = temp->control_macro;
|
||||
}
|
||||
}
|
||||
pfile->potential_control_macro = temp->control_macro;
|
||||
free (temp);
|
||||
_cpp_output_line_command (pfile, same_file);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1574,13 +1605,17 @@ validate_else (pfile, directive)
|
||||
cpp_reader *pfile;
|
||||
const char *directive;
|
||||
{
|
||||
long old_written;
|
||||
if (! CPP_PEDANTIC (pfile))
|
||||
return;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
if (PEEKC () != '\n')
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
pfile->no_macro_expand++;
|
||||
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
|
||||
cpp_pedwarn (pfile,
|
||||
"text following `#%s' violates ANSI standard", directive);
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
pfile->no_macro_expand--;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1604,6 +1639,13 @@ _cpp_handle_eof (pfile)
|
||||
}
|
||||
pfile->if_stack = ifs;
|
||||
|
||||
if (pfile->potential_control_macro)
|
||||
{
|
||||
CPP_BUFFER (pfile)->ihash->control_macro
|
||||
= pfile->potential_control_macro;
|
||||
pfile->potential_control_macro = 0;
|
||||
}
|
||||
|
||||
if (CPP_BUFFER (pfile)->nominal_fname && next_buf != NULL)
|
||||
{
|
||||
/* We're about to return from an #include file.
|
||||
@ -1623,38 +1665,37 @@ static int
|
||||
do_assert (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
long old_written;
|
||||
U_CHAR *sym;
|
||||
int ret, c;
|
||||
int ret;
|
||||
HASHNODE *base, *this;
|
||||
HASHNODE **bslot, **tslot;
|
||||
size_t blen, tlen;
|
||||
unsigned long bhash, thash;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
sym = CPP_PWRITTEN (pfile); /* remember where it starts */
|
||||
old_written = CPP_WRITTEN (pfile); /* remember where it starts */
|
||||
ret = _cpp_parse_assertion (pfile);
|
||||
if (ret == 0)
|
||||
goto error;
|
||||
else if (ret == 1)
|
||||
{
|
||||
cpp_error (pfile, "missing token-sequence in `#assert'");
|
||||
cpp_error (pfile, "missing token-sequence in #assert");
|
||||
goto error;
|
||||
}
|
||||
tlen = CPP_WRITTEN (pfile) - old_written;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
c = PEEKC();
|
||||
if (c != EOF && c != '\n')
|
||||
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
|
||||
{
|
||||
cpp_error (pfile, "junk at end of `#assert'");
|
||||
cpp_error (pfile, "junk at end of #assert");
|
||||
goto error;
|
||||
}
|
||||
|
||||
tlen = strlen (sym);
|
||||
sym = pfile->token_buffer + old_written;
|
||||
blen = (U_CHAR *) strchr (sym, '(') - sym;
|
||||
tslot = _cpp_lookup_slot (pfile, sym, tlen, 1, &thash);
|
||||
if (*tslot)
|
||||
{
|
||||
cpp_warning (pfile, "`%s' re-asserted", sym);
|
||||
cpp_warning (pfile, "%s re-asserted", sym);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1678,12 +1719,9 @@ do_assert (pfile)
|
||||
this->value.aschain = base->value.aschain;
|
||||
base->value.aschain = this;
|
||||
|
||||
pfile->limit = sym; /* Pop */
|
||||
return 0;
|
||||
|
||||
error:
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
pfile->limit = sym; /* Pop */
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1691,24 +1729,26 @@ static int
|
||||
do_unassert (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int c, ret;
|
||||
int ret;
|
||||
long old_written;
|
||||
U_CHAR *sym;
|
||||
long baselen, thislen;
|
||||
HASHNODE *base, *this, *next;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
|
||||
sym = CPP_PWRITTEN (pfile); /* remember where it starts */
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
ret = _cpp_parse_assertion (pfile);
|
||||
if (ret == 0)
|
||||
goto error;
|
||||
thislen = CPP_WRITTEN (pfile) - old_written;
|
||||
|
||||
_cpp_skip_hspace (pfile);
|
||||
c = PEEKC ();
|
||||
if (c != EOF && c != '\n')
|
||||
cpp_error (pfile, "junk at end of `#unassert'");
|
||||
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
|
||||
{
|
||||
cpp_error (pfile, "junk at end of #unassert");
|
||||
goto error;
|
||||
}
|
||||
sym = pfile->token_buffer + old_written;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
|
||||
thislen = strlen (sym);
|
||||
if (ret == 1)
|
||||
{
|
||||
base = _cpp_lookup (pfile, sym, thislen);
|
||||
@ -1743,12 +1783,11 @@ do_unassert (pfile)
|
||||
/* Last answer for this predicate deleted. */
|
||||
htab_remove_elt (pfile->hashtab, base);
|
||||
}
|
||||
|
||||
pfile->limit = sym; /* Pop */
|
||||
return 0;
|
||||
|
||||
error:
|
||||
_cpp_skip_rest_of_line (pfile);
|
||||
pfile->limit = sym; /* Pop */
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
10
gcc/cpplib.h
10
gcc/cpplib.h
@ -67,8 +67,8 @@ struct cpp_buffer
|
||||
const unsigned char *cur; /* current position */
|
||||
const unsigned char *rlimit; /* end of valid data */
|
||||
const unsigned char *buf; /* entire buffer */
|
||||
const unsigned char *alimit; /* end of allocated buffer */
|
||||
const unsigned char *line_base; /* start of current line */
|
||||
const unsigned char *mark; /* Saved position for lengthy backtrack. */
|
||||
|
||||
struct cpp_buffer *prev;
|
||||
|
||||
@ -84,10 +84,11 @@ struct cpp_buffer
|
||||
struct ihash *ihash;
|
||||
|
||||
long lineno; /* Line number at CPP_LINE_BASE. */
|
||||
long colno; /* Column number at CPP_LINE_BASE. */
|
||||
long mark; /* Saved position for lengthy backtrack. */
|
||||
parse_cleanup_t cleanup;
|
||||
void *data;
|
||||
|
||||
/* If the buffer is the expansion of a macro, this points to the
|
||||
macro's hash table entry. */
|
||||
struct hashnode *macro;
|
||||
|
||||
/* Value of if_stack at start of this file.
|
||||
Used to prohibit unmatched #endif (etc) in an include file. */
|
||||
@ -347,6 +348,7 @@ struct cpp_reader
|
||||
unsigned int max_include_len;
|
||||
|
||||
struct if_stack *if_stack;
|
||||
const unsigned char *potential_control_macro;
|
||||
|
||||
long lineno;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user