Commit ff2b53ef by Zack Weinberg Committed by Zack Weinberg

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
parent edea3682
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> 2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
* configure.in: And here. * configure.in: And here.
......
...@@ -742,12 +742,11 @@ read_include_file (pfile, fd, ihash) ...@@ -742,12 +742,11 @@ read_include_file (pfile, fd, ihash)
ihash->control_macro = (const U_CHAR *) ""; /* never re-include */ ihash->control_macro = (const U_CHAR *) ""; /* never re-include */
close (fd); close (fd);
fp->rlimit = fp->alimit = fp->buf + length; fp->rlimit = fp->buf + length;
fp->cur = fp->buf; fp->cur = fp->buf;
if (ihash->foundhere != ABSOLUTE_PATH) if (ihash->foundhere != ABSOLUTE_PATH)
fp->system_header_p = ihash->foundhere->sysp; fp->system_header_p = ihash->foundhere->sysp;
fp->lineno = 1; fp->lineno = 1;
fp->colno = 1;
fp->line_base = fp->buf; fp->line_base = fp->buf;
fp->cleanup = file_cleanup; fp->cleanup = file_cleanup;
......
...@@ -45,10 +45,6 @@ static enum cpp_token macarg PARAMS ((cpp_reader *, int)); ...@@ -45,10 +45,6 @@ static enum cpp_token macarg PARAMS ((cpp_reader *, int));
static struct tm *timestamp PARAMS ((cpp_reader *)); static struct tm *timestamp PARAMS ((cpp_reader *));
static void special_symbol PARAMS ((HASHNODE *, 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.) */ /* Initial hash table size. (It can grow if necessary - see hashtab.c.) */
#define HASHSIZE 500 #define HASHSIZE 500
...@@ -266,7 +262,7 @@ macro_cleanup (pbuf, pfile) ...@@ -266,7 +262,7 @@ macro_cleanup (pbuf, pfile)
cpp_buffer *pbuf; cpp_buffer *pbuf;
cpp_reader *pfile ATTRIBUTE_UNUSED; cpp_reader *pfile ATTRIBUTE_UNUSED;
{ {
HASHNODE *macro = (HASHNODE *) pbuf->data; HASHNODE *macro = pbuf->macro;
if (macro->type == T_DISABLED) if (macro->type == T_DISABLED)
macro->type = T_MACRO; macro->type = T_MACRO;
if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion) if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
...@@ -314,26 +310,18 @@ collect_expansion (pfile, arglist) ...@@ -314,26 +310,18 @@ collect_expansion (pfile, arglist)
last -= 2; /* two extra chars for the leading escape */ last -= 2; /* two extra chars for the leading escape */
for (;;) for (;;)
{ {
/* We use cpp_get_token because _cpp_get_directive_token would /* Macro expansion is off, so we are guaranteed not to see POP
discard whitespace and we can't cope with that yet. Macro or EOF. */
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;
here = CPP_WRITTEN (pfile); here = CPP_WRITTEN (pfile);
token = cpp_get_token (pfile); token = _cpp_get_define_token (pfile);
tok = pfile->token_buffer + here; tok = pfile->token_buffer + here;
switch (token) switch (token)
{ {
case CPP_POP: case CPP_POP:
case CPP_EOF: case CPP_EOF:
cpp_ice (pfile, "EOF in collect_expansion");
/* fall through */
case CPP_VSPACE: case CPP_VSPACE:
cpp_ice (pfile, "EOF or VSPACE in collect_expansion");
goto done; goto done;
case CPP_HSPACE: case CPP_HSPACE:
...@@ -386,16 +374,14 @@ collect_expansion (pfile, arglist) ...@@ -386,16 +374,14 @@ collect_expansion (pfile, arglist)
case CPP_COMMENT: case CPP_COMMENT:
/* We must be in -traditional mode. Pretend this was a /* We must be in -traditional mode. Pretend this was a
token paste, but only if there was no leading or 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); CPP_SET_WRITTEN (pfile, here);
if (last_token == START) if (last_token == START)
break; break;
if (is_hspace (pfile->token_buffer[here-1])) if (is_hspace (pfile->token_buffer[here-1]))
break; break;
if (is_hspace (PEEKC ()))
break;
if (PEEKC () == '\n')
break;
if (last_token == ARG) if (last_token == ARG)
endpat->raw_after = 1; endpat->raw_after = 1;
last_token = PASTE; last_token = PASTE;
...@@ -738,38 +724,21 @@ _cpp_create_definition (pfile, funlike) ...@@ -738,38 +724,21 @@ _cpp_create_definition (pfile, funlike)
cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col); cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
file = CPP_BUFFER (pfile)->nominal_fname; 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) if (funlike)
{ {
args = collect_formal_parameters (pfile); args = collect_formal_parameters (pfile);
if (args == 0) if (args == 0)
goto err; return 0;
} }
defn = collect_expansion (pfile, args); defn = collect_expansion (pfile, args);
if (defn == 0) if (defn == 0)
goto err; return 0;
defn->line = line; defn->line = line;
defn->file = file; defn->file = file;
defn->col = col; defn->col = col;
pfile->no_macro_expand--;
pfile->parsing_define_directive--;
CPP_OPTION (pfile, discard_comments)--;
CPP_OPTION (pfile, no_line_commands)--;
return defn; 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) ...@@ -1446,6 +1415,18 @@ unsafe_chars (pfile, c1, c2)
{ {
switch (c1) 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 '-': case '+': case '-':
if (c2 == c1 || c2 == '=') if (c2 == c1 || c2 == '=')
return 1; return 1;
...@@ -1488,17 +1469,14 @@ unsafe_chars (pfile, c1, c2) ...@@ -1488,17 +1469,14 @@ unsafe_chars (pfile, c1, c2)
} }
static void static void
push_macro_expansion (pfile, xbuf, xbuf_len, hp) push_macro_expansion (pfile, xbuf, len, hp)
cpp_reader *pfile; cpp_reader *pfile;
register U_CHAR *xbuf; register U_CHAR *xbuf;
int xbuf_len; int len;
HASHNODE *hp; HASHNODE *hp;
{ {
register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len); cpp_buffer *mbuf;
if (mbuf == NULL) int advance_cur = 0;
return;
mbuf->cleanup = macro_cleanup;
mbuf->data = hp;
/* The first chars of the expansion should be a "\r " added by /* The first chars of the expansion should be a "\r " added by
collect_expansion. This is to prevent accidental token-pasting collect_expansion. This is to prevent accidental token-pasting
...@@ -1507,34 +1485,31 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp) ...@@ -1507,34 +1485,31 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp)
We would like to avoid adding unneeded spaces (for the sake of 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 tools that use cpp, such as imake). In some common cases we can
tell that it is safe to omit the space. 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. */
if (xbuf[0] == '\r' && xbuf[1] == ' ' if (xbuf[0] == '\r' && xbuf[1] == ' '
&& (is_idchar(xbuf[2]) || xbuf[2] == '(' || xbuf[2] == '\'' && !unsafe_chars (pfile, EOF, xbuf[2]))
|| xbuf[2] == '\"')) advance_cur = 1;
mbuf->cur += 2;
/* Likewise, avoid the extra space at the end of the macro expansion /* 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 if this is safe. We can do a better job here since we can know
what the next char will be. */ what the next char will be. */
if (xbuf_len >= 3 if (len >= 3
&& mbuf->rlimit[-2] == '\r' && xbuf[len-2] == '\r'
&& mbuf->rlimit[-1] == ' ') && xbuf[len-1] == ' ')
{ {
int c1 = mbuf->rlimit[-3]; int c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile))); if (c == EOF || !unsafe_chars (pfile, xbuf[len-3], c))
if (c2 == EOF || !unsafe_chars (pfile, c1, c2)) len -= 2;
mbuf->rlimit -= 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. */ /* Return zero if two DEFINITIONs are isomorphic. */
......
...@@ -98,7 +98,7 @@ enum node_type ...@@ -98,7 +98,7 @@ enum node_type
T_MACRO, /* macro defined by `#define' */ T_MACRO, /* macro defined by `#define' */
T_DISABLED, /* macro temporarily turned off for rescan */ T_DISABLED, /* macro temporarily turned off for rescan */
T_POISON, /* macro defined with `#pragma poison' */ 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 /* different kinds of things that can appear in the value field
...@@ -192,11 +192,11 @@ extern unsigned char _cpp_IStable[256]; ...@@ -192,11 +192,11 @@ extern unsigned char _cpp_IStable[256];
/* Macros. */ /* 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) \ #define CPP_BUF_PEEK(BUFFER) \
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF) ((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. */ /* Make sure PFILE->token_buffer has space for at least N more characters. */
#define CPP_RESERVE(PFILE, N) \ #define CPP_RESERVE(PFILE, N) \
...@@ -223,6 +223,11 @@ extern unsigned char _cpp_IStable[256]; ...@@ -223,6 +223,11 @@ extern unsigned char _cpp_IStable[256];
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE)) #define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev) #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_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
#define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional) #define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional)
#define CPP_PEDANTIC(PFILE) \ #define CPP_PEDANTIC(PFILE) \
...@@ -232,7 +237,7 @@ extern unsigned char _cpp_IStable[256]; ...@@ -232,7 +237,7 @@ extern unsigned char _cpp_IStable[256];
/* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion. /* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion.
(Note that it is false while we're expanding macro *arguments*.) */ (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 /* Remember the current position of PFILE so it may be returned to
after looking ahead a bit. after looking ahead a bit.
...@@ -241,14 +246,18 @@ extern unsigned char _cpp_IStable[256]; ...@@ -241,14 +246,18 @@ extern unsigned char _cpp_IStable[256];
may not forget about it and continue parsing. You may not pop a 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 buffer with an active mark. You may not call CPP_BUMP_LINE while a
mark is active. */ mark is active. */
#define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur - (IP)->buf) #define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur)
#define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->buf + (IP)->mark, \ #define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->mark, (IP)->mark = 0)
(IP)->mark = -1)
#define CPP_SET_MARK(PFILE) CPP_SET_BUF_MARK(CPP_BUFFER(PFILE)) #define CPP_SET_MARK(PFILE) CPP_SET_BUF_MARK(CPP_BUFFER(PFILE))
#define CPP_GOTO_MARK(PFILE) CPP_GOTO_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. */ /* 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. */ /* Last arg to output_line_command. */
enum file_change_code {same_file, rename_file, enter_file, leave_file}; 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 *)); ...@@ -296,6 +305,8 @@ extern void _cpp_init_input_buffer PARAMS ((cpp_reader *));
extern void _cpp_grow_token_buffer PARAMS ((cpp_reader *, long)); extern void _cpp_grow_token_buffer PARAMS ((cpp_reader *, long));
extern enum cpp_token _cpp_get_directive_token extern enum cpp_token _cpp_get_directive_token
PARAMS ((cpp_reader *)); PARAMS ((cpp_reader *));
extern enum cpp_token _cpp_get_define_token
PARAMS ((cpp_reader *));
/* In cpplib.c */ /* In cpplib.c */
extern int _cpp_handle_directive PARAMS ((cpp_reader *)); extern int _cpp_handle_directive PARAMS ((cpp_reader *));
......
...@@ -25,11 +25,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -25,11 +25,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpplib.h" #include "cpplib.h"
#include "cpphash.h" #include "cpphash.h"
#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \ #define PEEKBUF(BUFFER, N) \
? CPP_BUFFER (pfile)->cur[N] : EOF) ((BUFFER)->rlimit - (BUFFER)->cur > (N) ? (BUFFER)->cur[N] : EOF)
#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) #define GETBUF(BUFFER) \
#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile)) ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) #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_block_comment PARAMS ((cpp_reader *));
static void skip_line_comment PARAMS ((cpp_reader *)); static void skip_line_comment PARAMS ((cpp_reader *));
...@@ -87,9 +92,9 @@ cpp_push_buffer (pfile, buffer, length) ...@@ -87,9 +92,9 @@ cpp_push_buffer (pfile, buffer, length)
new->if_stack = pfile->if_stack; new->if_stack = pfile->if_stack;
new->cleanup = null_cleanup; new->cleanup = null_cleanup;
new->buf = new->cur = buffer; new->buf = new->cur = buffer;
new->alimit = new->rlimit = buffer + length; new->rlimit = buffer + length;
new->prev = buf; new->prev = buf;
new->mark = -1; new->mark = NULL;
new->line_base = NULL; new->line_base = NULL;
CPP_BUFFER (pfile) = new; CPP_BUFFER (pfile) = new;
...@@ -667,7 +672,6 @@ _cpp_parse_assertion (pfile) ...@@ -667,7 +672,6 @@ _cpp_parse_assertion (pfile)
else else
CPP_PUTC (pfile, ')'); CPP_PUTC (pfile, ')');
CPP_NUL_TERMINATE (pfile);
return 2; return 2;
} }
...@@ -702,9 +706,17 @@ _cpp_lex_token (pfile) ...@@ -702,9 +706,17 @@ _cpp_lex_token (pfile)
/* Comments are equivalent to spaces. /* Comments are equivalent to spaces.
For -traditional, a comment is equivalent to nothing. */ 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; return CPP_COMMENT;
else else
goto get_next;
}
else
{ {
CPP_PUTC (pfile, c); CPP_PUTC (pfile, c);
return CPP_HSPACE; return CPP_HSPACE;
...@@ -713,7 +725,6 @@ _cpp_lex_token (pfile) ...@@ -713,7 +725,6 @@ _cpp_lex_token (pfile)
case '#': case '#':
if (pfile->parsing_if_directive) if (pfile->parsing_if_directive)
{ {
_cpp_skip_hspace (pfile);
if (_cpp_parse_assertion (pfile)) if (_cpp_parse_assertion (pfile))
return CPP_ASSERTION; return CPP_ASSERTION;
goto randomchar; goto randomchar;
...@@ -740,7 +751,6 @@ _cpp_lex_token (pfile) ...@@ -740,7 +751,6 @@ _cpp_lex_token (pfile)
case '\"': case '\"':
case '\'': case '\'':
parse_string (pfile, c); parse_string (pfile, c);
pfile->only_seen_white = 0;
return c == '\'' ? CPP_CHAR : CPP_STRING; return c == '\'' ? CPP_CHAR : CPP_STRING;
case '$': case '$':
...@@ -787,7 +797,6 @@ _cpp_lex_token (pfile) ...@@ -787,7 +797,6 @@ _cpp_lex_token (pfile)
{ {
/* In C++, there's a ->* operator. */ /* In C++, there's a ->* operator. */
token = CPP_OTHER; token = CPP_OTHER;
pfile->only_seen_white = 0;
CPP_RESERVE (pfile, 4); CPP_RESERVE (pfile, 4);
CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, GETC ()); CPP_PUTC_Q (pfile, GETC ());
...@@ -851,7 +860,6 @@ _cpp_lex_token (pfile) ...@@ -851,7 +860,6 @@ _cpp_lex_token (pfile)
if (c3 == '=') if (c3 == '=')
CPP_PUTC_Q (pfile, GETC ()); CPP_PUTC_Q (pfile, GETC ());
CPP_NUL_TERMINATE_Q (pfile); CPP_NUL_TERMINATE_Q (pfile);
pfile->only_seen_white = 0;
return CPP_OTHER; return CPP_OTHER;
case '.': case '.':
...@@ -876,14 +884,12 @@ _cpp_lex_token (pfile) ...@@ -876,14 +884,12 @@ _cpp_lex_token (pfile)
CPP_PUTC_Q (pfile, '.'); CPP_PUTC_Q (pfile, '.');
FORWARD (2); FORWARD (2);
CPP_NUL_TERMINATE_Q (pfile); CPP_NUL_TERMINATE_Q (pfile);
pfile->only_seen_white = 0;
return CPP_3DOTS; return CPP_3DOTS;
} }
goto randomchar; goto randomchar;
op2: op2:
token = CPP_OTHER; token = CPP_OTHER;
pfile->only_seen_white = 0;
CPP_RESERVE(pfile, 3); CPP_RESERVE(pfile, 3);
CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, GETC ()); CPP_PUTC_Q (pfile, GETC ());
...@@ -897,7 +903,6 @@ _cpp_lex_token (pfile) ...@@ -897,7 +903,6 @@ _cpp_lex_token (pfile)
CPP_PUTC (pfile, c); CPP_PUTC (pfile, c);
c = GETC (); c = GETC ();
parse_string (pfile, c); parse_string (pfile, c);
pfile->only_seen_white = 0;
return c == '\'' ? CPP_WCHAR : CPP_WSTRING; return c == '\'' ? CPP_WCHAR : CPP_WSTRING;
} }
goto letter; goto letter;
...@@ -923,13 +928,11 @@ _cpp_lex_token (pfile) ...@@ -923,13 +928,11 @@ _cpp_lex_token (pfile)
c2= c; c2= c;
} }
CPP_NUL_TERMINATE_Q (pfile); CPP_NUL_TERMINATE_Q (pfile);
pfile->only_seen_white = 0;
return CPP_NUMBER; return CPP_NUMBER;
case 'b': case 'c': case 'd': case 'h': case 'o': case 'b': case 'c': case 'd': case 'h': case 'o':
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 () == '\'') if (CPP_OPTION (pfile, chill) && PEEKC () == '\'')
{ {
pfile->only_seen_white = 0;
CPP_RESERVE (pfile, 2); CPP_RESERVE (pfile, 2);
CPP_PUTC_Q (pfile, c); CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, '\''); CPP_PUTC_Q (pfile, '\'');
...@@ -970,11 +973,10 @@ _cpp_lex_token (pfile) ...@@ -970,11 +973,10 @@ _cpp_lex_token (pfile)
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z': case 'Y': case 'Z':
letter: letter:
pfile->only_seen_white = 0;
_cpp_parse_name (pfile, c); _cpp_parse_name (pfile, c);
return CPP_MACRO; return CPP_MACRO;
case ' ': case '\t': case '\v': case ' ': case '\t': case '\v': case '\f':
for (;;) for (;;)
{ {
CPP_PUTC (pfile, c); CPP_PUTC (pfile, c);
...@@ -998,6 +1000,8 @@ _cpp_lex_token (pfile) ...@@ -998,6 +1000,8 @@ _cpp_lex_token (pfile)
} }
else if (c == ' ') else if (c == ' ')
{ {
/* "\r " means a space, but only if necessary to prevent
accidental token concatenation. */
CPP_RESERVE (pfile, 2); CPP_RESERVE (pfile, 2);
if (pfile->output_escapes) if (pfile->output_escapes)
CPP_PUTC_Q (pfile, '\r'); CPP_PUTC_Q (pfile, '\r');
...@@ -1019,15 +1023,6 @@ _cpp_lex_token (pfile) ...@@ -1019,15 +1023,6 @@ _cpp_lex_token (pfile)
case '\n': case '\n':
CPP_PUTC (pfile, c); 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; return CPP_VSPACE;
case '(': token = CPP_LPAREN; goto char1; case '(': token = CPP_LPAREN; goto char1;
...@@ -1041,7 +1036,6 @@ _cpp_lex_token (pfile) ...@@ -1041,7 +1036,6 @@ _cpp_lex_token (pfile)
default: default:
token = CPP_OTHER; token = CPP_OTHER;
char1: char1:
pfile->only_seen_white = 0;
CPP_PUTC (pfile, c); CPP_PUTC (pfile, c);
return token; return token;
} }
...@@ -1075,6 +1069,13 @@ maybe_macroexpand (pfile, written) ...@@ -1075,6 +1069,13 @@ maybe_macroexpand (pfile, written)
} }
return 0; 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 macro wants an arglist, verify that a '(' follows. */
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
...@@ -1146,9 +1147,28 @@ cpp_get_token (pfile) ...@@ -1146,9 +1147,28 @@ cpp_get_token (pfile)
switch (token) switch (token)
{ {
default: 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; return token;
case CPP_DIRECTIVE: case CPP_DIRECTIVE:
pfile->potential_control_macro = 0;
if (_cpp_handle_directive (pfile)) if (_cpp_handle_directive (pfile))
return CPP_DIRECTIVE; return CPP_DIRECTIVE;
pfile->only_seen_white = 0; pfile->only_seen_white = 0;
...@@ -1156,6 +1176,8 @@ cpp_get_token (pfile) ...@@ -1156,6 +1176,8 @@ cpp_get_token (pfile)
return CPP_OTHER; return CPP_OTHER;
case CPP_MACRO: case CPP_MACRO:
pfile->potential_control_macro = 0;
pfile->only_seen_white = 0;
if (! pfile->no_macro_expand if (! pfile->no_macro_expand
&& maybe_macroexpand (pfile, written)) && maybe_macroexpand (pfile, written))
goto get_next; goto get_next;
...@@ -1192,57 +1214,96 @@ cpp_get_non_space_token (pfile) ...@@ -1192,57 +1214,96 @@ cpp_get_non_space_token (pfile)
for (;;) for (;;)
{ {
enum cpp_token token = cpp_get_token (pfile); enum cpp_token token = cpp_get_token (pfile);
if (token != CPP_COMMENT && token != CPP_POP if (token != CPP_COMMENT && token != CPP_HSPACE && token != CPP_VSPACE)
&& token != CPP_HSPACE && token != CPP_VSPACE)
return token; return token;
CPP_SET_WRITTEN (pfile, old_written); CPP_SET_WRITTEN (pfile, old_written);
} }
} }
/* Like cpp_get_token, except that it does not read past end-of-line. /* Like cpp_get_token, except that it does not execute directives,
Also, horizontal space is skipped, and macros are popped. */ 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 enum cpp_token
_cpp_get_directive_token (pfile) _cpp_get_define_token (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
long old_written = CPP_WRITTEN (pfile); long old_written;
enum cpp_token token; enum cpp_token token;
for (;;) get_next:
old_written = CPP_WRITTEN (pfile);
token = _cpp_lex_token (pfile);
switch (token)
{ {
_cpp_skip_hspace (pfile); default:
if (PEEKC () == '\n') return token;
case CPP_VSPACE:
/* Put it back and return VSPACE. */
FORWARD(-1);
CPP_ADJUST_WRITTEN (pfile, -1);
return CPP_VSPACE; return CPP_VSPACE;
token = cpp_get_token (pfile); case CPP_HSPACE:
/* token could be hspace at the beginning of a macro. */ if (CPP_PEDANTIC (pfile))
if (token == CPP_HSPACE || token == CPP_COMMENT)
{ {
CPP_SET_WRITTEN (pfile, old_written); U_CHAR *p, *limit;
continue; 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;
/* token cannot be vspace, it would have been caught above. */ case CPP_EOF:
if (token == CPP_VSPACE) if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
{ {
cpp_ice (pfile, "VSPACE in get_directive_token"); cpp_pop_buffer (pfile);
return token; 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;
} }
}
/* token cannot be POP unless the buffer is a macro buffer. */ /* Just like _cpp_get_define_token except that it discards horizontal
if (token != CPP_POP) whitespace. */
return token;
if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) enum cpp_token
_cpp_get_directive_token (pfile)
cpp_reader *pfile;
{
int old_written = CPP_WRITTEN (pfile);
for (;;)
{ {
cpp_ice (pfile, "POP of file buffer in get_directive_token"); enum cpp_token token = _cpp_get_define_token (pfile);
if (token != CPP_COMMENT && token != CPP_HSPACE)
return token; return token;
} CPP_SET_WRITTEN (pfile, old_written);
/* 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);
} }
} }
......
...@@ -28,12 +28,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -28,12 +28,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "intl.h" #include "intl.h"
#include "symcat.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' defines one #-directive, including how to handle it. */
struct directive struct directive
...@@ -63,9 +57,9 @@ typedef struct if_stack IF_STACK; ...@@ -63,9 +57,9 @@ typedef struct if_stack IF_STACK;
static void validate_else PARAMS ((cpp_reader *, const char *)); static void validate_else PARAMS ((cpp_reader *, const char *));
static int parse_ifdef 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 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 *)); 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, static void pass_thru_directive PARAMS ((const U_CHAR *, size_t,
cpp_reader *, int)); cpp_reader *, int));
static int read_line_number PARAMS ((cpp_reader *, int *)); static int read_line_number PARAMS ((cpp_reader *, int *));
...@@ -74,8 +68,14 @@ static int consider_directive_while_skipping ...@@ -74,8 +68,14 @@ static int consider_directive_while_skipping
PARAMS ((cpp_reader *, IF_STACK *)); PARAMS ((cpp_reader *, IF_STACK *));
static int get_macro_name PARAMS ((cpp_reader *)); static int get_macro_name PARAMS ((cpp_reader *));
/* Values for the "origin" field of the table below. */ /* Values for the "origin" field of the table below. KANDR and COND
enum { KANDR = 0, STDC89, EXTENSION }; 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 /* This is the table of directive handlers. It is ordered by
frequency of occurrence; the numbers at the end are directive frequency of occurrence; the numbers at the end are directive
...@@ -95,16 +95,16 @@ enum { KANDR = 0, STDC89, EXTENSION }; ...@@ -95,16 +95,16 @@ enum { KANDR = 0, STDC89, EXTENSION };
#endif #endif
#define DIRECTIVE_TABLE \ #define DIRECTIVE_TABLE \
D(define, T_DEFINE, KANDR) /* 270554 */ \ D(define, T_DEFINE = 0, KANDR) /* 270554 */ \
D(include, T_INCLUDE, KANDR) /* 52262 */ \ D(include, T_INCLUDE, KANDR) /* 52262 */ \
D(endif, T_ENDIF, KANDR) /* 45855 */ \ D(endif, T_ENDIF, COND) /* 45855 */ \
D(ifdef, T_IFDEF, KANDR) /* 22000 */ \ D(ifdef, T_IFDEF, COND) /* 22000 */ \
D(if, T_IF, KANDR) /* 18162 */ \ D(if, T_IF, COND) /* 18162 */ \
D(else, T_ELSE, KANDR) /* 9863 */ \ D(else, T_ELSE, COND) /* 9863 */ \
D(ifndef, T_IFNDEF, KANDR) /* 9675 */ \ D(ifndef, T_IFNDEF, COND) /* 9675 */ \
D(undef, T_UNDEF, KANDR) /* 4837 */ \ D(undef, T_UNDEF, KANDR) /* 4837 */ \
D(line, T_LINE, KANDR) /* 2465 */ \ 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(error, T_ERROR, STDC89) /* 475 */ \
D(pragma, T_PRAGMA, STDC89) /* 195 */ \ D(pragma, T_PRAGMA, STDC89) /* 195 */ \
D(warning, T_WARNING, EXTENSION) /* 22 - GNU */ \ D(warning, T_WARNING, EXTENSION) /* 22 - GNU */ \
...@@ -152,11 +152,12 @@ int ...@@ -152,11 +152,12 @@ int
_cpp_handle_directive (pfile) _cpp_handle_directive (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int c, i; int i;
int hash_at_bol; int hash_at_bol;
unsigned int len; unsigned int len;
U_CHAR *ident; U_CHAR *ident;
long old_written = CPP_WRITTEN (pfile); long old_written = CPP_WRITTEN (pfile);
enum cpp_token tok;
if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
{ {
...@@ -164,18 +165,25 @@ _cpp_handle_directive (pfile) ...@@ -164,18 +165,25 @@ _cpp_handle_directive (pfile)
return 0; return 0;
} }
/* -traditional directives are recognized only with the # in column 1. /* -traditional directives are recognized only with the # in column 1. */
XXX Layering violation. */ hash_at_bol = CPP_IN_COLUMN_1 (pfile);
hash_at_bol = (CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base == 1);
_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 /* # followed by a number is equivalent to #line. Do not recognize
this form in assembly language source files. Complain about this this form in assembly language source files. Complain about this
form if we're being pedantic, but not if this is regurgitated form if we're being pedantic, but not if this is regurgitated
input (preprocessed or fed back in by the C++ frontend). */ 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)) if (CPP_OPTION (pfile, lang_asm))
return 0; return 0;
...@@ -190,62 +198,86 @@ _cpp_handle_directive (pfile) ...@@ -190,62 +198,86 @@ _cpp_handle_directive (pfile)
/* If we are rescanning preprocessed input, don't obey any directives /* If we are rescanning preprocessed input, don't obey any directives
other than # nnn. */ other than # nnn. */
if (CPP_OPTION (pfile, preprocessed)) else if (CPP_OPTION (pfile, preprocessed))
return 0; return 0;
/* Now find the directive name. */ /* A line of just # becomes blank. */
CPP_PUTC (pfile, '#'); else if (tok == CPP_VSPACE)
_cpp_parse_name (pfile, GETC()); return 1;
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. */ /* A NAME token might in fact be a directive! */
else if (tok == CPP_NAME)
{
for (i = 0; i < N_DIRECTIVES; i++) for (i = 0; i < N_DIRECTIVES; i++)
{ {
if (dtable[i].length == len if (dtable[i].length == len
&& !strncmp (dtable[i].name, ident, len)) && !strncmp (dtable[i].name, ident, len))
break; goto real_directive;
} }
if (i == N_DIRECTIVES) /* Don't complain about invalid directives in assembly source,
/* # identifier, but not a legit directive. Pass onward as a we don't know where the comments are, and # may introduce
CPP_DIRECTIVE token anyway - let the consumer worry about it. */ assembler pseudo-ops. */
return 1; 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;
CPP_SET_WRITTEN (pfile, old_written); 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) 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); dtable[i].name);
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
return 1; return 1;
} }
/* Issue -pedantic warnings for extended directives. */
if (CPP_PEDANTIC (pfile) && dtable[i].origin == EXTENSION) if (CPP_PEDANTIC (pfile) && dtable[i].origin == EXTENSION)
cpp_pedwarn (pfile, "ISO C does not allow #%s", dtable[i].name); 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 (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", cpp_warning (pfile, "traditional C ignores #%s with the # indented",
dtable[i].name); 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, cpp_warning (pfile,
"traditional C rejects #%s unless the # is indented", "suggest hiding #%s from traditional C with an indented #",
dtable[i].name); dtable[i].name);
} }
if (CPP_TRADITIONAL (pfile) && !hash_at_bol) /* Unfortunately, it's necessary to scan the directive name again,
return 0; now we know we're going to consume it. FIXME. */
pfile->no_macro_expand++;
_cpp_get_directive_token (pfile);
pfile->no_macro_expand--;
CPP_SET_WRITTEN (pfile, old_written);
(*dtable[i].func) (pfile); /* 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; return 1;
} }
...@@ -282,7 +314,6 @@ get_macro_name (pfile) ...@@ -282,7 +314,6 @@ get_macro_name (pfile)
long here, len; long here, len;
here = CPP_WRITTEN (pfile); here = CPP_WRITTEN (pfile);
pfile->no_macro_expand++;
if (_cpp_get_directive_token (pfile) != CPP_NAME) if (_cpp_get_directive_token (pfile) != CPP_NAME)
{ {
cpp_error (pfile, "`#define' must be followed by an identifier"); cpp_error (pfile, "`#define' must be followed by an identifier");
...@@ -296,12 +327,10 @@ get_macro_name (pfile) ...@@ -296,12 +327,10 @@ get_macro_name (pfile)
goto invalid; goto invalid;
} }
pfile->no_macro_expand--;
return len; return len;
invalid: invalid:
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
pfile->no_macro_expand--;
return 0; return 0;
} }
...@@ -312,38 +341,52 @@ do_define (pfile) ...@@ -312,38 +341,52 @@ do_define (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
HASHNODE **slot; HASHNODE **slot;
DEFINITION *def; DEFINITION *def = 0;
long here; long here;
unsigned long hash; unsigned long hash;
int len, c; int len;
int funlike = 0; int funlike = 0, empty = 0;
U_CHAR *sym; 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); here = CPP_WRITTEN (pfile);
len = get_macro_name (pfile); len = get_macro_name (pfile);
if (len == 0) if (len == 0)
return 0; goto out;
/* Copy out the name so we can pop the token buffer. */ /* Copy out the name so we can pop the token buffer. */
len = CPP_WRITTEN (pfile) - here; len = CPP_WRITTEN (pfile) - here;
sym = (U_CHAR *) alloca (len + 1); sym = (U_CHAR *) alloca (len + 1);
memcpy (sym, pfile->token_buffer + here, len); memcpy (sym, pfile->token_buffer + here, len);
sym[len] = '\0'; sym[len] = '\0';
CPP_SET_WRITTEN (pfile, here);
/* If the next character, with no intervening whitespace, is '(', /* If the next character, with no intervening whitespace, is '(',
then this is a function-like macro. */ then this is a function-like macro.
c = PEEKC (); XXX Layering violation. */
if (c == '(') 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; funlike = 1;
else if (c != '\n' && !is_hspace (c)) else if (ADJACENT_TO_MARK (pfile))
/* Otherwise, C99 requires white space after the name. We treat it /* If this is an object-like macro, C99 requires white space after
as an object-like macro if this happens, with a warning. */ the name. */
cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym); cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym);
CPP_GOTO_MARK (pfile);
CPP_SET_WRITTEN (pfile, here);
if (! empty)
{
def = _cpp_create_definition (pfile, funlike); def = _cpp_create_definition (pfile, funlike);
if (def == 0) if (def == 0)
return 0; goto out;
}
slot = _cpp_lookup_slot (pfile, sym, len, 1, &hash); slot = _cpp_lookup_slot (pfile, sym, len, 1, &hash);
if (*slot) if (*slot)
...@@ -353,7 +396,9 @@ do_define (pfile) ...@@ -353,7 +396,9 @@ do_define (pfile)
/* Redefining a macro is ok if the definitions are the same. */ /* Redefining a macro is ok if the definitions are the same. */
if (hp->type == T_MACRO) 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. */ /* Redefining a constant is ok with -D. */
else if (hp->type == T_CONST || hp->type == T_STDC) else if (hp->type == T_CONST || hp->type == T_STDC)
ok = ! pfile->done_initializing; ok = ! pfile->done_initializing;
...@@ -379,10 +424,18 @@ do_define (pfile) ...@@ -379,10 +424,18 @@ do_define (pfile)
/* Replace the old definition. */ /* Replace the old definition. */
if (hp->type == T_MACRO) if (hp->type == T_MACRO)
_cpp_free_definition (hp->value.defn); _cpp_free_definition (hp->value.defn);
if (empty)
{
hp->type = T_EMPTY;
hp->value.defn = 0;
}
else
{
hp->type = T_MACRO; hp->type = T_MACRO;
hp->value.defn = def; hp->value.defn = def;
} }
} }
}
else else
{ {
HASHNODE *hp = _cpp_make_hashnode (sym, len, T_MACRO, hash); HASHNODE *hp = _cpp_make_hashnode (sym, len, T_MACRO, hash);
...@@ -396,6 +449,11 @@ do_define (pfile) ...@@ -396,6 +449,11 @@ do_define (pfile)
else if (CPP_OPTION (pfile, dump_macros) == dump_names) else if (CPP_OPTION (pfile, dump_macros) == dump_names)
pass_thru_directive (sym, len, pfile, T_DEFINE); 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; return 0;
} }
...@@ -774,29 +832,21 @@ do_undef (pfile) ...@@ -774,29 +832,21 @@ do_undef (pfile)
{ {
int len; int len;
HASHNODE **slot; HASHNODE **slot;
U_CHAR *buf, *name, *limit; U_CHAR *name;
int c;
long here = CPP_WRITTEN (pfile); long here = CPP_WRITTEN (pfile);
enum cpp_token token; enum cpp_token token;
_cpp_skip_hspace (pfile); pfile->no_macro_expand++;
c = GETC(); token = _cpp_get_directive_token (pfile);
if (! is_idstart(c)) pfile->no_macro_expand--;
if (token != CPP_NAME)
{ {
cpp_error (pfile, "token after #undef is not an identifier"); cpp_error (pfile, "token after #undef is not an identifier");
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
return 1; return 0;
} }
len = CPP_WRITTEN (pfile) - here;
_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';
token = _cpp_get_directive_token (pfile); token = _cpp_get_directive_token (pfile);
if (token != CPP_VSPACE) if (token != CPP_VSPACE)
...@@ -804,20 +854,23 @@ do_undef (pfile) ...@@ -804,20 +854,23 @@ do_undef (pfile)
cpp_pedwarn (pfile, "junk on line after #undef"); cpp_pedwarn (pfile, "junk on line after #undef");
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
} }
name = pfile->token_buffer + here;
CPP_SET_WRITTEN (pfile, here); CPP_SET_WRITTEN (pfile, here);
slot = _cpp_lookup_slot (pfile, name, len, 0, 0); slot = _cpp_lookup_slot (pfile, name, len, 0, 0);
if (slot) if (slot)
{ {
HASHNODE *hp = *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) if (hp->type == T_POISON)
cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name); cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name);
else 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) if (hp->type != T_MACRO)
cpp_warning (pfile, "undefining `%s'", hp->name); cpp_warning (pfile, "undefining `%s'", hp->name);
...@@ -1184,8 +1237,7 @@ do_if (pfile) ...@@ -1184,8 +1237,7 @@ do_if (pfile)
{ {
U_CHAR *control_macro = detect_if_not_defined (pfile); U_CHAR *control_macro = detect_if_not_defined (pfile);
int value = _cpp_parse_expr (pfile); int value = _cpp_parse_expr (pfile);
conditional_skip (pfile, value == 0, T_IF, control_macro); return conditional_skip (pfile, value == 0, T_IF, control_macro);
return 0;
} }
/* /*
...@@ -1214,17 +1266,11 @@ do_elif (pfile) ...@@ -1214,17 +1266,11 @@ do_elif (pfile)
} }
if (pfile->if_stack->if_succeeded) if (pfile->if_stack->if_succeeded)
skip_if_group (pfile); return skip_if_group (pfile);
else
{
if (_cpp_parse_expr (pfile) == 0) if (_cpp_parse_expr (pfile) == 0)
skip_if_group (pfile); return skip_if_group (pfile);
else
{
++pfile->if_stack->if_succeeded; /* continue processing input */ ++pfile->if_stack->if_succeeded; /* continue processing input */
_cpp_output_line_command (pfile, same_file);
}
}
return 0; return 0;
} }
...@@ -1291,8 +1337,7 @@ do_ifdef (pfile) ...@@ -1291,8 +1337,7 @@ do_ifdef (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int skip = ! parse_ifdef (pfile, dtable[T_IFDEF].name); int skip = ! parse_ifdef (pfile, dtable[T_IFDEF].name);
conditional_skip (pfile, skip, T_IFDEF, 0); return conditional_skip (pfile, skip, T_IFDEF, 0);
return 0;
} }
/* #ifndef is a tad more complex, because we need to check for a /* #ifndef is a tad more complex, because we need to check for a
...@@ -1311,8 +1356,7 @@ do_ifndef (pfile) ...@@ -1311,8 +1356,7 @@ do_ifndef (pfile)
if (start_of_file && !skip) if (start_of_file && !skip)
control_macro = (U_CHAR *) xstrdup (CPP_PWRITTEN (pfile)); control_macro = (U_CHAR *) xstrdup (CPP_PWRITTEN (pfile));
conditional_skip (pfile, skip, T_IFNDEF, control_macro); return conditional_skip (pfile, skip, T_IFNDEF, control_macro);
return 0;
} }
/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
...@@ -1320,7 +1364,7 @@ do_ifndef (pfile) ...@@ -1320,7 +1364,7 @@ do_ifndef (pfile)
CONTROL_MACRO is the macro name tested by the #ifndef. CONTROL_MACRO is the macro name tested by the #ifndef.
Otherwise, CONTROL_MACRO is 0. */ Otherwise, CONTROL_MACRO is 0. */
static void static int
conditional_skip (pfile, skip, type, control_macro) conditional_skip (pfile, skip, type, control_macro)
cpp_reader *pfile; cpp_reader *pfile;
int skip; int skip;
...@@ -1337,19 +1381,19 @@ conditional_skip (pfile, skip, type, control_macro) ...@@ -1337,19 +1381,19 @@ conditional_skip (pfile, skip, type, control_macro)
pfile->if_stack->type = type; pfile->if_stack->type = type;
if (skip != 0) { if (skip != 0)
skip_if_group (pfile); return skip_if_group (pfile);
return;
} else {
++pfile->if_stack->if_succeeded; ++pfile->if_stack->if_succeeded;
_cpp_output_line_command (pfile, same_file); return 0;
}
} }
/* Subroutine of skip_if_group. Examine one preprocessing directive and /* Subroutine of skip_if_group. Examine one preprocessing directive
return 0 if skipping should continue, 1 if it should halt. Also and return 0 if skipping should continue, or the directive number
adjusts the if_stack as appropriate. of the directive that ends the block if it should halt.
The `#' has been read, but not the identifier. */
Also adjusts the if_stack as appropriate. The `#' has been read,
but not the identifier. */
static int static int
consider_directive_while_skipping (pfile, stack) consider_directive_while_skipping (pfile, stack)
...@@ -1357,33 +1401,63 @@ consider_directive_while_skipping (pfile, stack) ...@@ -1357,33 +1401,63 @@ consider_directive_while_skipping (pfile, stack)
IF_STACK *stack; IF_STACK *stack;
{ {
long ident; long ident;
const struct directive *kt; int i, hash_at_bol;
int i;
unsigned int len; unsigned int len;
IF_STACK *temp; 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); ident = CPP_WRITTEN (pfile);
_cpp_parse_name (pfile, GETC()); if (_cpp_get_directive_token (pfile) != CPP_NAME)
return 0;
len = CPP_WRITTEN (pfile) - ident; len = CPP_WRITTEN (pfile) - ident;
CPP_SET_WRITTEN (pfile, ident);
for (i = 0; i < N_DIRECTIVES; i++) for (i = 0; i < N_DIRECTIVES; i++)
{ {
kt = &dtable[i]; if (dtable[i].length == len
if (kt->length == len && !strncmp (dtable[i].name, pfile->token_buffer + ident, len))
&& strncmp (pfile->token_buffer + ident, kt->name, kt->length) == 0) goto real_directive;
}
return 0;
real_directive:
/* If it's not a directive of interest to us, return now. */
if (dtable[i].origin != COND)
return 0;
/* First, deal with -traditional and -Wtraditional.
All COND directives are from K+R. */
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);
}
switch (i) switch (i)
{ {
default:
cpp_ice (pfile, "non COND directive in switch in c_d_w_s");
return 0;
case T_IF: case T_IF:
case T_IFDEF: case T_IFDEF:
case T_IFNDEF: case T_IFNDEF:
temp = (IF_STACK *) xmalloc (sizeof (IF_STACK)); temp = (IF_STACK *) xcalloc (1, sizeof (IF_STACK));
temp->lineno = CPP_BUFFER (pfile)->lineno;
temp->next = pfile->if_stack; temp->next = pfile->if_stack;
pfile->if_stack = temp;
temp->type = i; temp->type = i;
pfile->if_stack = temp;
return 0; return 0;
case T_ELSE: case T_ELSE:
...@@ -1392,84 +1466,69 @@ consider_directive_while_skipping (pfile, stack) ...@@ -1392,84 +1466,69 @@ consider_directive_while_skipping (pfile, stack)
/* fall through */ /* fall through */
case T_ELIF: case T_ELIF:
if (pfile->if_stack == stack) if (pfile->if_stack == stack)
return 1; return i;
else
{
pfile->if_stack->type = i; pfile->if_stack->type = i;
return 0; return 0;
}
case T_ENDIF: case T_ENDIF:
if (pfile->if_stack != stack) if (pfile->if_stack != stack)
validate_else (pfile, dtable[i].name); validate_else (pfile, dtable[i].name);
if (pfile->if_stack == stack) if (pfile->if_stack == stack)
return 1; return i;
temp = pfile->if_stack; temp = pfile->if_stack;
pfile->if_stack = temp->next; pfile->if_stack = temp->next;
free (temp); free (temp);
return 0; return 0;
default:
return 0;
}
} }
/* 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;
} }
/* skip to #endif, #else, or #elif. adjust line numbers, etc. /* Skip to #endif, #else, or #elif. Consumes the directive that
* leaves input ptr at the sharp sign found. causes it to stop, but not its argument. Returns the number of
*/ that directive, which must be passed back up to
static void _cpp_handle_directive, which will execute it. */
static int
skip_if_group (pfile) skip_if_group (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int c; enum cpp_token token;
IF_STACK *save_if_stack = pfile->if_stack; /* don't pop past here */ IF_STACK *save_if_stack = pfile->if_stack; /* don't pop past here */
const U_CHAR *beg_of_line;
long old_written; long old_written;
int ret = 0;
old_written = CPP_WRITTEN (pfile); old_written = CPP_WRITTEN (pfile);
pfile->no_macro_expand++;
CPP_OPTION (pfile, no_line_commands)++;
for (;;) for (;;)
{ {
beg_of_line = CPP_BUFFER (pfile)->cur; token = _cpp_get_directive_token (pfile);
if (! CPP_TRADITIONAL (pfile)) if (token == CPP_DIRECTIVE)
_cpp_skip_hspace (pfile);
c = GETC();
if (c == '\n')
{
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; break;
} }
else if (c == EOF)
return; /* Caller will issue error. */
FORWARD(-1); if (token != CPP_VSPACE)
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
c = GETC(); /* Only cpp_get_token knows how to advance the line number
if (c == EOF) properly. */
return; /* Caller will issue error. */ token = cpp_get_token (pfile);
else if (token == CPP_POP)
CPP_BUMP_LINE (pfile); break; /* Caller will issue error. */
}
/* Back up to the beginning of this line. Caller will process the else if (token != CPP_VSPACE)
directive. */ cpp_ice (pfile, "cpp_get_token returned %d in skip_if_group", token);
CPP_BUFFER (pfile)->cur = beg_of_line; CPP_SET_WRITTEN (pfile, old_written);
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) ...@@ -1507,12 +1566,9 @@ do_else (pfile)
} }
if (pfile->if_stack->if_succeeded) if (pfile->if_stack->if_succeeded)
skip_if_group (pfile); return skip_if_group (pfile);
else
{
++pfile->if_stack->if_succeeded; /* continue processing input */ ++pfile->if_stack->if_succeeded; /* continue processing input */
_cpp_output_line_command (pfile, same_file);
}
return 0; return 0;
} }
...@@ -1534,33 +1590,8 @@ do_endif (pfile) ...@@ -1534,33 +1590,8 @@ do_endif (pfile)
IF_STACK *temp = pfile->if_stack; IF_STACK *temp = pfile->if_stack;
pfile->if_stack = temp->next; pfile->if_stack = temp->next;
if (temp->control_macro != 0) if (temp->control_macro != 0)
{ pfile->potential_control_macro = temp->control_macro;
/* 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;
}
}
free (temp); free (temp);
_cpp_output_line_command (pfile, same_file);
} }
return 0; return 0;
} }
...@@ -1574,13 +1605,17 @@ validate_else (pfile, directive) ...@@ -1574,13 +1605,17 @@ validate_else (pfile, directive)
cpp_reader *pfile; cpp_reader *pfile;
const char *directive; const char *directive;
{ {
long old_written;
if (! CPP_PEDANTIC (pfile)) if (! CPP_PEDANTIC (pfile))
return; return;
_cpp_skip_hspace (pfile); old_written = CPP_WRITTEN (pfile);
if (PEEKC () != '\n') pfile->no_macro_expand++;
if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
cpp_pedwarn (pfile, cpp_pedwarn (pfile,
"text following `#%s' violates ANSI standard", directive); "text following `#%s' violates ANSI standard", directive);
CPP_SET_WRITTEN (pfile, old_written);
pfile->no_macro_expand--;
} }
void void
...@@ -1604,6 +1639,13 @@ _cpp_handle_eof (pfile) ...@@ -1604,6 +1639,13 @@ _cpp_handle_eof (pfile)
} }
pfile->if_stack = ifs; 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) if (CPP_BUFFER (pfile)->nominal_fname && next_buf != NULL)
{ {
/* We're about to return from an #include file. /* We're about to return from an #include file.
...@@ -1623,38 +1665,37 @@ static int ...@@ -1623,38 +1665,37 @@ static int
do_assert (pfile) do_assert (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
long old_written;
U_CHAR *sym; U_CHAR *sym;
int ret, c; int ret;
HASHNODE *base, *this; HASHNODE *base, *this;
HASHNODE **bslot, **tslot; HASHNODE **bslot, **tslot;
size_t blen, tlen; size_t blen, tlen;
unsigned long bhash, thash; unsigned long bhash, thash;
_cpp_skip_hspace (pfile); old_written = CPP_WRITTEN (pfile); /* remember where it starts */
sym = CPP_PWRITTEN (pfile); /* remember where it starts */
ret = _cpp_parse_assertion (pfile); ret = _cpp_parse_assertion (pfile);
if (ret == 0) if (ret == 0)
goto error; goto error;
else if (ret == 1) else if (ret == 1)
{ {
cpp_error (pfile, "missing token-sequence in `#assert'"); cpp_error (pfile, "missing token-sequence in #assert");
goto error; goto error;
} }
tlen = CPP_WRITTEN (pfile) - old_written;
_cpp_skip_hspace (pfile); if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
c = PEEKC();
if (c != EOF && c != '\n')
{ {
cpp_error (pfile, "junk at end of `#assert'"); cpp_error (pfile, "junk at end of #assert");
goto error; goto error;
} }
tlen = strlen (sym); sym = pfile->token_buffer + old_written;
blen = (U_CHAR *) strchr (sym, '(') - sym; blen = (U_CHAR *) strchr (sym, '(') - sym;
tslot = _cpp_lookup_slot (pfile, sym, tlen, 1, &thash); tslot = _cpp_lookup_slot (pfile, sym, tlen, 1, &thash);
if (*tslot) if (*tslot)
{ {
cpp_warning (pfile, "`%s' re-asserted", sym); cpp_warning (pfile, "%s re-asserted", sym);
goto error; goto error;
} }
...@@ -1678,12 +1719,9 @@ do_assert (pfile) ...@@ -1678,12 +1719,9 @@ do_assert (pfile)
this->value.aschain = base->value.aschain; this->value.aschain = base->value.aschain;
base->value.aschain = this; base->value.aschain = this;
pfile->limit = sym; /* Pop */
return 0;
error: error:
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
pfile->limit = sym; /* Pop */ CPP_SET_WRITTEN (pfile, old_written);
return 0; return 0;
} }
...@@ -1691,24 +1729,26 @@ static int ...@@ -1691,24 +1729,26 @@ static int
do_unassert (pfile) do_unassert (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int c, ret; int ret;
long old_written;
U_CHAR *sym; U_CHAR *sym;
long baselen, thislen; long baselen, thislen;
HASHNODE *base, *this, *next; HASHNODE *base, *this, *next;
_cpp_skip_hspace (pfile); old_written = CPP_WRITTEN (pfile);
sym = CPP_PWRITTEN (pfile); /* remember where it starts */
ret = _cpp_parse_assertion (pfile); ret = _cpp_parse_assertion (pfile);
if (ret == 0) if (ret == 0)
goto error; goto error;
thislen = CPP_WRITTEN (pfile) - old_written;
_cpp_skip_hspace (pfile); if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
c = PEEKC (); {
if (c != EOF && c != '\n') cpp_error (pfile, "junk at end of #unassert");
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) if (ret == 1)
{ {
base = _cpp_lookup (pfile, sym, thislen); base = _cpp_lookup (pfile, sym, thislen);
...@@ -1743,12 +1783,11 @@ do_unassert (pfile) ...@@ -1743,12 +1783,11 @@ do_unassert (pfile)
/* Last answer for this predicate deleted. */ /* Last answer for this predicate deleted. */
htab_remove_elt (pfile->hashtab, base); htab_remove_elt (pfile->hashtab, base);
} }
pfile->limit = sym; /* Pop */
return 0; return 0;
error: error:
_cpp_skip_rest_of_line (pfile); _cpp_skip_rest_of_line (pfile);
pfile->limit = sym; /* Pop */ CPP_SET_WRITTEN (pfile, old_written);
return 0; return 0;
} }
......
...@@ -67,8 +67,8 @@ struct cpp_buffer ...@@ -67,8 +67,8 @@ struct cpp_buffer
const unsigned char *cur; /* current position */ const unsigned char *cur; /* current position */
const unsigned char *rlimit; /* end of valid data */ const unsigned char *rlimit; /* end of valid data */
const unsigned char *buf; /* entire buffer */ 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 *line_base; /* start of current line */
const unsigned char *mark; /* Saved position for lengthy backtrack. */
struct cpp_buffer *prev; struct cpp_buffer *prev;
...@@ -84,10 +84,11 @@ struct cpp_buffer ...@@ -84,10 +84,11 @@ struct cpp_buffer
struct ihash *ihash; struct ihash *ihash;
long lineno; /* Line number at CPP_LINE_BASE. */ 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; 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. /* Value of if_stack at start of this file.
Used to prohibit unmatched #endif (etc) in an include file. */ Used to prohibit unmatched #endif (etc) in an include file. */
...@@ -347,6 +348,7 @@ struct cpp_reader ...@@ -347,6 +348,7 @@ struct cpp_reader
unsigned int max_include_len; unsigned int max_include_len;
struct if_stack *if_stack; struct if_stack *if_stack;
const unsigned char *potential_control_macro;
long lineno; long lineno;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment