Commit 9e62c811 by Zack Weinberg Committed by Zack Weinberg

cpphash.c (struct arg, [...]): Const-ify strings.

	* cpphash.c (struct arg, struct arglist): Const-ify strings.
	(warn_trad_stringify, duplicate_arg_p): New helper functions.
	(collect_expansion): Rewrite to scan over a token list.
	Remove -traditional support.
	(collect_formal_parameters): Rename to collect_params; rewrite
	to scan over a token list.
	(_cpp_create_definition): Adjust to scan a token list.
	(_cpp_macroexpand): Remove -traditional support.
	(_cpp_compare_defs): Whitespace is now canonicalized.
	(comp_def_part): Delete function.

	* cpphash.h: Update prototypes.
	* cpplex.c (init_token_list): Don't set lineno if there is no
	buffer.
	(pedantic_whitespace): New function.
	(_cpp_scan_line): Mark tokens that had hspace before.  Don't
	consume a newline.  Use pedantic_whitespace.
	(_cpp_lex_token): Remove support for -traditional macros.
	(_cpp_get_define_token): Delete.
	(_cpp_get_directive_token): Do the real work here.  Use
	pedantic_whitespace.
	(_cpp_init_input_buffer): Initialize pfile->directbuf.

	* cpplib.c (get_macro_name): Delete.
	(do_define): Read the entire line into pfile->directbuf, then
	feed the token list to _cpp_create_definition.
	* cpplib.h (HSPACE_BEFORE): new define.
	(struct cpp_reader): Add a toklist member, "directbuf".

From-SVN: r33309
parent 152897b1
2000-04-21 Zack Weinberg <zack@wolery.cumb.org>
* cpphash.c (struct arg, struct arglist): Const-ify strings.
(warn_trad_stringify, duplicate_arg_p): New helper functions.
(collect_expansion): Rewrite to scan over a token list.
Remove -traditional support.
(collect_formal_parameters): Rename to collect_params; rewrite
to scan over a token list.
(_cpp_create_definition): Adjust to scan a token list.
(_cpp_macroexpand): Remove -traditional support.
(_cpp_compare_defs): Whitespace is now canonicalized.
(comp_def_part): Delete function.
* cpphash.h: Update prototypes.
* cpplex.c (init_token_list): Don't set lineno if there is no
buffer.
(pedantic_whitespace): New function.
(_cpp_scan_line): Mark tokens that had hspace before. Don't
consume a newline. Use pedantic_whitespace.
(_cpp_lex_token): Remove support for -traditional macros.
(_cpp_get_define_token): Delete.
(_cpp_get_directive_token): Do the real work here. Use
pedantic_whitespace.
(_cpp_init_input_buffer): Initialize pfile->directbuf.
* cpplib.c (get_macro_name): Delete.
(do_define): Read the entire line into pfile->directbuf, then
feed the token list to _cpp_create_definition.
* cpplib.h (HSPACE_BEFORE): new define.
(struct cpp_reader): Add a toklist member, "directbuf".
* predict.c (estimate_probability): New heuristic: if a jump
branches around a block with no successors, predict it taken.
Disentangle control flow.
......
......@@ -272,7 +272,8 @@ extern HASHNODE **_cpp_lookup_slot PARAMS ((cpp_reader *,
enum insert_option,
unsigned long *));
extern void _cpp_free_definition PARAMS ((DEFINITION *));
extern DEFINITION *_cpp_create_definition PARAMS ((cpp_reader *, int));
extern DEFINITION *_cpp_create_definition PARAMS ((cpp_reader *,
cpp_toklist *, int));
extern void _cpp_dump_definition PARAMS ((cpp_reader *, const U_CHAR *,
long, DEFINITION *));
extern int _cpp_compare_defs PARAMS ((cpp_reader *, DEFINITION *,
......
......@@ -57,6 +57,8 @@ static void bump_column PARAMS ((cpp_printer *, unsigned int,
static void expand_name_space PARAMS ((cpp_toklist *));
static void expand_token_space PARAMS ((cpp_toklist *));
static void init_token_list PARAMS ((cpp_reader *, cpp_toklist *, int));
static void pedantic_whitespace PARAMS ((cpp_reader *, U_CHAR *,
unsigned int));
/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
......@@ -474,7 +476,8 @@ init_token_list (pfile, list, recycle)
list->namebuf = (unsigned char *) xmalloc (list->name_cap);
}
list->line = pfile->buffer->lineno;
if (pfile->buffer)
list->line = pfile->buffer->lineno;
list->dir_handler = 0;
list->dir_flags = 0;
}
......@@ -490,11 +493,13 @@ _cpp_scan_line (pfile, list)
int i, col;
long written, len;
enum cpp_ttype type;
int space_before;
init_token_list (pfile, list, 1);
written = CPP_WRITTEN (pfile);
i = 0;
space_before = 0;
for (;;)
{
col = CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base;
......@@ -502,17 +507,26 @@ _cpp_scan_line (pfile, list)
len = CPP_WRITTEN (pfile) - written;
CPP_SET_WRITTEN (pfile, written);
if (type == CPP_HSPACE)
continue;
{
if (CPP_PEDANTIC (pfile))
pedantic_whitespace (pfile, pfile->token_buffer + written, len);
space_before = 1;
continue;
}
if (list->tokens_used >= list->tokens_cap)
expand_token_space (list);
if (list->name_used + len >= list->name_cap)
expand_name_space (list);
if (type == CPP_MACRO)
type = CPP_NAME;
list->tokens_used++;
list->tokens[i].type = type;
list->tokens[i].col = col;
list->tokens[i].flags = space_before ? HSPACE_BEFORE : 0;
if (type == CPP_VSPACE)
break;
......@@ -521,8 +535,12 @@ _cpp_scan_line (pfile, list)
memcpy (list->namebuf + list->name_used, CPP_PWRITTEN (pfile), len);
list->name_used += len;
i++;
space_before = 0;
}
list->tokens[i].aux = CPP_BUFFER (pfile)->lineno + 1;
/* XXX Temporary kluge: put back the newline. */
FORWARD(-1);
}
......@@ -1034,14 +1052,8 @@ _cpp_lex_token (pfile)
For -traditional, a comment is equivalent to nothing. */
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 if (CPP_TRADITIONAL (pfile))
goto get_next;
else
{
CPP_PUTC (pfile, c);
......@@ -1060,7 +1072,7 @@ _cpp_lex_token (pfile)
return CPP_OTHER;
}
if (pfile->parsing_define_directive && ! CPP_TRADITIONAL (pfile))
if (pfile->parsing_define_directive)
{
c2 = PEEKC ();
if (c2 == '#')
......@@ -1510,6 +1522,26 @@ maybe_macroexpand (pfile, written)
return 1;
}
/* Complain about \v or \f in a preprocessing directive (constraint
violation, C99 6.10 para 5). Caller has checked CPP_PEDANTIC. */
static void
pedantic_whitespace (pfile, p, len)
cpp_reader *pfile;
U_CHAR *p;
unsigned int len;
{
while (len)
{
if (*p == '\v')
cpp_pedwarn (pfile, "vertical tab in preprocessing directive");
else if (*p == '\f')
cpp_pedwarn (pfile, "form feed in preprocessing directive");
p++;
len--;
}
}
enum cpp_ttype
cpp_get_token (pfile)
cpp_reader *pfile;
......@@ -1591,14 +1623,10 @@ cpp_get_non_space_token (pfile)
}
/* 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). */
does not consume vertical space, discards horizontal space, and
automatically pops off macro buffers. */
enum cpp_ttype
_cpp_get_define_token (pfile)
_cpp_get_directive_token (pfile)
cpp_reader *pfile;
{
long old_written;
......@@ -1620,18 +1648,10 @@ _cpp_get_define_token (pfile)
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++;
}
}
pedantic_whitespace (pfile, pfile->token_buffer + old_written,
CPP_WRITTEN (pfile) - old_written);
CPP_SET_WRITTEN (pfile, old_written);
goto get_next;
return CPP_HSPACE;
case CPP_DIRECTIVE:
......@@ -1660,23 +1680,6 @@ _cpp_get_define_token (pfile)
}
}
/* Just like _cpp_get_define_token except that it discards horizontal
whitespace. */
enum cpp_ttype
_cpp_get_directive_token (pfile)
cpp_reader *pfile;
{
int old_written = CPP_WRITTEN (pfile);
for (;;)
{
enum cpp_ttype token = _cpp_get_define_token (pfile);
if (token != CPP_COMMENT && token != CPP_HSPACE)
return token;
CPP_SET_WRITTEN (pfile, old_written);
}
}
/* Determine the current line and column. Used only by read_and_prescan. */
static U_CHAR *
find_position (start, limit, linep)
......@@ -2008,6 +2011,7 @@ _cpp_init_input_buffer (pfile)
U_CHAR *tmp;
init_chartab ();
init_token_list (pfile, &pfile->directbuf, 0);
/* Determine the appropriate size for the input buffer. Normal C
source files are smaller than eight K. */
......
......@@ -66,7 +66,6 @@ static int read_line_number PARAMS ((cpp_reader *, int *));
static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *));
static int consider_directive_while_skipping
PARAMS ((cpp_reader *, IF_STACK *));
static int get_macro_name PARAMS ((cpp_reader *));
/* Values for the flags field of the table below. KANDR and COND
directives come from traditional (K&R) C. The difference is, if we
......@@ -310,36 +309,6 @@ pass_thru_directive (buf, len, pfile, keyword)
CPP_PUTS_Q (pfile, buf, len);
}
/* Subroutine of do_define: determine the name of the macro to be
defined. */
static int
get_macro_name (pfile)
cpp_reader *pfile;
{
long here, len;
here = CPP_WRITTEN (pfile);
if (_cpp_get_directive_token (pfile) != CPP_NAME)
{
cpp_error (pfile, "`#define' must be followed by an identifier");
goto invalid;
}
len = CPP_WRITTEN (pfile) - here;
if (len == 7 && !strncmp (pfile->token_buffer + here, "defined", 7))
{
cpp_error (pfile, "`defined' is not a legal macro name");
goto invalid;
}
return len;
invalid:
_cpp_skip_rest_of_line (pfile);
return 0;
}
/* Process a #define command. */
static int
......@@ -348,47 +317,60 @@ do_define (pfile)
{
HASHNODE **slot;
DEFINITION *def = 0;
long here;
unsigned long hash;
int len;
int funlike = 0, empty = 0;
U_CHAR *sym;
enum cpp_ttype token;
cpp_toklist *list = &pfile->directbuf;
pfile->no_macro_expand++;
pfile->parsing_define_directive++;
CPP_OPTION (pfile, discard_comments)++;
here = CPP_WRITTEN (pfile);
len = get_macro_name (pfile);
if (len == 0)
goto out;
_cpp_scan_line (pfile, list);
/* 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';
/* First token on the line must be a NAME. There must be at least
one token (the VSPACE at the end). */
if (list->tokens[0].type != CPP_NAME)
{
cpp_error_with_line (pfile, list->line, list->tokens[0].col,
"#define must be followed by an identifier");
goto out;
}
sym = list->namebuf + list->tokens[0].val.name.offset;
len = list->tokens[0].val.name.len;
/* That NAME is not allowed to be "defined". (Not clear if the
standard requires this.) */
if (len == 7 && !strncmp (sym, "defined", 7))
{
cpp_error_with_line (pfile, list->line, list->tokens[0].col,
"\"defined\" is not a legal macro name");
goto out;
}
if (list->tokens_used == 2 && list->tokens[1].type == CPP_VSPACE)
empty = 0; /* Empty definition of object-like macro. */
/* If the next character, with no intervening whitespace, is '(',
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_OPEN_PAREN && ADJACENT_TO_MARK (pfile))
funlike = 1;
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);
then this is a function-like macro. Otherwise it is an object-
like macro, and C99 requires whitespace after the name
(6.10.3 para 3). */
else if (!(list->tokens[1].flags & HSPACE_BEFORE))
{
if (list->tokens[1].type == CPP_OPEN_PAREN)
funlike = 1;
else
cpp_pedwarn (pfile,
"The C standard requires whitespace after #define %.*s",
len, sym);
}
if (! empty)
{
def = _cpp_create_definition (pfile, funlike);
def = _cpp_create_definition (pfile, list, funlike);
if (def == 0)
goto out;
}
......
......@@ -135,6 +135,9 @@ struct cpp_name
unsigned int offset; /* from list->namebuf */
};
/* Per token flags. */
#define HSPACE_BEFORE (1 << 0) /* token preceded by hspace */
/* A preprocessing token.
This has been carefully packed and should occupy 16 bytes on
both 32- and 64-bit hosts. */
......@@ -146,7 +149,7 @@ struct cpp_token
#else
unsigned char type;
#endif
unsigned char flags; /* flags - not presently used */
unsigned char flags; /* flags - see above */
unsigned int aux; /* hash of a NAME, or something -
see uses in the code */
union
......@@ -435,8 +438,12 @@ struct cpp_options
struct cpp_reader
{
/* Top of buffer stack. */
cpp_buffer *buffer;
/* Token list used by get_directive_token. */
cpp_toklist directbuf;
/* A buffer used for both for cpp_get_token's output, and also internally. */
unsigned char *token_buffer;
/* Allocated size of token_buffer. CPP_RESERVE allocates space. */
......
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