Commit 041c3194 by Zack Weinberg

top level:

2000-07-03  Zack Weinberg  <zack@wolery.cumb.org>

	* fix-header.c (struct partial_proto): Remove unnecessary fields.
	(recognized_extern, recognized_function, read_scan_file):
	Update for new scheme.
	(check_protection): It's still a multiple include guard even
	if it doesn't always trigger.
	* scan-decls.c (skip_to_closing_brace, scan_decls): Update for
	new scheme.
	* scan.h: Declare struct cpp_token.  Update prototypes.

2000-07-03  Neil Booth  <neilb@earthling.net>
	    Zack Weinberg  <zack@wolery.cumb.org>

	Complete overhaul of the lexer and macro expander.

	* cpphash.c (object_defn, funct_defn, push_macro_expansion,
	arg, arglist, argdata, reflist, collect_objlike_expansion,
	collect_funlike_expansion, collect_params,
	warn_trad_stringify, trad_stringify, duplicate_arg_p, add_pat,
	unsafe_chars, macarg, compare_defs, special_symbol,
	scan_arguments, stringify, funlike_macroexpand,
	_cpp_quote_string, monthnames): Delete.
	(cpp_lookup, _cpp_free_definition, dump_funlike_macro,
	_cpp_create_definition, _cpp_dump_definition,
	dump_hash_helper): Adjust.
	(find_param, count_params, parse_define, var_args_str,
	check_macro_redefinition, save_expansion): New.

	* cpplex.c (skip_block_comment, skip_line_comment, parse_name,
        parse_string, output_line_command, trigraph_replace,
        lex_line, cpp_push_buffer, cpp_pop_buffer, cpp_output_tokens,
        cpp_scan_buffer_nooutput, cpp_scan_buffer, cpp_free_toklist,
        cpp_idcmp, _cpp_get_directive_token, _cpp_init_input_buffer,
	_cpp_skip_rest_of_line): Modify.

        (maybe_macroexpand, skip_comment, copy_comment, skip_string,
	find_position, null_warning, bump_column, expand_name_space,
	pedantic_whitespace, _cpp_output_list, _cpp_slice_toklist,
	_cpp_squeeze_toklist, _cpp_scan_until, _cpp_skip_hspace,
	_cpp_parse_name, _cpp_lex_token, cpp_get_non_space_token,
	_cpp_prescan): Delete.

	(dump_param_spelling, process_directive, lex_next,
        is_macro_disabled, stringify_arg, expand_context_stack,
        output_token, make_string_token, alloc_number_token,
        special_symbol, duplicate_token, maybe_paste_with_next,
        can_paste, prevent_macro_expansion, restore_macro_expansion,
        get_temp_token, release_temp_tokens, quote_string,
        token_names, token_spellings, _cpp_expand_name_space,
        _cpp_glue_header_name, _cpp_reserve_name_space,
        digraph_spellings, trigraph_ok, skip_whitespace, save_comment,
        placemarker_token, eof_token, cpp_context, macro_args,
        get_raw_token, parse_arg, parse_args, save_token,
        push_arg_context, push_macro_context, pop_context,
        do_pop_context, free_macro_args, _cpp_get_line,
        _cpp_run_directive): New.

	* cpplib.c (validate_else, parse_include, push_conditional,
	pass_thru_directive, read_line_number, parse_ifdef,
	detect_if_not_defined, _cpp_check_directive, do_define,
	do_undef, do_include, do_import, do_include_next, do_error,
	do_warning, do_ident, do_pragma, pragma_dispatch, gcc_pragmas,
	top_pragmas, do_pragma_gcc, do_pragma_implementation,
	do_pragma_poison, do_pragma_system_header,
	do_pragma_dependency, do_sccs, do_ifdef, do_ifndef, do_else,
	dl_elif, do_endif, _cpp_unwind_if_stack, do_assert,
	do_unassert, cpp_define, cpp_undef, cpp_assert, cpp_unassert,
	cpp_defined): Update for new scheme.
	(strtoul_for_line, get_define_node, dump_macro_name,
	_cpp_check_linemarker, _cpp_parse_assertion): New.
	(_cpp_handle_directive, do_pragma_default): Delete.

	* cpphash.h (struct predicate): Now struct answer.
	(enum spell_type, struct token_spelling, struct directive,
	directive_handler): New.
	Update prototypes.  Remove unused macros.
	* cpplib.h: Update prototypes.  Remove unused macros,
	structure definitions, and fields.

	* cpperror.c (print_containing_files, v_message): Adjust.
	* cppexp.c (parse_assertion, lex, parse_escape,
	_cpp_parse_expr): Adjust.
	* cppfiles.c (open_include_file, _cpp_execute_include,
	_cpp_compare_file_date, cpp_read_file, read_include_file):
	Adjust.
	* cppinit.c (dump_special_to_buffer): Delete.
	(append_include_chain, merge_include_chains, cpp_reader_init,
	cpp_cleanup, initialize_builtins, builtin_array, cpp_start_read,
	cpp_finish, handle_option, print_help): Adjust.
	* cppmain.c (main): Adjust.

testsuite:
2000-07-03  Zack Weinberg  <zack@wolery.cumb.org>

	* testsuite/gcc.dg/cpp/19951025-1.c: Adjust regexps.
	* testsuite/gcc.dg/cpp/19990703-1.c: Likewise.
	* testsuite/gcc.dg/cpp/20000625-1.c: Likewise.
	* testsuite/gcc.dg/cpp/20000625-2.c: Likewise.

	* testsuite/gcc.dg/cpp/macro1.c,
	testsuite/gcc.dg/cpp/paste1.c, testsuite/gcc.dg/cpp/paste2.c,
	testsuite/gcc.dg/cpp/paste3.c, testsuite/gcc.dg/cpp/paste4.c,
	testsuite/gcc.dg/cpp/strify1.c,
	testsuite/gcc.dg/cpp/strify2.c: New tests.

From-SVN: r34859
parent 4f647814
2000-07-03 Zack Weinberg <zack@wolery.cumb.org>
* fix-header.c (struct partial_proto): Remove unnecessary fields.
(recognized_extern, recognized_function, read_scan_file):
Update for new scheme.
(check_protection): It's still a multiple include guard even
if it doesn't always trigger.
* scan-decls.c (skip_to_closing_brace, scan_decls): Update for
new scheme.
* scan.h: Declare struct cpp_token. Update prototypes.
2000-07-03 Neil Booth <neilb@earthling.net>
Zack Weinberg <zack@wolery.cumb.org>
Complete overhaul of the lexer and macro expander.
* cpphash.c (object_defn, funct_defn, push_macro_expansion,
arg, arglist, argdata, reflist, collect_objlike_expansion,
collect_funlike_expansion, collect_params,
warn_trad_stringify, trad_stringify, duplicate_arg_p, add_pat,
unsafe_chars, macarg, compare_defs, special_symbol,
scan_arguments, stringify, funlike_macroexpand,
_cpp_quote_string, monthnames): Delete.
(cpp_lookup, _cpp_free_definition, dump_funlike_macro,
_cpp_create_definition, _cpp_dump_definition,
dump_hash_helper): Adjust.
(find_param, count_params, parse_define, var_args_str,
check_macro_redefinition, save_expansion): New.
* cpplex.c (skip_block_comment, skip_line_comment, parse_name,
parse_string, output_line_command, trigraph_replace,
lex_line, cpp_push_buffer, cpp_pop_buffer, cpp_output_tokens,
cpp_scan_buffer_nooutput, cpp_scan_buffer, cpp_free_toklist,
cpp_idcmp, _cpp_get_directive_token, _cpp_init_input_buffer,
_cpp_skip_rest_of_line): Modify.
(maybe_macroexpand, skip_comment, copy_comment, skip_string,
find_position, null_warning, bump_column, expand_name_space,
pedantic_whitespace, _cpp_output_list, _cpp_slice_toklist,
_cpp_squeeze_toklist, _cpp_scan_until, _cpp_skip_hspace,
_cpp_parse_name, _cpp_lex_token, cpp_get_non_space_token,
_cpp_prescan): Delete.
(dump_param_spelling, process_directive, lex_next,
is_macro_disabled, stringify_arg, expand_context_stack,
output_token, make_string_token, alloc_number_token,
special_symbol, duplicate_token, maybe_paste_with_next,
can_paste, prevent_macro_expansion, restore_macro_expansion,
get_temp_token, release_temp_tokens, quote_string,
token_names, token_spellings, _cpp_expand_name_space,
_cpp_glue_header_name, _cpp_reserve_name_space,
digraph_spellings, trigraph_ok, skip_whitespace, save_comment,
placemarker_token, eof_token, cpp_context, macro_args,
get_raw_token, parse_arg, parse_args, save_token,
push_arg_context, push_macro_context, pop_context,
do_pop_context, free_macro_args, _cpp_get_line,
_cpp_run_directive): New.
* cpplib.c (validate_else, parse_include, push_conditional,
pass_thru_directive, read_line_number, parse_ifdef,
detect_if_not_defined, _cpp_check_directive, do_define,
do_undef, do_include, do_import, do_include_next, do_error,
do_warning, do_ident, do_pragma, pragma_dispatch, gcc_pragmas,
top_pragmas, do_pragma_gcc, do_pragma_implementation,
do_pragma_poison, do_pragma_system_header,
do_pragma_dependency, do_sccs, do_ifdef, do_ifndef, do_else,
dl_elif, do_endif, _cpp_unwind_if_stack, do_assert,
do_unassert, cpp_define, cpp_undef, cpp_assert, cpp_unassert,
cpp_defined): Update for new scheme.
(strtoul_for_line, get_define_node, dump_macro_name,
_cpp_check_linemarker, _cpp_parse_assertion): New.
(_cpp_handle_directive, do_pragma_default): Delete.
* cpphash.h (struct predicate): Now struct answer.
(enum spell_type, struct token_spelling, struct directive,
directive_handler): New.
Update prototypes. Remove unused macros.
* cpplib.h: Update prototypes. Remove unused macros,
structure definitions, and fields.
* cpperror.c (print_containing_files, v_message): Adjust.
* cppexp.c (parse_assertion, lex, parse_escape,
_cpp_parse_expr): Adjust.
* cppfiles.c (open_include_file, _cpp_execute_include,
_cpp_compare_file_date, cpp_read_file, read_include_file):
Adjust.
* cppinit.c (dump_special_to_buffer): Delete.
(append_include_chain, merge_include_chains, cpp_reader_init,
cpp_cleanup, initialize_builtins, builtin_array, cpp_start_read,
cpp_finish, handle_option, print_help): Adjust.
* cppmain.c (main): Adjust.
2000-07-03 Zack Weinberg <zack@wolery.cumb.org>
* cppspec.c (lang_specific_driver): Use double quotes in error
message.
......
......@@ -58,23 +58,27 @@ print_containing_files (pfile, ip)
if (first)
{
first = 0;
/* N.B. The current line in each outer source file is one
greater than the line of the #include, so we must
subtract one to correct for that. */
fprintf (stderr, _("In file included from %s:%u"),
ip->nominal_fname, CPP_BUF_LINE (ip));
ip->nominal_fname, CPP_BUF_LINE (ip) - 1);
}
else
/* Translators note: this message is used in conjunction
with "In file included from %s:%ld" and some other
tricks. We want something like this:
In file included from sys/select.h:123,
from sys/types.h:234,
from userfile.c:31:
bits/select.h:45: <error message here>
| In file included from sys/select.h:123,
| from sys/types.h:234,
| from userfile.c:31:
| bits/select.h:45: <error message here>
with all the "from"s lined up.
The trailing comma is at the beginning of this message,
and the trailing colon is not translated. */
fprintf (stderr, _(",\n from %s:%u"),
ip->nominal_fname, CPP_BUF_LINE (ip));
ip->nominal_fname, CPP_BUF_LINE (ip) - 1);
}
if (first == 0)
fputs (":\n", stderr);
......@@ -111,17 +115,14 @@ v_message (pfile, is_error, file, line, col, msg, ap)
const char *msg;
va_list ap;
{
cpp_buffer *ip = cpp_file_buffer (pfile);
cpp_buffer *ip = CPP_BUFFER (pfile);
if (ip)
{
if (file == NULL)
file = ip->nominal_fname;
if (line == 0)
{
line = CPP_BUF_LINE (ip);
col = CPP_BUF_COL (ip);
}
line = _cpp_get_line (pfile, &col);
print_containing_files (pfile, ip);
print_file_and_line (file, line,
CPP_OPTION (pfile, show_column) ? col : 0);
......@@ -132,8 +133,12 @@ v_message (pfile, is_error, file, line, col, msg, ap)
switch (is_error)
{
case 0:
fprintf (stderr, _("warning: "));
break;
if (! CPP_OPTION (pfile, warnings_are_errors))
{
fprintf (stderr, _("warning: "));
break;
}
/* else fall through */
case 1:
if (pfile->errors < CPP_FATAL_LIMIT)
pfile->errors++;
......
......@@ -394,74 +394,22 @@ parse_assertion (pfile)
cpp_reader *pfile;
{
struct operation op;
struct answer *answer;
cpp_hashnode *hp;
struct predicate *pred;
cpp_toklist query;
enum cpp_ttype type;
U_CHAR *tok;
size_t len;
unsigned int old_written;
int specific = 0;
old_written = CPP_WRITTEN (pfile);
CPP_PUTC (pfile, '#');
pfile->no_macro_expand++;
type = _cpp_get_directive_token (pfile);
if (type == CPP_VSPACE)
SYNTAX_ERROR ("assertion without predicate");
else if (type != CPP_NAME)
SYNTAX_ERROR ("assertion predicate is not an identifier");
tok = pfile->token_buffer + old_written;
len = CPP_WRITTEN (pfile) - old_written;
hp = cpp_lookup (pfile, tok, len);
/* Look ahead for an open paren. */
_cpp_skip_hspace (pfile);
if (CPP_BUF_PEEK (CPP_BUFFER (pfile)) == '(')
op.op = ERROR;
hp = _cpp_parse_assertion (pfile, &answer);
if (hp)
{
if (_cpp_get_directive_token (pfile) != CPP_OPEN_PAREN)
CPP_ICE ("impossible token, expecting ( in parse_assertion");
_cpp_init_toklist (&query, NO_DUMMY_TOKEN);
specific = 1;
if (_cpp_scan_until (pfile, &query, CPP_CLOSE_PAREN) != CPP_CLOSE_PAREN)
SYNTAX_ERROR ("missing close paren on assertion answer");
if (_cpp_get_directive_token (pfile) != CPP_CLOSE_PAREN)
CPP_ICE ("impossible token, expecting ) in parse_assertion");
}
/* If we get here, the syntax is valid. */
op.op = INT;
op.value = (hp->type == T_ASSERTION &&
(answer == 0 || *find_answer (hp, &answer->list) != 0));
/* If we get here, the syntax is valid. */
op.op = INT;
op.value = 0;
/* Has this predicate been asserted at all? */
if (hp->type == T_ASSERTION)
{
if (specific)
{
for (pred = hp->value.pred; pred; pred = pred->next)
if (_cpp_equiv_toklists (&query, &pred->answer))
{
op.value = 1;
break;
}
_cpp_free_toklist (&query);
}
else
op.value = 1;
if (answer)
FREE_ANSWER (answer);
}
out:
pfile->no_macro_expand--;
CPP_SET_WRITTEN (pfile, old_written);
return op;
syntax_error:
if (specific)
_cpp_free_toklist (&query);
op.op = ERROR;
goto out;
}
struct token
......@@ -480,8 +428,6 @@ static const struct token tokentab2[] =
{"!=", NOTEQUAL},
{"<=", LEQ},
{">=", GEQ},
{"++", ERROR},
{"--", ERROR},
{NULL, ERROR}
};
......@@ -496,16 +442,20 @@ lex (pfile, skip_evaluation)
enum cpp_ttype token;
struct operation op;
U_CHAR *tok_start, *tok_end;
long old_written;
long old_written = CPP_WRITTEN (pfile);
old_written = CPP_WRITTEN (pfile);
retry:
token = _cpp_get_directive_token (pfile);
tok_start = pfile->token_buffer + old_written;
tok_end = CPP_PWRITTEN (pfile);
CPP_SET_WRITTEN (pfile, old_written);
switch (token)
{
case CPP_PLACEMARKER:
CPP_SET_WRITTEN (pfile, old_written);
goto retry;
case CPP_EOF: /* Should not happen ... */
case CPP_VSPACE:
op.op = 0;
......@@ -524,6 +474,7 @@ lex (pfile, skip_evaluation)
return parse_charconst (pfile, tok_start, tok_end);
case CPP_NAME:
/* FIXME: could this not overflow the tok_start buffer? */
if (!ustrncmp (tok_start, U"defined", 7))
return parse_defined (pfile);
......@@ -539,7 +490,16 @@ lex (pfile, skip_evaluation)
case CPP_HASH:
return parse_assertion (pfile);
case CPP_OTHER:
case CPP_AND_AND: op.op = ANDAND; return op;
case CPP_OR_OR: op.op = OROR; return op;
case CPP_LSHIFT: op.op = LSH; return op;
case CPP_RSHIFT: op.op = RSH; return op;
case CPP_EQ_EQ: op.op = EQUAL; return op;
case CPP_NOT_EQ: op.op = NOTEQUAL; return op;
case CPP_LESS_EQ: op.op = LEQ; return op;
case CPP_GREATER_EQ:op.op = GEQ; return op;
default:
/* See if it is a special token of length 2. */
if (tok_start + 2 == tok_end)
{
......@@ -553,8 +513,6 @@ lex (pfile, skip_evaluation)
op.op = toktab->token;
return op;
}
/* fall through */
default:
op.op = *tok_start;
return op;
}
......@@ -612,7 +570,7 @@ parse_escape (pfile, string_ptr, result_mask)
case 'e':
case 'E':
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, '\\%c'", c);
cpp_pedwarn (pfile, "non-ISO-standard escape sequence, '\\%c'", c);
return TARGET_ESC;
case 'f':
return TARGET_FF;
......@@ -844,9 +802,7 @@ _cpp_parse_expr (pfile)
char buff[5];
/* Save parser state and set it to something sane. */
int save_only_seen_white = pfile->only_seen_white;
int save_skipping = pfile->skipping;
pfile->only_seen_white = 0;
pfile->skipping = 0;
/* We've finished when we try to reduce this. */
......@@ -875,7 +831,8 @@ _cpp_parse_expr (pfile)
case ERROR:
goto syntax_error;
default:
SYNTAX_ERROR ("invalid character in #if");
SYNTAX_ERROR2 ("invalid character '%s' in #if",
op_to_str (op.op, buff));
push_immediate:
case INT:
......@@ -1168,7 +1125,6 @@ _cpp_parse_expr (pfile)
if (stack != init_stack)
free (stack);
CPP_SET_WRITTEN (pfile, old_written);
pfile->only_seen_white = save_only_seen_white;
pfile->skipping = save_skipping;
return result;
}
......@@ -180,7 +180,7 @@ open_include_file (pfile, filename)
#ifdef EACCES
if (errno == EACCES)
{
cpp_error (pfile, "included file `%s' exists but is not readable",
cpp_error (pfile, "included file \"%s\" exists but is not readable",
filename);
}
#endif
......@@ -360,16 +360,16 @@ cpp_make_system_header (pfile, pbuf, flag)
#define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
void
_cpp_execute_include (pfile, f, len, no_reinclude, search_start)
_cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
cpp_reader *pfile;
U_CHAR *f;
const U_CHAR *f;
unsigned int len;
int no_reinclude;
struct file_name_list *search_start;
int angle_brackets;
{
struct include_file *inc;
char *fname = (char *)f;
int angle_brackets = fname[0] == '<';
char *fname;
if (!search_start)
{
......@@ -387,9 +387,8 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
return;
}
/* Remove quote marks. */
fname++;
len -= 2;
fname = alloca (len + 1);
memcpy (fname, f, len);
fname[len] = '\0';
inc = find_include_file (pfile, fname, search_start);
......@@ -470,32 +469,27 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
if F cannot be located or dated, 1, if it is newer and 0 if older. */
int
_cpp_compare_file_date (pfile, f, len, search_start)
_cpp_compare_file_date (pfile, f, len, angle_brackets)
cpp_reader *pfile;
U_CHAR *f;
const U_CHAR *f;
unsigned int len;
struct file_name_list *search_start;
int angle_brackets;
{
char *fname = (char *)f;
int angle_brackets = fname[0] == '<';
char *fname;
struct file_name_list *search_start;
struct include_file *inc;
struct include_file *current_include = cpp_file_buffer (pfile)->inc;
struct include_file *current_include = CPP_BUFFER (pfile)->inc;
if (!search_start)
{
if (angle_brackets)
search_start = CPP_OPTION (pfile, bracket_include);
else if (CPP_OPTION (pfile, ignore_srcdir))
search_start = CPP_OPTION (pfile, quote_include);
else
search_start = CPP_BUFFER (pfile)->actual_dir;
}
if (angle_brackets)
search_start = CPP_OPTION (pfile, bracket_include);
else if (CPP_OPTION (pfile, ignore_srcdir))
search_start = CPP_OPTION (pfile, quote_include);
else
search_start = CPP_BUFFER (pfile)->actual_dir;
/* Remove quote marks. */
fname++;
len -= 2;
fname = alloca (len + 1);
memcpy (fname, f, len);
fname[len] = '\0';
inc = find_include_file (pfile, fname, search_start);
if (!inc)
......@@ -534,6 +528,12 @@ cpp_read_file (pfile, fname)
f = open_include_file (pfile, fname);
if (f == NULL)
{
cpp_error_from_errno (pfile, fname);
return 0;
}
return read_include_file (pfile, f);
}
......@@ -550,12 +550,17 @@ read_include_file (pfile, inc)
cpp_buffer *fp;
int fd = inc->fd;
/* Ensures we dump our current line before entering an include file. */
if (CPP_BUFFER (pfile) && pfile->printer)
cpp_output_tokens (pfile, pfile->printer,
CPP_BUF_LINE (CPP_BUFFER (pfile)));
fp = cpp_push_buffer (pfile, NULL, 0);
if (fp == 0)
goto push_fail;
if (fstat (fd, &st) < 0)
if (fd < 0 || fstat (fd, &st) < 0)
goto perror_fail;
inc->date = st.st_mtime;
......@@ -622,9 +627,6 @@ read_include_file (pfile, inc)
if (length == 0)
inc->cmacro = NEVER_REREAD;
else
/* Temporary - I hope. */
length = _cpp_prescan (pfile, fp, length);
fp->rlimit = fp->buf + length;
fp->cur = fp->buf;
......@@ -637,13 +639,13 @@ read_include_file (pfile, inc)
fp->actual_dir = actual_directory (pfile, inc->name);
pfile->input_stack_listing_current = 0;
pfile->only_seen_white = 2;
return 1;
perror_fail:
cpp_error_from_errno (pfile, inc->name);
/* Do not try to read this file again. */
close (fd);
if (fd != -1)
close (fd);
inc->fd = -1;
inc->cmacro = NEVER_REREAD;
fail:
......
......@@ -25,11 +25,60 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
typedef unsigned char U_CHAR;
#define U (const U_CHAR *) /* Intended use: U"string" */
/* Structure used for assertion predicates. */
struct predicate
/* Order here matters. Those beyond SPELL_NONE store their spelling
in the token list, and it's length in the token->val.name.len. */
enum spell_type
{
struct predicate *next;
struct cpp_toklist answer;
SPELL_OPERATOR = 0,
SPELL_CHAR,
SPELL_NONE,
SPELL_IDENT,
SPELL_STRING
};
struct token_spelling
{
ENUM_BITFIELD(spell_type) type : CHAR_BIT;
const U_CHAR *spelling;
};
extern const struct token_spelling token_spellings[];
/* Chained list of answers to an assertion. */
struct answer
{
struct answer *next;
cpp_toklist list;
};
#define FREE_ANSWER(answer) do {_cpp_free_toklist (&answer->list); \
free (answer); } while (0)
/* Values for the origin field of struct directive. KANDR directives
come from traditional (K&R) C. STDC89 directives come from the
1989 C standard. EXTENSION directives are extensions. */
#define KANDR 0
#define STDC89 1
#define EXTENSION 2
/* Values for the flags field of struct directive. COND indicates a
conditional. EXPAND means that macros are to be expanded on the
directive line. INCL means to treat "..." and <...> as
q-char-sequence and h-char-sequence respectively. COMMENTS means
preserve comments in the directive if -C. */
#define COND (1 << 0)
#define EXPAND (1 << 1)
#define INCL (1 << 2)
#define COMMENTS (1 << 3)
/* Defines one #-directive, including how to handle it. */
typedef int (*directive_handler) PARAMS ((cpp_reader *));
struct directive
{
directive_handler handler; /* Function to handle directive. */
const U_CHAR *name; /* Name of directive. */
unsigned short length; /* Length of name. */
unsigned char origin; /* Origin of directive. */
unsigned char flags; /* Flags describing this directive. */
};
/* List of directories to look for include files in. */
......@@ -105,12 +154,6 @@ 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)
/* Make sure PFILE->token_buffer has space for at least N more characters. */
#define CPP_RESERVE(PFILE, N) \
(CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
......@@ -127,53 +170,15 @@ extern unsigned char _cpp_IStable[256];
/* Append character CH to PFILE's output buffer. Make space if need be. */
#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
/* Advance the current line by one. */
#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
(PBUF)->line_base = (PBUF)->cur)
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
#define CPP_BUMP_BUFFER_LINE_CUR(PBUF, CUR) ((PBUF)->lineno++,\
(PBUF)->line_base = CUR)
#define CPP_BUMP_LINE_CUR(PFILE, CUR) \
CPP_BUMP_BUFFER_LINE_CUR(CPP_BUFFER(PFILE), CUR)
#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_IN_SYSTEM_HEADER(PFILE) (cpp_file_buffer (PFILE)->inc->sysp)
#define CPP_IN_SYSTEM_HEADER(PFILE) (CPP_BUFFER (PFILE)->inc->sysp)
#define CPP_PEDANTIC(PF) \
(CPP_OPTION (PF, pedantic) && !CPP_IN_SYSTEM_HEADER (PF))
#define CPP_WTRADITIONAL(PF) \
(CPP_OPTION (PF, warn_traditional) && !CPP_IN_SYSTEM_HEADER (PF))
/* 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)->macro != NULL)
/* Remember the current position of PFILE so it may be returned to
after looking ahead a bit.
Note that when you set a mark, you _must_ return to that mark. You
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)
#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 != 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)
/* Flags for _cpp_init_toklist. */
#define DUMMY_TOKEN 0
#define NO_DUMMY_TOKEN 1
......@@ -181,22 +186,19 @@ extern unsigned char _cpp_IStable[256];
/* In cpphash.c */
extern unsigned int _cpp_calc_hash PARAMS ((const U_CHAR *, size_t));
extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_toklist *,
cpp_hashnode *));
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
extern void _cpp_dump_definition PARAMS ((cpp_reader *, cpp_hashnode *));
extern void _cpp_quote_string PARAMS ((cpp_reader *, const U_CHAR *));
extern void _cpp_macroexpand PARAMS ((cpp_reader *, cpp_hashnode *));
extern void _cpp_init_macro_hash PARAMS ((cpp_reader *));
extern void _cpp_dump_macro_hash PARAMS ((cpp_reader *));
/* In cppfiles.c */
extern void _cpp_simplify_pathname PARAMS ((char *));
extern void _cpp_execute_include PARAMS ((cpp_reader *, U_CHAR *,
extern void _cpp_execute_include PARAMS ((cpp_reader *, const U_CHAR *,
unsigned int, int,
struct file_name_list *));
extern int _cpp_compare_file_date PARAMS ((cpp_reader *, U_CHAR *,
unsigned int,
struct file_name_list *));
struct file_name_list *,
int));
extern int _cpp_compare_file_date PARAMS ((cpp_reader *, const U_CHAR *,
unsigned int, int));
extern void _cpp_init_include_table PARAMS ((cpp_reader *));
extern const char *_cpp_fake_include PARAMS ((cpp_reader *, const char *));
......@@ -204,40 +206,46 @@ extern const char *_cpp_fake_include PARAMS ((cpp_reader *, const char *));
extern int _cpp_parse_expr PARAMS ((cpp_reader *));
/* In cpplex.c */
extern void _cpp_parse_name PARAMS ((cpp_reader *, int));
extern void _cpp_skip_rest_of_line PARAMS ((cpp_reader *));
extern void _cpp_skip_hspace PARAMS ((cpp_reader *));
extern void _cpp_expand_to_buffer PARAMS ((cpp_reader *,
const unsigned char *, int));
extern int _cpp_parse_assertion PARAMS ((cpp_reader *));
extern enum cpp_ttype _cpp_lex_token PARAMS ((cpp_reader *));
extern ssize_t _cpp_prescan PARAMS ((cpp_reader *, cpp_buffer *,
ssize_t));
extern void _cpp_free_temp_tokens PARAMS ((cpp_reader *));
extern void _cpp_init_input_buffer PARAMS ((cpp_reader *));
extern void _cpp_grow_token_buffer PARAMS ((cpp_reader *, long));
extern enum cpp_ttype _cpp_get_directive_token
PARAMS ((cpp_reader *));
extern enum cpp_ttype _cpp_get_define_token
PARAMS ((cpp_reader *));
extern enum cpp_ttype _cpp_scan_until PARAMS ((cpp_reader *, cpp_toklist *,
enum cpp_ttype));
extern void _cpp_init_toklist PARAMS ((cpp_toklist *, int));
extern void _cpp_clear_toklist PARAMS ((cpp_toklist *));
extern void _cpp_free_toklist PARAMS ((cpp_toklist *));
extern void _cpp_slice_toklist PARAMS ((cpp_toklist *,
const cpp_token *,
const cpp_token *));
extern void _cpp_squeeze_toklist PARAMS ((cpp_toklist *));
extern void _cpp_free_toklist PARAMS ((const cpp_toklist *));
extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
const cpp_token *));
extern int _cpp_equiv_toklists PARAMS ((const cpp_toklist *,
const cpp_toklist *));
extern void _cpp_expand_token_space PARAMS ((cpp_toklist *, unsigned int));
extern void _cpp_reserve_name_space PARAMS ((cpp_toklist *, unsigned int));
extern void _cpp_expand_name_space PARAMS ((cpp_toklist *, unsigned int));
extern void _cpp_dump_list PARAMS ((cpp_reader *,
const cpp_toklist *,
const cpp_token *, int));
extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
const cpp_token *));
extern void _cpp_run_directive PARAMS ((cpp_reader *,
const struct directive *,
const char *, size_t));
extern unsigned int _cpp_get_line PARAMS ((cpp_reader *,
unsigned int *));
extern const cpp_token *_cpp_get_raw_token PARAMS ((cpp_reader *));
extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token*));
extern const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *));
/* In cpplib.c */
extern int _cpp_handle_directive PARAMS ((cpp_reader *));
extern const struct directive *_cpp_check_directive
PARAMS ((cpp_reader *, const cpp_token *, int));
extern const struct directive *_cpp_check_linemarker
PARAMS ((cpp_reader *, const cpp_token *, int));
extern void _cpp_unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *));
extern void _cpp_check_directive PARAMS ((cpp_toklist *, cpp_token *));
extern cpp_hashnode * _cpp_parse_assertion PARAMS ((cpp_reader *,
struct answer **));
extern struct answer** find_answer PARAMS ((cpp_hashnode *,
const cpp_toklist *));
/* Utility routines and macros. */
#define xnew(T) (T *) xmalloc (sizeof(T))
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -68,6 +68,7 @@ main (argc, argv)
print = cpp_printer_init (pfile, &parse_out);
if (! print)
return (FATAL_EXIT_CODE);
pfile->printer = print;
if (! cpp_start_read (pfile, print, CPP_OPTION (pfile, in_fname)))
return (FATAL_EXIT_CODE);
......
......@@ -432,8 +432,6 @@ write_lbrac ()
struct partial_proto
{
struct partial_proto *next;
char *fname; /* name of function */
char *rtype; /* return type */
struct fn_decl *fn;
int line_seen;
};
......@@ -497,15 +495,13 @@ recognized_macro (fname)
}
void
recognized_extern (name, name_length, type, type_length)
const char *name;
const char *type ATTRIBUTE_UNUSED;
int name_length, type_length ATTRIBUTE_UNUSED;
recognized_extern (name)
const cpp_token *name;
{
switch (special_file_handling)
{
case errno_h:
if (name_length == 5 && strncmp (name, "errno", 5) == 0 && !seen_errno)
if (!cpp_idcmp (name->val.name.text, name->val.name.len, "errno"))
seen_errno = 1, required_other--;
break;
......@@ -515,25 +511,17 @@ recognized_extern (name, name_length, type, type_length)
}
/* Called by scan_decls if it saw a function definition for a function
named FNAME, with return type RTYPE, and argument list ARGS,
in source file FILE_SEEN on line LINE_SEEN.
KIND is 'I' for an inline function;
'F' if a normal function declaration preceded by 'extern "C"'
(or nested inside 'extern "C"' braces); or
named FNAME, in source file FILE_SEEN on line LINE_SEEN. KIND is
'I' for an inline function; 'F' if a normal function declaration
preceded by 'extern "C"' (or nested inside 'extern "C"' braces); or
'f' for other function declarations. */
void
recognized_function (fname, fname_length,
kind, rtype, rtype_length,
have_arg_list, file_seen, line_seen)
const char *fname;
int fname_length;
recognized_function (fname, kind, have_arg_list, file_seen)
const cpp_token *fname;
int kind; /* One of 'f' 'F' or 'I' */
const char *rtype;
int rtype_length;
int have_arg_list;
const char *file_seen;
int line_seen;
{
struct partial_proto *partial;
int i;
......@@ -543,7 +531,8 @@ recognized_function (fname, fname_length,
missing_extern_C_count++;
#endif
fn = lookup_std_proto (fname, fname_length);
fn = lookup_std_proto ((const char *)fname->val.name.text,
fname->val.name.len);
/* Remove the function from the list of required function. */
if (fn)
......@@ -577,12 +566,7 @@ recognized_function (fname, fname_length,
partial_count++;
partial = (struct partial_proto *)
obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
partial->fname = obstack_alloc (&scan_file_obstack, fname_length + 1);
bcopy (fname, partial->fname, fname_length);
partial->fname[fname_length] = 0;
partial->rtype = obstack_alloc (&scan_file_obstack, rtype_length + 1);
sprintf (partial->rtype, "%.*s", rtype_length, rtype);
partial->line_seen = line_seen;
partial->line_seen = fname->line;
partial->fn = fn;
fn->partial = partial;
partial->next = partial_proto_list;
......@@ -590,7 +574,7 @@ recognized_function (fname, fname_length,
if (verbose)
{
fprintf (stderr, "(%s: %s non-prototype function declaration.)\n",
inc_filename, partial->fname);
inc_filename, fn->fname);
}
}
......@@ -646,19 +630,12 @@ read_scan_file (in_fname, argc, argv)
for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++)
check_macro_names (&scan_in, cur_symbols->names);
if (verbose && (scan_in.errors + warnings) > 0)
fprintf (stderr, "(%s: %d errors and %d warnings from cpp)\n",
inc_filename, scan_in.errors, warnings);
if (scan_in.errors)
exit (SUCCESS_EXIT_CODE);
/* Traditionally, getc and putc are defined in terms of _filbuf and _flsbuf.
If so, those functions are also required. */
if (special_file_handling == stdio_h
&& (fn = lookup_std_proto ("_filbuf", 7)) != NULL)
{
static const unsigned char getchar_call[] = "getchar();";
int old_written = CPP_WRITTEN (&scan_in);
int seen_filbuf = 0;
cpp_buffer *buf = CPP_BUFFER (&scan_in);
if (cpp_push_buffer (&scan_in, getchar_call,
......@@ -668,14 +645,17 @@ read_scan_file (in_fname, argc, argv)
/* Scan the macro expansion of "getchar();". */
for (;;)
{
enum cpp_ttype token = cpp_get_token (&scan_in);
int length = CPP_WRITTEN (&scan_in) - old_written;
unsigned char *id = scan_in.token_buffer + old_written;
CPP_SET_WRITTEN (&scan_in, old_written);
if (token == CPP_EOF && CPP_BUFFER (&scan_in) == buf)
break;
if (token == CPP_NAME && cpp_idcmp (id, length, "_filbuf") == 0)
const cpp_token *t = cpp_get_token (&scan_in);
if (t->type == CPP_EOF)
{
cpp_pop_buffer (&scan_in);
if (CPP_BUFFER (&scan_in) == buf)
break;
}
else if (t->type == CPP_NAME && cpp_idcmp (t->val.name.text,
t->val.name.len,
"_filbuf") == 0)
seen_filbuf++;
}
if (seen_filbuf)
......@@ -1030,8 +1010,6 @@ check_protection (ifndef_line, endif_line)
}
else if (!strcmp (buf.base, "define"))
{
if (if_nesting != 1)
goto skip_to_eol;
c = inf_skip_spaces (c);
c = inf_scan_ident (&buf, c);
if (buf.base[0] > 0 && strcmp (buf.base, protect_name) == 0)
......
......@@ -45,7 +45,7 @@ skip_to_closing_brace (pfile)
int nesting = 1;
for (;;)
{
enum cpp_ttype token = cpp_get_token (pfile);
enum cpp_ttype token = cpp_get_token (pfile)->type;
if (token == CPP_EOF)
break;
if (token == CPP_OPEN_BRACE)
......@@ -84,24 +84,17 @@ scan_decls (pfile, argc, argv)
char **argv ATTRIBUTE_UNUSED;
{
int saw_extern, saw_inline;
int start_written;
/* If declarator_start is non-zero, it marks the start of the current
declarator. If it is zero, we are either still parsing the
decl-specs, or prev_id_start marks the start of the declarator. */
int declarator_start;
int prev_id_start, prev_id_end = 0;
enum cpp_ttype token;
const cpp_token *prev_id;
const cpp_token *token;
new_statement:
CPP_SET_WRITTEN (pfile, 0);
start_written = 0;
token = cpp_get_token (pfile);
handle_statement:
current_extern_C = 0;
saw_extern = 0;
saw_inline = 0;
if (token == CPP_OPEN_BRACE)
if (token->type == CPP_OPEN_BRACE)
{
/* Pop an 'extern "C"' nesting level, if appropriate. */
if (extern_C_braces_length
......@@ -110,120 +103,112 @@ scan_decls (pfile, argc, argv)
brace_nesting--;
goto new_statement;
}
if (token == CPP_OPEN_BRACE)
if (token->type == CPP_OPEN_BRACE)
{
brace_nesting++;
goto new_statement;
}
if (token == CPP_EOF)
if (token->type == CPP_EOF)
{
cpp_pop_buffer (pfile);
if (CPP_BUFFER (pfile) == NULL)
return 0;
else
goto new_statement;
goto new_statement;
}
if (token == CPP_SEMICOLON)
if (token->type == CPP_SEMICOLON)
goto new_statement;
if (token != CPP_NAME)
if (token->type != CPP_NAME)
goto new_statement;
prev_id_start = 0;
declarator_start = 0;
prev_id = 0;
for (;;)
{
switch (token)
switch (token->type)
{
default:
goto handle_statement;
case CPP_MULT:
case CPP_AND:
case CPP_PLACEMARKER:
/* skip */
break;
case CPP_COMMA:
case CPP_SEMICOLON:
if (prev_id && saw_extern)
{
recognized_extern (prev_id);
}
if (token->type == CPP_COMMA)
break;
/* ... fall through ... */
case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE:
goto new_statement;
case CPP_EOF:
cpp_pop_buffer (pfile);
if (CPP_BUFFER (pfile) == NULL)
return 0;
break;
case CPP_OPEN_PAREN:
/* Looks like this is the start of a formal parameter list. */
if (prev_id_start)
if (prev_id)
{
int nesting = 1;
int have_arg_list = 0;
cpp_buffer *fbuf = cpp_file_buffer (pfile);
unsigned int func_lineno = CPP_BUF_LINE (fbuf);
for (;;)
{
token = cpp_get_token (pfile);
if (token == CPP_OPEN_PAREN)
if (token->type == CPP_OPEN_PAREN)
nesting++;
else if (token == CPP_CLOSE_PAREN)
else if (token->type == CPP_CLOSE_PAREN)
{
nesting--;
if (nesting == 0)
break;
}
else if (token == CPP_EOF)
else if (token->type == CPP_EOF)
break;
else if (token == CPP_NAME || token == CPP_ELLIPSIS)
else if (token->type == CPP_NAME
|| token->type == CPP_ELLIPSIS)
have_arg_list = 1;
}
recognized_function (pfile->token_buffer + prev_id_start,
prev_id_end - prev_id_start,
recognized_function (prev_id,
(saw_inline ? 'I'
: in_extern_C_brace || current_extern_C
? 'F' : 'f'),
pfile->token_buffer, prev_id_start,
have_arg_list,
fbuf->nominal_fname, func_lineno);
token = cpp_get_non_space_token (pfile);
if (token == CPP_OPEN_BRACE)
? 'F' : 'f'), have_arg_list,
CPP_BUFFER (pfile)->nominal_fname);
token = cpp_get_token (pfile);
if (token->type == CPP_OPEN_BRACE)
{
/* skip body of (normally) inline function */
skip_to_closing_brace (pfile);
goto new_statement;
}
goto maybe_handle_comma;
if (token->type == CPP_SEMICOLON)
goto new_statement;
}
break;
case CPP_OTHER:
if (CPP_WRITTEN (pfile) == (size_t) start_written + 1
&& (CPP_PWRITTEN (pfile)[-1] == '*'
|| CPP_PWRITTEN (pfile)[-1] == '&'))
declarator_start = start_written;
else
goto handle_statement;
break;
case CPP_COMMA:
case CPP_SEMICOLON:
if (prev_id_start && saw_extern)
{
recognized_extern (pfile->token_buffer + prev_id_start,
prev_id_end - prev_id_start,
pfile->token_buffer,
prev_id_start);
}
/* ... fall through ... */
maybe_handle_comma:
if (token != CPP_COMMA)
goto new_statement;
/* Handle multiple declarators in a single declaration,
as in: extern char *strcpy (), *strcat (), ... ; */
if (declarator_start == 0)
declarator_start = prev_id_start;
CPP_SET_WRITTEN (pfile, declarator_start);
break;
case CPP_NAME:
/* "inline" and "extern" are recognized but skipped */
if (!cpp_idcmp (pfile->token_buffer,
CPP_WRITTEN (pfile), "inline"))
if (!cpp_idcmp (token->val.name.text, token->val.name.len, "inline"))
{
saw_inline = 1;
CPP_SET_WRITTEN (pfile, start_written);
}
else if (!cpp_idcmp (pfile->token_buffer,
CPP_WRITTEN (pfile), "extern"))
else if (!cpp_idcmp (token->val.name.text,
token->val.name.len, "extern"))
{
saw_extern = 1;
CPP_SET_WRITTEN (pfile, start_written);
token = cpp_get_non_space_token (pfile);
if (token == CPP_STRING
&& strcmp (pfile->token_buffer, "\"C\"") == 0)
token = cpp_get_token (pfile);
if (token->type == CPP_STRING
&& !cpp_idcmp (token->val.name.text,
token->val.name.len, "C"))
{
CPP_SET_WRITTEN (pfile, start_written);
current_extern_C = 1;
token = cpp_get_non_space_token (pfile);
if (token == CPP_OPEN_BRACE)
token = cpp_get_token (pfile);
if (token->type == CPP_OPEN_BRACE)
{
brace_nesting++;
extern_C_braces[extern_C_braces_length++]
......@@ -236,29 +221,9 @@ scan_decls (pfile, argc, argv)
break;
}
/* This may be the name of a variable or function. */
prev_id_start = start_written;
prev_id_end = CPP_WRITTEN (pfile);
break;
case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE: case CPP_DIRECTIVE:
goto new_statement; /* handle_statement? */
case CPP_EOF:
if (CPP_BUFFER (pfile) == NULL)
return 0;
/* else fall through */
case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT:
/* Skip initial white space. */
if (start_written == 0)
CPP_SET_WRITTEN (pfile, 0);
prev_id = token;
break;
default:
prev_id_start = 0;
}
start_written = CPP_WRITTEN (pfile);
token = cpp_get_token (pfile);
}
}
......@@ -50,6 +50,8 @@ struct fn_decl
struct partial_proto *partial;
};
struct cpp_token;
extern int lineno;
extern void sstring_append _PARAMS((sstring *, sstring *));
extern void make_sstring_space _PARAMS((sstring *, int));
......@@ -58,8 +60,9 @@ extern int scan_ident _PARAMS((FILE *, sstring *, int));
extern int scan_string _PARAMS((FILE *, sstring *, int));
extern int read_upto _PARAMS((FILE *, sstring *, int));
extern unsigned long hash _PARAMS((const char *));
extern void recognized_function _PARAMS((const char *, int, int, const char *, int, int, const char *, int));
extern void recognized_extern _PARAMS((const char *, int, const char *, int));
extern void recognized_function _PARAMS((const struct cpp_token *, int, int,
const char *));
extern void recognized_extern _PARAMS((const struct cpp_token *));
extern unsigned int hashstr _PARAMS((const char *, unsigned int));
struct cpp_reader;
......
2000-07-03 Zack Weinberg <zack@wolery.cumb.org>
* testsuite/gcc.dg/cpp/19951025-1.c: Adjust regexps.
* testsuite/gcc.dg/cpp/19990703-1.c: Likewise.
* testsuite/gcc.dg/cpp/20000625-1.c: Likewise.
* testsuite/gcc.dg/cpp/20000625-2.c: Likewise.
* testsuite/gcc.dg/cpp/macro1.c,
testsuite/gcc.dg/cpp/paste1.c, testsuite/gcc.dg/cpp/paste2.c,
testsuite/gcc.dg/cpp/paste3.c, testsuite/gcc.dg/cpp/paste4.c,
testsuite/gcc.dg/cpp/strify1.c,
testsuite/gcc.dg/cpp/strify2.c: New tests.
2000-07-03 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20000703-1.c: New test.
......
/* { dg-do preprocess } */
/* { dg-error "include expects" "" { target *-*-* } 4 } */
/* { dg-warning "no newline" "" { target *-*-* } 5 } */
/* { dg-error "newline at end" "" { target *-*-* } 4 } */
#include /\
......@@ -14,7 +14,7 @@
int
main(void)
{
char *x = SP1(0,MZ);
char *x = SP1(0,MZ); /* { dg-warning "valid preprocessing token" "" } */
char *y = "0-0"; /* should be the expansion of SP1(0,MZ) */
if(strcmp(x, y))
......
......@@ -11,6 +11,6 @@ main(void)
{
goto socket;
ENTRY(socket)
ENTRY(socket) /* { dg-warning "valid preprocessing token" "" } */
return 0;
}
......@@ -7,6 +7,7 @@
#define xstr(x) #x
const char a[] = str(symbol_version(getrlimit, GLIBC_2.0));
/* { dg-warning "valid preprocessing token" "" { target *-*-* } 9 } */
const char b[] = str(getrlimit@GLIBC_2.0);
const char c[] = "getrlimit@GLIBC_2.0";
......
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do run } */
/* Tests various macros are correctly expanded. */
extern int puts (const char *);
extern void abort (void);
#define err(str) do { puts(str); abort(); } while (0)
#define j(x, y) x + y
#define k(x, y) j(x + 2, y +
int q(int x) {return x + 40;}
int B(int x) {return x + 20;}
int foo(int x) {return x + 10;}
int bar(int x, int y) {return x + y;}
int baz(int x, int y) {return x + y;}
int toupper(int x) {return x + 32;}
int main (int argc, char *argv[])
{
#define q(x) x
if (q(q)(2) != 42)
err ("q");
#define A(x) B(x)
if (A(A(2)) != 42)
err ("A");
#define E(x) A x
#define F (22)
if (E(F) != 42)
err ("E(F)");
#define COMMA ,
#define NASTY(a) j(a 37)
if (NASTY (5 COMMA) != 42)
err ("NASTY");
#define bar(x, y) foo(x(y, 0))
#define apply(x, y) foo(x(y, 22))
#define bam bar
if (bar(bar, 32) != 42) /* foo(bar(32, 0)). */
err ("bar bar");
if (bar(bam, 32) != 42) /* Same. */
err ("bar bam");
if (apply(bar, baz) != 42) /* foo(foo(baz(22, 0))). */
err ("apply bar baz");
#define __tobody(c, f) f (c)
#define toupper(c) __tobody (c, toupper)
if (toupper (10) != 42) /* toupper (10). */
err ("toupper");
/* This looks like it has too many ')', but it hasn't. */
if (k(1, 4) 35) != 42)
err ("k");
/*#define B(x) Z B(x)
#define XEXP(RTX, N) RTX->fld[N].rtx
#define PATTERN(INSN) XEXP(INSN, 3)
#define COST(X) XEXP (XEXP (x, 0), 0)
#define M(a) OK M (a)
#define stpcpy(a) M(a)
#define C(x) A(x)
XEXP (PATTERN (insn), i);
XEXP (XEXP (insn, 3), i);
COST (b)*/
return 0;
}
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
/* Test operator ## semantics. */
#define bad1 ## owt /* { dg-error "cannot" "## at objlike start" } */
#define bad2 owt ## /* { dg-error "cannot" "## at objlike end" } */
#define bad3(x) ## x /* { dg-error "cannot" "## at funlike start" } */
#define bad4(x) x ## /* { dg-error "cannot" "## at funlike end" } */
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do run } */
/* { dg-options "-std=c99 -pedantic-errors" } */
/* Test ## behaviour and corner cases thoroughly. The macro expander
failed many of these during development. */
#include <string.h>
#ifndef __WCHAR_TYPE__
#define __WCHAR_TYPE__ int
#endif
typedef __WCHAR_TYPE__ wchar_t;
extern int puts (const char *);
extern void abort (void);
#define err(str) do { puts(str); abort(); } while (0)
#define EMPTY
#define str(x) #x
#define xstr(x) str(x)
#define glue(x, y) x ## y
#define xglue(x, y) glue (x, y)
#define glue3(x, y, z) x ## y ## z
#define glue_var(x, ...) x ## __VA_ARGS__
#define __muldi3 __NDW(mul, 3 = 50)
#define __NDW(a,b) __ ## a ## di ## b
#define m3 NDW()
#define NDW(x) m3 ## x = 50
#define five 5
#define fifty int fif ## ty
/* Defines a function called glue, returning what it is passed. */
int glue (glue,) (int x)
{
return x;
}
int main ()
{
/* m3 and __muldi3 would sometimes cause an infinite loop. Ensure
we only expand fifty once. */
fifty = 50, m3, __muldi3;
/* General glue and macro expanding test. */
int five0 = xglue (glue (fi, ve), 0);
/* Tests only first and last tokens are pasted, and pasting to form
the != operator. Should expand to: if (five0 != 50). */
if (glue3 (fi, ve0 !,= glue (EMPTY 5, 0)))
err ("five0 != 50");
/* Test varags pasting, and pasting to form the >> operator. */
if (glue_var(50 >, > 1 != 25))
err ("Operator >> pasting");
/* The LHS should not attempt to expand twice, and thus becomes a
call to the function glue, but the RHS should fully expand. */
if (glue (gl, ue) (12) != glue (xgl, ue) (1, 2))
err ("Recursive macros");
/* Test placemarker pasting. The glued lines should all appear
neatly in the same column and below each other, though we don't
test that here. */
{
int glue3(a, b, ) = 1, glue3(a,,) = 1;
glue3(a, , b)++;
glue3(, a, b)++;
glue3(,a,)++;
glue3(,,a)++;
if (a != 3 || ab != 3 glue3(,,))
err ("Placemarker pasting");
}
/* Test that macros in arguments are not expanded. */
{
int glue (EMPTY,1) = 123, glue (T, EMPTY) = 123;
if (EMPTY1 != 123 || TEMPTY != 123)
err ("Pasted arguments macro expanding");
}
/* Test various paste combinations. */
{
const wchar_t* wc_array = glue(L, "wide string");
wchar_t wc = glue(L, 'w');
const char * hh = xstr(xglue(glue(%, :), glue(%, :)));
int array glue (<, :) 1 glue (:, >) = glue(<, %) 1 glue(%, >);
int x = 4;
if (array[0] != 1)
err ("Digraph pasting");
x glue (>>, =) 1; /* 2 */
x glue (<<, =) 1; /* 4 */
x glue (*, =) 2; /* 8 */
x glue (+, =) 100; /* 108 */
x glue (-, =) 50; /* 58 */
x glue (/, =) 2; /* 29 */
x glue (%, =) 20; /* 9 */
x glue (&, =) 254; /* 8 */
x glue (|, =) 16; /* 24 */
x glue (^, =) 18; /* 10 */
if (x != 10 || 0 glue (>, =) 1 glue (|, |) 1 glue (<, =) 0)
err ("Various operator pasting");
if (strcmp (hh, "%:%:"))
err ("Pasted digraph spelling");
if ((glue (., 0) glue (=, =) .0) + (glue3 (1.0e, +, 1) == 10.0) != 2)
err ("Pasted numbers");
}
return 0;
}
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do compile } */
#define plus +
void foo()
{
int a, b = 1;
/* The correct "a = 1 + ++b" will compile.
The incorrect "a = 1 +++b" won't. */
a = 1 plus++b;
}
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do compile } */
/* Since 1.0e and + form the pasted token, 1 is a separate token and
so should be output with a preceding space. The old preprocessor
gets this wrong. */
#define glue(x, y) x ## y
int main ()
{
double d = glue (1.0e, +1); /* { dg-error "floating const|parse error" } */
return 0;
}
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
/* Test operator # semantics. */
#define OK1 # /* No problem. */
#define OK2(x) x#x /* No problem. */
#define bad1(x) # /* { dg-error "followed by a macro parameter" "#1" } */
#define bad2(x) #y /* { dg-error "followed by a macro parameter" "#2" } */
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do run } */
/* { dg-options "-std=c99 -pedantic-errors" } */
/* Tests a whole bunch of things are correctly stringified. */
extern int strcmp (const char *, const char *);
extern int puts (const char *);
extern void abort (void);
#define err(str) do { puts(str); abort(); } while (0)
#define str(x) #x
#define xstr(x) str(x)
#define strvar(...) #__VA_ARGS__
int main (int argc, char *argv[])
{
str (\); /* { dg-warning "valid string" "str(\)" } */
str (\\\); /* { dg-warning "valid string" "str(\\\)" } */
/* This also serves as a useful test of the value of __INCLUDE_LEVEL. */
if (strcmp (xstr (__INCLUDE_LEVEL__), "0"))
err ("macro expansion");
if (strcmp(str (__INCLUDE_LEVEL__), "__INCLUDE_LEVEL__"))
err ("macro name");
if (strcmp(str ("s\n"), "\"s\\n\""))
err ("quoted string");
if (strcmp (str (a b), "a \200 b"))
err ("unprintable char");
if (strcmp (str ( a b@ c ), "a b@ c"))
err ("internal whitespace");
if (strcmp (str(a \n), "a \n"))
err ("backslash token");
if (strcmp (strvar (foo, bar), "foo, bar"))
err ("variable arguments");
return 0;
}
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