cpperror.c (v_message): Split into _cpp_begin_message and v_message macro.

* cpperror.c (v_message): Split into _cpp_begin_message and
	v_message macro.  All callers updated.
	(_cpp_begin_message): Do inhibit_errors/inhibit_warnings
	checks here.

	* cppfiles.c (cpp_syshdr_flags): New function.
	(read_include_file): Don't call cpp_output_tokens.  Call
	enter_file hook.
	* cppinit.c (dump_macros_helper): Moved to cppmain.c.
	(cpp_reader_init): Don't initialize token_buffer.  Call
	_cpp_init_internal_pragmas.
	(cpp_cleanup): Don't clear token_buffer.
	(cpp_start_read): Don't worry about output from -D processing.
	Don't call cpp_output_tokens.
	(cpp_finish): Don't dump macros here.  Don't call
	cpp_output_tokens.
	* cppmacro.c (_cpp_dump_definition): Rename
	cpp_dump_definition.  Write directly to a FILE *.
	(dump_funlike_macro): Delete.
	(dump_macro_args): New.

	* cpplex.c (TOKEN_LEN): Convert to inline function.
	(_cpp_grow_token_buffer, safe_fwrite, cpp_output_tokens,
	cpp_scan_line, _cpp_dump_list): Delete.
	(cpp_printf, cpp_output_list): New.
	(output_line_command): Don't worry about entering or leaving files.
	(cpp_scan_buffer): Just output each token as we hit it.
	(process_directive): Don't call cpp_output_tokens.
	(_cpp_glue_header_name): Don't use token_buffer.
	(output_token, dump_param_spelling): Write directly to a FILE *.

	* cpplib.c (pass_thru_directive, dump_macro_name,
	pragma_dispatch, do_pragma_gcc): Delete.
	(do_define, do_undef, parse_include, do_line, do_ident, do_pragma,
	do_pragma_poison, cpp_pop_buffer): Call the appropriate hook
	functions.
	(do_error, do_warning, pragma_dependency): Call
	_cpp_begin_message, then cpp_output_list.
	(cpp_register_pragma, cpp_register_pragma_space,
	_cpp_init_internal_pragmas): New.
	(do_pragma): Walk the pragmas table here.
	(do_pragma_once, do_pragma_poison, do_pragma_system_header,
	do_pragma_dependency): Return void.
	(do_pragma_implementation): Moved to cppmain.c.

	* cpplib.h: Update prototypes.
	 (struct cpp_reader): Remove printer, token_buffer,
	token_buffer_size, and limit.  Add struct cb, and pragmas.
	(struct cpp_printer): Remove last_id and written.
	(CPP_WRITTEN, CPP_PWRITTEN, CPP_SET_WRITTEN,
	CPP_ADJUST_WRITTEN): Delete.
	* cpphash.h: Update prototypes.
	(ufputs): New wrapper.

	* cppmain.c (cb_define, cb_undef, cb_include, cb_ident,
	cb_enter_file, cb_leave_file, cb_def_pragma): New functions.
	(main): Set up callbacks.  Register #pragma implementation.
	Dump macros from here.

From-SVN: r35415
This commit is contained in:
Zack Weinberg 2000-08-02 01:13:45 +00:00
parent 8cd8f856b3
commit 58fea6afd9
10 changed files with 757 additions and 645 deletions

View File

@ -32,10 +32,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void print_containing_files PARAMS ((cpp_reader *, cpp_buffer *));
static void print_file_and_line PARAMS ((const char *, unsigned int,
unsigned int));
static void v_message PARAMS ((cpp_reader *, int,
const char *,
unsigned int, unsigned int,
const char *, va_list));
#define v_message(msgid, ap) \
do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
/* Print the file names and line numbers of the #include
commands which led to the current file. */
@ -92,30 +91,83 @@ print_file_and_line (filename, line, column)
const char *filename;
unsigned int line, column;
{
if (filename == 0 || *filename == '\0')
filename = "<stdin>";
if (line == 0)
fputs (_("<command line>: "), stderr);
else if (column > 0)
fprintf (stderr, "%s:%u:%u: ", filename, line, column);
else
fprintf (stderr, "%s:%u: ", filename, line);
{
if (filename == 0 || *filename == '\0')
filename = "<stdin>";
if (column > 0)
fprintf (stderr, "%s:%u:%u: ", filename, line, column);
else
fprintf (stderr, "%s:%u: ", filename, line);
}
}
/* IS_ERROR is 3 for ICE, 2 for merely "fatal" error,
1 for error, 0 for warning. */
/* Set up for an error message: print the file and line, bump the error
counter, etc.
If it returns 0, this error has been suppressed. */
static void
v_message (pfile, is_error, file, line, col, msg, ap)
int
_cpp_begin_message (pfile, code, file, line, col)
cpp_reader *pfile;
int is_error;
enum error_type code;
const char *file;
unsigned int line;
unsigned int col;
const char *msg;
va_list ap;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
int is_warning = 0;
switch (code)
{
case WARNING:
if (! CPP_OPTION (pfile, warnings_are_errors))
{
if (CPP_OPTION (pfile, inhibit_warnings))
return 0;
is_warning = 1;
}
else
{
if (CPP_OPTION (pfile, inhibit_errors))
return 0;
if (pfile->errors < CPP_FATAL_LIMIT)
pfile->errors++;
}
break;
case PEDWARN:
if (! CPP_OPTION (pfile, pedantic_errors))
{
if (CPP_OPTION (pfile, inhibit_warnings))
return 0;
is_warning = 1;
}
else
{
if (CPP_OPTION (pfile, inhibit_errors))
return 0;
if (pfile->errors < CPP_FATAL_LIMIT)
pfile->errors++;
}
break;
case ERROR:
if (CPP_OPTION (pfile, inhibit_errors))
return 0;
if (pfile->errors < CPP_FATAL_LIMIT)
pfile->errors++;
break;
/* Fatal errors cannot be inhibited. */
case FATAL:
pfile->errors = CPP_FATAL_LIMIT;
break;
case ICE:
fprintf (stderr, _("internal error: "));
pfile->errors = CPP_FATAL_LIMIT;
break;
}
if (ip)
{
@ -130,32 +182,10 @@ v_message (pfile, is_error, file, line, col, msg, ap)
else
fprintf (stderr, "%s: ", progname);
switch (is_error)
{
case 0:
if (! CPP_OPTION (pfile, warnings_are_errors))
{
fprintf (stderr, _("warning: "));
break;
}
/* else fall through */
case 1:
if (pfile->errors < CPP_FATAL_LIMIT)
pfile->errors++;
break;
case 2:
pfile->errors = CPP_FATAL_LIMIT;
break;
case 3:
fprintf (stderr, _("internal error: "));
pfile->errors = CPP_FATAL_LIMIT;
break;
default:
cpp_ice (pfile, "bad is_error(%d) in v_message", is_error);
}
if (is_warning)
fputs (_("warning: "), stderr);
vfprintf (stderr, _(msg), ap);
putc ('\n', stderr);
return 1;
}
/* Exported interface. */
@ -179,7 +209,8 @@ cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
v_message (pfile, 3, NULL, 0, 0, msgid, ap);
if (_cpp_begin_message (pfile, ICE, NULL, 0, 0))
v_message (msgid, ap);
va_end(ap);
}
@ -205,7 +236,8 @@ cpp_fatal VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
v_message (pfile, 2, NULL, 0, 0, msgid, ap);
if (_cpp_begin_message (pfile, FATAL, NULL, 0, 0))
v_message (msgid, ap);
va_end(ap);
}
@ -225,10 +257,8 @@ cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, inhibit_errors))
return;
v_message (pfile, 1, NULL, 0, 0, msgid, ap);
if (_cpp_begin_message (pfile, ERROR, NULL, 0, 0))
v_message (msgid, ap);
va_end(ap);
}
@ -253,10 +283,8 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column,
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, inhibit_errors))
return;
v_message (pfile, 1, NULL, line, column, msgid, ap);
if (_cpp_begin_message (pfile, ERROR, NULL, line, column))
v_message (msgid, ap);
va_end(ap);
}
@ -285,10 +313,8 @@ cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, 0, NULL, 0, 0, msgid, ap);
if (_cpp_begin_message (pfile, WARNING, NULL, 0, 0))
v_message (msgid, ap);
va_end(ap);
}
@ -313,10 +339,8 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, 0, NULL, line, column, msgid, ap);
if (_cpp_begin_message (pfile, WARNING, NULL, line, column))
v_message (msgid, ap);
va_end(ap);
}
@ -336,13 +360,8 @@ cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, pedantic_errors)
? CPP_OPTION (pfile, inhibit_errors)
: CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, CPP_OPTION (pfile, pedantic_errors),
NULL, 0, 0, msgid, ap);
if (_cpp_begin_message (pfile, PEDWARN, NULL, 0, 0))
v_message (msgid, ap);
va_end(ap);
}
@ -367,13 +386,8 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, pedantic_errors)
? CPP_OPTION (pfile, inhibit_errors)
: CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, CPP_OPTION (pfile, pedantic_errors),
NULL, line, column, msgid, ap);
if (_cpp_begin_message (pfile, PEDWARN, NULL, line, column))
v_message (msgid, ap);
va_end(ap);
}
@ -404,13 +418,8 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile,
msgid = va_arg (ap, const char *);
#endif
if (CPP_OPTION (pfile, pedantic_errors)
? CPP_OPTION (pfile, inhibit_errors)
: CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, CPP_OPTION (pfile, pedantic_errors),
file, line, col, msgid, ap);
if (_cpp_begin_message (pfile, PEDWARN, file, line, col))
v_message (msgid, ap);
va_end(ap);
}

View File

@ -370,6 +370,20 @@ cpp_make_system_header (pfile, pbuf, flag)
pbuf->inc->sysp = flag;
}
const char *
cpp_syshdr_flags (pfile, pbuf)
cpp_reader *pfile ATTRIBUTE_UNUSED;
cpp_buffer *pbuf;
{
#ifndef NO_IMPLICIT_EXTERN_C
if (CPP_OPTION (pfile, cplusplus) && pbuf->inc->sysp == 2)
return " 3 4";
#endif
if (pbuf->inc->sysp)
return " 3";
return "";
}
/* Report on all files that might benefit from a multiple include guard.
Triggered by -H. */
void
@ -594,11 +608,6 @@ 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)
@ -683,6 +692,8 @@ read_include_file (pfile, inc)
fp->actual_dir = actual_directory (pfile, inc->name);
pfile->input_stack_listing_current = 0;
if (pfile->cb.enter_file)
(*pfile->cb.enter_file) (pfile);
return 1;
perror_fail:

View File

@ -210,10 +210,15 @@ extern unsigned char _cpp_IStable[256];
#define DUMMY_TOKEN 0
#define NO_DUMMY_TOKEN 1
/* In cpperror.c */
enum error_type { WARNING = 0, PEDWARN, ERROR, FATAL, ICE };
extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type,
const char *, unsigned int,
unsigned int));
/* In cppmacro.c */
extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
extern void _cpp_dump_definition PARAMS ((cpp_reader *, cpp_hashnode *));
/* In cpphash.c */
extern void _cpp_init_macros PARAMS ((cpp_reader *));
@ -253,9 +258,6 @@ extern int _cpp_equiv_toklists PARAMS ((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 *,
@ -279,6 +281,7 @@ extern struct answer **_cpp_find_answer PARAMS ((cpp_hashnode *,
const cpp_toklist *));
extern void _cpp_init_stacks PARAMS ((cpp_reader *));
extern void _cpp_cleanup_stacks PARAMS ((cpp_reader *));
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
/* Utility routines and macros. */
#define xnew(T) (T *) xmalloc (sizeof(T))
@ -295,6 +298,7 @@ static inline int ustrncmp PARAMS ((const U_CHAR *, const U_CHAR *,
static inline size_t ustrlen PARAMS ((const U_CHAR *));
static inline U_CHAR *uxstrdup PARAMS ((const U_CHAR *));
static inline U_CHAR *ustrchr PARAMS ((const U_CHAR *, int));
static inline int ufputs PARAMS ((const U_CHAR *, FILE *));
static inline int
ustrcmp (s1, s2)
@ -333,4 +337,12 @@ ustrchr (s1, c)
return (U_CHAR *) strchr ((const char *)s1, c);
}
static inline int
ufputs (s, f)
const U_CHAR *s;
FILE *f;
{
return fputs ((const char *)s, f);
}
#endif

View File

@ -114,7 +114,6 @@ static int opt_comp PARAMS ((const void *, const void *));
static void sort_options PARAMS ((void));
#endif
static int parse_option PARAMS ((const char *));
static int dump_macros_helper PARAMS ((cpp_reader *, cpp_hashnode *));
/* Fourth argument to append_include_chain: chain to use */
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
@ -415,10 +414,6 @@ cpp_reader_init (pfile)
memset ((char *) pfile, 0, sizeof (cpp_reader));
pfile->token_buffer_size = 200;
pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size);
CPP_SET_WRITTEN (pfile, 0);
CPP_OPTION (pfile, dollars_in_ident) = 1;
CPP_OPTION (pfile, cplusplus_comments) = 1;
CPP_OPTION (pfile, warn_import) = 1;
@ -434,6 +429,7 @@ cpp_reader_init (pfile)
_cpp_init_macros (pfile);
_cpp_init_stacks (pfile);
_cpp_init_includes (pfile);
_cpp_init_internal_pragmas (pfile);
}
/* Initialize a cpp_printer structure. As a side effect, open the
@ -470,12 +466,6 @@ cpp_cleanup (pfile)
while (CPP_BUFFER (pfile) != NULL)
cpp_pop_buffer (pfile);
if (pfile->token_buffer)
{
free (pfile->token_buffer);
pfile->token_buffer = NULL;
}
if (pfile->deps)
deps_free (pfile->deps);
@ -857,18 +847,6 @@ cpp_start_read (pfile, print, fname)
initialize_dependency_output (pfile);
/* -D and friends may produce output, which should be identified
as line 0. */
CPP_BUFFER (pfile)->lineno = 0;
if (print)
{
print->last_fname = CPP_BUFFER (pfile)->nominal_fname;
print->last_id = pfile->include_depth;
print->written = CPP_WRITTEN (pfile);
print->lineno = 0;
}
/* Install __LINE__, etc. */
initialize_builtins (pfile);
@ -883,12 +861,12 @@ cpp_start_read (pfile, print, fname)
}
pfile->done_initializing = 1;
/* Now flush any output recorded during initialization, and advance
to line 1 of the main input file. */
CPP_BUFFER (pfile)->lineno = 1;
if (print && ! CPP_OPTION (pfile, no_output))
cpp_output_tokens (pfile, print, 1);
/* We start at line 1 of the main input file. */
if (print)
{
print->last_fname = CPP_BUFFER (pfile)->nominal_fname;
print->lineno = 1;
}
/* The -imacros files can be scanned now, but the -include files
have to be pushed onto the include stack and processed later,
@ -907,9 +885,7 @@ cpp_start_read (pfile, print, fname)
p = CPP_OPTION (pfile, pending)->include_head;
while (p)
{
if (cpp_read_file (pfile, p->arg)
&& print && ! CPP_OPTION (pfile, no_output))
cpp_output_tokens (pfile, print, 1); /* record entry to file */
cpp_read_file (pfile, p->arg);
q = p->next;
free (p);
p = q;
@ -921,18 +897,6 @@ cpp_start_read (pfile, print, fname)
return 1;
}
/* Dump out the hash table. */
static int
dump_macros_helper (pfile, hp)
cpp_reader *pfile;
cpp_hashnode *hp;
{
if (hp->type == T_MACRO)
_cpp_dump_definition (pfile, hp);
return 1;
}
/* This is called at the end of preprocessing. It pops the
last buffer and writes dependency output. It should also
clear macro definitions, such that you could call cpp_start_read
@ -975,13 +939,11 @@ cpp_finish (pfile, print)
}
}
if (CPP_OPTION (pfile, dump_macros) == dump_only)
cpp_forall_identifiers (pfile, dump_macros_helper);
/* Flush any pending output. */
if (print)
{
cpp_output_tokens (pfile, print, print->lineno);
if (pfile->need_newline)
putc ('\n', print->outf);
if (ferror (print->outf) || fclose (print->outf))
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
}

View File

@ -24,13 +24,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
Cleanups to do:-
o -dM and with _cpp_dump_list: too many \n output.
o Put a printer object in cpp_reader?
o Check line numbers assigned to all errors.
o Replace strncmp with memcmp almost everywhere.
o lex_line's use of cur_token, flags and list->token_used is a bit opaque.
o Convert do_ functions to return void. Kaveh thinks its OK; and said he'll
give it a run when we've got some code.
o Distinguish integers, floats, and 'other' pp-numbers.
o Store ints and char constants as binary values.
o New command-line assertion syntax.
@ -101,9 +97,7 @@ static void free_macro_args PARAMS ((macro_args *));
#define auto_expand_name_space(list) \
_cpp_expand_name_space ((list), 1 + (list)->name_cap / 2)
static void safe_fwrite PARAMS ((cpp_reader *, const U_CHAR *,
size_t, FILE *));
static void dump_param_spelling PARAMS ((cpp_reader *, const cpp_toklist *,
static void dump_param_spelling PARAMS ((FILE *, const cpp_toklist *,
unsigned int));
static void output_line_command PARAMS ((cpp_reader *, cpp_printer *,
unsigned int));
@ -135,8 +129,8 @@ static cpp_token *stringify_arg PARAMS ((cpp_reader *, const cpp_token *));
static void expand_context_stack PARAMS ((cpp_reader *));
static unsigned char * spell_token PARAMS ((cpp_reader *, const cpp_token *,
unsigned char *));
static void output_token PARAMS ((cpp_reader *, const cpp_token *,
const cpp_token *));
static void output_token PARAMS ((cpp_reader *, FILE *, const cpp_token *,
const cpp_token *, int));
typedef unsigned int (* speller) PARAMS ((unsigned char *, cpp_toklist *,
cpp_token *));
static cpp_token *make_string_token PARAMS ((cpp_token *, const U_CHAR *,
@ -189,11 +183,21 @@ static void process_directive PARAMS ((cpp_reader *, const cpp_token *));
/* An upper bound on the number of bytes needed to spell a token,
including preceding whitespace. */
#define TOKEN_LEN(token) (5 + (TOKEN_SPELL(token) == SPELL_STRING \
? (token)->val.str.len \
: (TOKEN_SPELL(token) == SPELL_IDENT \
? (token)->val.node->length \
: 0)))
static inline size_t TOKEN_LEN PARAMS ((const cpp_token *));
static inline size_t
TOKEN_LEN (token)
const cpp_token *token;
{
size_t len;
switch (TOKEN_SPELL (token))
{
default: len = 0; break;
case SPELL_STRING: len = token->val.str.len; break;
case SPELL_IDENT: len = token->val.node->length; break;
}
return len + 5;
}
#define IS_ARG_CONTEXT(c) ((c)->flags & CONTEXT_ARG)
#define CURRENT_CONTEXT(pfile) ((pfile)->contexts + (pfile)->cur_context)
@ -246,44 +250,6 @@ END
#undef END
#undef s
/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
void
_cpp_grow_token_buffer (pfile, n)
cpp_reader *pfile;
long n;
{
long old_written = CPP_WRITTEN (pfile);
pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
pfile->token_buffer = (U_CHAR *)
xrealloc(pfile->token_buffer, pfile->token_buffer_size);
CPP_SET_WRITTEN (pfile, old_written);
}
/* Deal with the annoying semantics of fwrite. */
static void
safe_fwrite (pfile, buf, len, fp)
cpp_reader *pfile;
const U_CHAR *buf;
size_t len;
FILE *fp;
{
size_t count;
while (len)
{
count = fwrite (buf, 1, len, fp);
if (count == 0)
goto error;
len -= count;
buf += count;
}
return;
error:
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
}
/* Notify the compiler proper that the current line number has jumped,
or the current file name has changed. */
@ -294,51 +260,30 @@ output_line_command (pfile, print, line)
unsigned int line;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
enum { same = 0, enter, leave, rname } change;
static const char * const codes[] = { "", " 1", " 2", "" };
if (line == 0)
return;
/* End the previous line of text. */
if (pfile->need_newline)
putc ('\n', print->outf);
{
putc ('\n', print->outf);
print->lineno++;
}
pfile->need_newline = 0;
if (CPP_OPTION (pfile, no_line_commands))
return;
/* If ip is null, we've been called from cpp_finish, and they just
needed the final flush and trailing newline. */
if (!ip)
return;
if (pfile->include_depth == print->last_id)
{
/* Determine whether the current filename has changed, and if so,
how. 'nominal_fname' values are unique, so they can be compared
by comparing pointers. */
if (ip->nominal_fname == print->last_fname)
change = same;
else
change = rname;
}
else
{
if (pfile->include_depth > print->last_id)
change = enter;
else
change = leave;
print->last_id = pfile->include_depth;
}
print->last_fname = ip->nominal_fname;
/* If the current file has not changed, we can output a few newlines
instead if we want to increase the line number by a small amount.
We cannot do this if print->lineno is zero, because that means we
haven't output any line commands yet. (The very first line
command output is a `same_file' command.) */
if (change == same && print->lineno > 0
command output is a `same_file' command.)
'nominal_fname' values are unique, so they can be compared by
comparing pointers. */
if (ip->nominal_fname == print->last_fname && print->lineno > 0
&& line >= print->lineno && line < print->lineno + 8)
{
while (line > print->lineno)
@ -349,41 +294,41 @@ output_line_command (pfile, print, line)
return;
}
#ifndef NO_IMPLICIT_EXTERN_C
if (CPP_OPTION (pfile, cplusplus))
fprintf (print->outf, "# %u \"%s\"%s%s%s\n", line, ip->nominal_fname,
codes[change],
ip->inc->sysp ? " 3" : "",
(ip->inc->sysp == 2) ? " 4" : "");
else
#endif
fprintf (print->outf, "# %u \"%s\"%s%s\n", line, ip->nominal_fname,
codes[change],
ip->inc->sysp ? " 3" : "");
fprintf (print->outf, "# %u \"%s\"%s\n", line, ip->nominal_fname,
cpp_syshdr_flags (pfile, ip));
print->last_fname = ip->nominal_fname;
print->lineno = line;
}
/* Write the contents of the token_buffer to the output stream, and
clear the token_buffer. Also handles generating line commands and
keeping track of file transitions. */
/* Like fprintf, but writes to a printer object. You should be sure
always to generate a complete line when you use this function. */
void
cpp_output_tokens (pfile, print, line)
cpp_reader *pfile;
cpp_printer *print;
unsigned int line;
cpp_printf VPARAMS ((cpp_reader *pfile, cpp_printer *print,
const char *fmt, ...))
{
if (CPP_WRITTEN (pfile) - print->written)
{
safe_fwrite (pfile, pfile->token_buffer,
CPP_WRITTEN (pfile) - print->written, print->outf);
pfile->need_newline = 1;
if (print->lineno)
print->lineno++;
va_list ap;
#ifndef ANSI_PROTOTYPES
cpp_reader *pfile;
cpp_printer *print;
const char *fmt;
#endif
CPP_SET_WRITTEN (pfile, print->written);
}
output_line_command (pfile, print, line);
VA_START (ap, fmt);
#ifndef ANSI_PROTOTYPES
pfile = va_arg (ap, cpp_reader *);
print = va_arg (ap, cpp_printer *);
fmt = va_arg (ap, const char *);
#endif
/* End the previous line of text. */
if (pfile->need_newline)
putc ('\n', print->outf);
pfile->need_newline = 0;
vfprintf (print->outf, fmt, ap);
va_end (ap);
}
/* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output. */
@ -434,9 +379,6 @@ cpp_scan_buffer (pfile, print)
{
cpp_pop_buffer (pfile);
if (CPP_BUFFER (pfile))
cpp_output_tokens (pfile, print, CPP_BUF_LINE (CPP_BUFFER (pfile)));
if (CPP_BUFFER (pfile) == stop)
return;
@ -452,48 +394,18 @@ cpp_scan_buffer (pfile, print)
continue;
}
cpp_output_tokens (pfile, print, pfile->token_list.line);
output_line_command (pfile, print, pfile->token_list.line);
prev = 0;
}
if (token->type != CPP_PLACEMARKER)
output_token (pfile, token, prev);
prev = token;
}
}
/* Scan a single line of the input into the token_buffer. */
int
cpp_scan_line (pfile)
cpp_reader *pfile;
{
const cpp_token *token, *prev = 0;
if (pfile->buffer == NULL)
return 0;
do
{
token = cpp_get_token (pfile);
if (token->type == CPP_EOF)
{
cpp_pop_buffer (pfile);
break;
output_token (pfile, print->outf, token, prev, 1);
pfile->need_newline = 1;
}
/* If the last token on a line results from a macro expansion,
the check below will fail to stop us from proceeding to the
next line - so make sure we stick in a newline, at least. */
if (token->flags & BOL)
CPP_PUTC (pfile, '\n');
output_token (pfile, token, prev);
prev = token;
}
while (pfile->cur_context > 0
|| pfile->contexts[0].posn < pfile->contexts[0].count);
return 1;
}
/* Helper routine used by parse_include, which can't see spell_token.
@ -503,11 +415,14 @@ const cpp_token *
_cpp_glue_header_name (pfile)
cpp_reader *pfile;
{
unsigned int written = CPP_WRITTEN (pfile);
const cpp_token *t;
cpp_token *hdr;
U_CHAR *buf;
size_t len;
U_CHAR *buf, *p;
size_t len, avail;
avail = 40;
len = 0;
buf = xmalloc (avail);
for (;;)
{
@ -515,19 +430,23 @@ _cpp_glue_header_name (pfile)
if (t->type == CPP_GREATER || t->type == CPP_EOF)
break;
CPP_RESERVE (pfile, TOKEN_LEN (t));
if (len + TOKEN_LEN (t) > avail)
{
avail = len + TOKEN_LEN (t) + 40;
buf = xrealloc (buf, avail);
}
if (t->flags & PREV_WHITE)
CPP_PUTC_Q (pfile, ' ');
pfile->limit = spell_token (pfile, t, pfile->limit);
buf[len++] = ' ';
p = spell_token (pfile, t, buf + len);
len = (size_t) (p - buf); /* p known >= buf */
}
if (t->type == CPP_EOF)
cpp_error (pfile, "missing terminating > character");
len = CPP_WRITTEN (pfile) - written;
buf = xmalloc (len);
memcpy (buf, pfile->token_buffer + written, len);
CPP_SET_WRITTEN (pfile, written);
buf = xrealloc (buf, len);
hdr = get_temp_token (pfile);
hdr->type = CPP_HEADER_NAME;
@ -1894,51 +1813,150 @@ lex_line (pfile, list)
}
/* Write the spelling of a token TOKEN, with any appropriate
whitespace before it, to the token_buffer. PREV is the previous
token, which is used to determine if we need to shove in an extra
space in order to avoid accidental token paste. */
whitespace before it, to FP. PREV is the previous token, which
is used to determine if we need to shove in an extra space in order
to avoid accidental token paste. If WHITE is 0, do not insert any
leading whitespace. */
static void
output_token (pfile, token, prev)
output_token (pfile, fp, token, prev, white)
cpp_reader *pfile;
FILE *fp;
const cpp_token *token, *prev;
int white;
{
int dummy;
if (token->col && (token->flags & BOL))
if (white)
{
/* Supply enough whitespace to put this token in its original
column. Don't bother trying to reconstruct tabs; we can't
get it right in general, and nothing ought to care. (Yes,
some things do care; the fault lies with them.) */
unsigned char *buffer;
unsigned int spaces = token->col - 1;
int dummy;
CPP_RESERVE (pfile, token->col);
buffer = pfile->limit;
if (token->col && (token->flags & BOL))
{
/* Supply enough whitespace to put this token in its original
column. Don't bother trying to reconstruct tabs; we can't
get it right in general, and nothing ought to care. (Yes,
some things do care; the fault lies with them.) */
unsigned int spaces = token->col - 1;
while (spaces--)
putc (' ', fp);
}
else if (token->flags & PREV_WHITE)
putc (' ', fp);
else
/* Check for and prevent accidental token pasting.
In addition to the cases handled by can_paste, consider
while (spaces--)
*buffer++ = ' ';
pfile->limit = buffer;
}
else if (token->flags & PREV_WHITE)
CPP_PUTC (pfile, ' ');
else if (prev)
{
/* Check for and prevent accidental token pasting. */
if (can_paste (pfile, prev, token, &dummy) != CPP_EOF)
CPP_PUTC (pfile, ' ');
/* can_paste doesn't catch all the accidental pastes.
Consider a + ++b - if there is not a space between the + and ++, it
will be misparsed as a++ + b. */
else if ((prev->type == CPP_PLUS && token->type == CPP_PLUS_PLUS)
|| (prev->type == CPP_MINUS && token->type == CPP_MINUS_MINUS))
CPP_PUTC (pfile, ' ');
a + ++b - if there is not a space between the + and ++, it
will be misparsed as a++ + b. But + ## ++ doesn't produce
a valid token. */
if (prev
&& (can_paste (pfile, prev, token, &dummy) != CPP_EOF
|| (prev->type == CPP_PLUS && token->type == CPP_PLUS_PLUS)
|| (prev->type == CPP_MINUS && token->type == CPP_MINUS_MINUS)))
putc (' ', fp);
}
CPP_RESERVE (pfile, TOKEN_LEN (token));
pfile->limit = spell_token (pfile, token, pfile->limit);
switch (TOKEN_SPELL (token))
{
case SPELL_OPERATOR:
{
const unsigned char *spelling;
if (token->flags & DIGRAPH)
spelling = digraph_spellings[token->type - CPP_FIRST_DIGRAPH];
else if (token->flags & NAMED_OP)
goto spell_ident;
else
spelling = TOKEN_NAME (token);
ufputs (spelling, fp);
}
break;
case SPELL_IDENT:
spell_ident:
ufputs (token->val.node->name, fp);
break;
case SPELL_STRING:
{
if (token->type == CPP_WSTRING || token->type == CPP_WCHAR)
putc ('L', fp);
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
putc ('"', fp);
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
putc ('\'', fp);
fwrite (token->val.str.text, 1, token->val.str.len, fp);
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
putc ('"', fp);
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
putc ('\'', fp);
}
break;
case SPELL_CHAR:
putc (token->val.aux, fp);
break;
case SPELL_NONE:
/* Placemarker or EOF - no output. (Macro args are handled
elsewhere. */
break;
}
}
/* Dump the original user's spelling of argument index ARG_NO to the
macro whose expansion is LIST. */
static void
dump_param_spelling (fp, list, arg_no)
FILE *fp;
const cpp_toklist *list;
unsigned int arg_no;
{
const U_CHAR *param = list->namebuf;
while (arg_no--)
param += ustrlen (param) + 1;
ufputs (param, fp);
}
/* Output all the tokens of LIST, starting at TOKEN, to FP. */
void
cpp_output_list (pfile, fp, list, token)
cpp_reader *pfile;
FILE *fp;
const cpp_toklist *list;
const cpp_token *token;
{
const cpp_token *limit = list->tokens + list->tokens_used;
const cpp_token *prev = 0;
int white = 0;
while (token < limit)
{
/* XXX Find some way we can write macro args from inside
output_token/spell_token. */
if (token->type == CPP_MACRO_ARG)
{
if (white && token->flags & PREV_WHITE)
putc (' ', fp);
if (token->flags & STRINGIFY_ARG)
putc ('#', fp);
dump_param_spelling (fp, list, token->val.aux);
}
else
output_token (pfile, fp, token, prev, white);
if (token->flags & PASTE_LEFT)
fputs (" ##", fp);
prev = token;
token++;
white = 1;
}
}
/* Write the spelling of a token TOKEN to BUFFER. The buffer must
already contain the enough space to hold the token's spelling.
Returns a pointer to the character after the last character
@ -3033,12 +3051,6 @@ process_directive (pfile, token)
else if (token[1].type != CPP_NUMBER)
cpp_ice (pfile, "directive begins with %s?!", TOKEN_NAME (token));
/* Flush pending tokens at this point, in case the directive produces
output. XXX Directive output won't be visible to a direct caller of
cpp_get_token. */
if (pfile->printer && CPP_WRITTEN (pfile) - pfile->printer->written)
cpp_output_tokens (pfile, pfile->printer, pfile->token_list.line);
if (! (d->flags & EXPAND))
prev_nme = prevent_macro_expansion (pfile);
(void) (*d->handler) (pfile);
@ -3464,58 +3476,6 @@ special_symbol (pfile, node, token)
}
#undef DSC
/* Dump the original user's spelling of argument index ARG_NO to the
macro whose expansion is LIST. */
static void
dump_param_spelling (pfile, list, arg_no)
cpp_reader *pfile;
const cpp_toklist *list;
unsigned int arg_no;
{
const U_CHAR *param = list->namebuf;
while (arg_no--)
param += ustrlen (param) + 1;
CPP_PUTS (pfile, param, ustrlen (param));
}
/* Dump a token list to the output. */
void
_cpp_dump_list (pfile, list, token, flush)
cpp_reader *pfile;
const cpp_toklist *list;
const cpp_token *token;
int flush;
{
const cpp_token *limit = list->tokens + list->tokens_used;
const cpp_token *prev = 0;
/* Avoid the CPP_EOF. */
if (list->directive)
limit--;
while (token < limit)
{
if (token->type == CPP_MACRO_ARG)
{
if (token->flags & PREV_WHITE)
CPP_PUTC (pfile, ' ');
if (token->flags & STRINGIFY_ARG)
CPP_PUTC (pfile, '#');
dump_param_spelling (pfile, list, token->val.aux);
}
else if (token->type != CPP_PLACEMARKER)
output_token (pfile, token, prev);
if (token->flags & PASTE_LEFT)
CPP_PUTS (pfile, " ##", 3);
prev = token;
token++;
}
if (flush && pfile->printer)
cpp_output_tokens (pfile, pfile->printer, pfile->token_list.line);
}
/* Allocate pfile->input_buffer, and initialize trigraph_map[]
if it hasn't happened already. */

View File

@ -49,7 +49,6 @@ static int parse_include PARAMS ((cpp_reader *, const U_CHAR *, int,
int *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
const cpp_hashnode *));
static void pass_thru_directive PARAMS ((cpp_reader *));
static int read_line_number PARAMS ((cpp_reader *, int *));
static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
unsigned long *));
@ -60,7 +59,6 @@ static const cpp_hashnode *
detect_if_not_defined PARAMS ((cpp_reader *));
static cpp_hashnode *
get_define_node PARAMS ((cpp_reader *));
static void dump_macro_name PARAMS ((cpp_reader *, cpp_hashnode *));
static void unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *));
/* Utility. */
@ -214,29 +212,6 @@ _cpp_check_linemarker (pfile, token, bol)
return &dtable[T_LINE];
}
static void
dump_macro_name (pfile, node)
cpp_reader *pfile;
cpp_hashnode *node;
{
CPP_PUTS (pfile, "#define ", sizeof "#define " - 1);
CPP_PUTS (pfile, node->name, node->length);
}
/* Pass the current directive through to the output file. */
static void
pass_thru_directive (pfile)
cpp_reader *pfile;
{
/* XXX This output may be genuinely needed even when there is no
printer. */
if (! pfile->printer)
return;
/* Flush first (temporary). */
cpp_output_tokens (pfile, pfile->printer, pfile->token_list.line);
_cpp_dump_list (pfile, &pfile->token_list, pfile->first_directive_token, 1);
}
static cpp_hashnode *
get_define_node (pfile)
cpp_reader *pfile;
@ -288,13 +263,8 @@ do_define (pfile)
if ((node = get_define_node (pfile)))
if (_cpp_create_definition (pfile, node))
{
if (CPP_OPTION (pfile, debug_output)
|| CPP_OPTION (pfile, dump_macros) == dump_definitions)
_cpp_dump_definition (pfile, node);
else if (CPP_OPTION (pfile, dump_macros) == dump_names)
dump_macro_name (pfile, node);
}
if (pfile->cb.define)
(*pfile->cb.define) (pfile, node);
}
/* Remove the definition of a symbol from the symbol table. */
@ -311,12 +281,8 @@ do_undef (pfile)
is not currently defined as a macro name. */
if (node && node->type != T_VOID)
{
/* 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)
|| CPP_OPTION (pfile, dump_macros) == dump_definitions
|| CPP_OPTION (pfile, dump_macros) == dump_names)
pass_thru_directive (pfile);
if (pfile->cb.undef)
(*pfile->cb.undef) (pfile, node);
if (node->type != T_MACRO)
cpp_warning (pfile, "undefining \"%s\"", node->name);
@ -362,6 +328,9 @@ parse_include (pfile, dir, trail, strp, lenp, abp)
*lenp = name->val.str.len;
*strp = name->val.str.text;
*abp = (name->type == CPP_HEADER_NAME);
if (pfile->cb.include)
(*pfile->cb.include) (pfile, dir, *strp, *lenp, *abp);
return 0;
}
@ -377,8 +346,6 @@ do_include (pfile)
return;
_cpp_execute_include (pfile, str, len, 0, 0, ab);
if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (pfile);
}
static void
@ -401,8 +368,6 @@ do_import (pfile)
return;
_cpp_execute_include (pfile, str, len, 1, 0, ab);
if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (pfile);
}
static void
@ -436,8 +401,6 @@ do_include_next (pfile)
cpp_warning (pfile, "#include_next in primary source file");
_cpp_execute_include (pfile, str, len, 0, search_start, ab);
if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (pfile);
}
/* Subroutine of do_line. Read next token from PFILE without adding it to
@ -504,6 +467,7 @@ do_line (pfile)
/* C99 raised the minimum limit on #line numbers. */
unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
int action_number = 0;
int enter = 0, leave = 0;
enum cpp_ttype type;
const U_CHAR *str;
char *fname;
@ -558,18 +522,15 @@ do_line (pfile)
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "garbage at end of #line");
/* This is somewhat questionable: change the buffer stack
depth so that output_line_command thinks we've stacked
another buffer. */
if (action_number == 1)
{
pfile->buffer_stack_depth++;
enter = 1;
cpp_make_system_header (pfile, ip, 0);
read_line_number (pfile, &action_number);
}
else if (action_number == 2)
{
pfile->buffer_stack_depth--;
leave = 1;
cpp_make_system_header (pfile, ip, 0);
read_line_number (pfile, &action_number);
}
@ -584,6 +545,11 @@ do_line (pfile)
read_line_number (pfile, &action_number);
}
if (enter && pfile->cb.enter_file)
(*pfile->cb.enter_file) (pfile);
if (leave && pfile->cb.leave_file)
(*pfile->cb.leave_file) (pfile);
done:
return;
}
@ -598,13 +564,12 @@ static void
do_error (pfile)
cpp_reader *pfile;
{
U_CHAR *text, *limit;
text = pfile->limit;
_cpp_dump_list (pfile, &pfile->token_list, pfile->first_directive_token, 0);
limit = pfile->limit;
pfile->limit = text;
cpp_error (pfile, "%.*s", (int)(limit - text), text);
if (_cpp_begin_message (pfile, ERROR, NULL, 0, 0))
{
cpp_output_list (pfile, stderr, &pfile->token_list,
pfile->first_directive_token);
putc ('\n', stderr);
}
}
/*
@ -616,13 +581,12 @@ static void
do_warning (pfile)
cpp_reader *pfile;
{
U_CHAR *text, *limit;
text = pfile->limit;
_cpp_dump_list (pfile, &pfile->token_list, pfile->first_directive_token, 0);
limit = pfile->limit;
pfile->limit = text;
cpp_warning (pfile, "%.*s", (int)(limit - text), text);
if (_cpp_begin_message (pfile, WARNING, NULL, 0, 0))
{
cpp_output_list (pfile, stderr, &pfile->token_list,
pfile->first_directive_token);
putc ('\n', stderr);
}
}
/* Report program identification. */
@ -631,15 +595,14 @@ static void
do_ident (pfile)
cpp_reader *pfile;
{
/* Next token should be a string constant. */
if (_cpp_get_token (pfile)->type == CPP_STRING)
/* And then a newline. */
if (_cpp_get_token (pfile)->type == CPP_EOF)
{
/* Good - ship it. */
pass_thru_directive (pfile);
return;
}
const cpp_token *str = _cpp_get_token (pfile);
if (str->type == CPP_STRING && _cpp_get_token (pfile)->type == CPP_EOF)
{
if (pfile->cb.ident)
(*pfile->cb.ident) (pfile, str);
return;
}
cpp_error (pfile, "invalid #ident");
}
@ -659,88 +622,154 @@ do_ident (pfile)
They return 1 if the token buffer is to be popped, 0 if not. */
struct pragma_entry
{
struct pragma_entry *next;
const char *name;
int (*handler) PARAMS ((cpp_reader *));
size_t len;
int isnspace;
union {
void (*handler) PARAMS ((cpp_reader *));
struct pragma_entry *space;
} u;
};
static int pragma_dispatch
PARAMS ((cpp_reader *, const struct pragma_entry *, const cpp_hashnode *));
static int do_pragma_once PARAMS ((cpp_reader *));
static int do_pragma_implementation PARAMS ((cpp_reader *));
static int do_pragma_poison PARAMS ((cpp_reader *));
static int do_pragma_system_header PARAMS ((cpp_reader *));
static int do_pragma_gcc PARAMS ((cpp_reader *));
static int do_pragma_dependency PARAMS ((cpp_reader *));
static const struct pragma_entry top_pragmas[] =
{
{"once", do_pragma_once},
{"implementation", do_pragma_implementation},
{"poison", do_pragma_poison},
{"GCC", do_pragma_gcc},
{NULL, NULL}
};
static const struct pragma_entry gcc_pragmas[] =
{
{"implementation", do_pragma_implementation},
{"poison", do_pragma_poison},
{"system_header", do_pragma_system_header},
{"dependency", do_pragma_dependency},
{NULL, NULL}
};
static int pragma_dispatch (pfile, table, node)
void
cpp_register_pragma (pfile, space, name, handler)
cpp_reader *pfile;
const struct pragma_entry *table;
const cpp_hashnode *node;
const char *space;
const char *name;
void (*handler) PARAMS ((cpp_reader *));
{
const U_CHAR *p = node->name;
size_t len = node->length;
struct pragma_entry **x, *new;
size_t len;
x = &pfile->pragmas;
if (space)
{
struct pragma_entry *p = pfile->pragmas;
len = strlen (space);
while (p)
{
if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
{
x = &p->u.space;
goto found;
}
p = p->next;
}
cpp_ice (pfile, "unknown #pragma namespace %s", space);
return;
}
found:
new = xnew (struct pragma_entry);
new->name = name;
new->len = strlen (name);
new->isnspace = 0;
new->u.handler = handler;
new->next = *x;
*x = new;
}
void
cpp_register_pragma_space (pfile, space)
cpp_reader *pfile;
const char *space;
{
struct pragma_entry *new;
const struct pragma_entry *p = pfile->pragmas;
size_t len = strlen (space);
while (p)
{
if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
{
cpp_ice (pfile, "#pragma namespace %s already registered", space);
return;
}
p = p->next;
}
new = xnew (struct pragma_entry);
new->name = space;
new->len = len;
new->isnspace = 1;
new->u.space = 0;
new->next = pfile->pragmas;
pfile->pragmas = new;
}
for (; table->name; table++)
if (strlen (table->name) == len && !memcmp (p, table->name, len))
return (*table->handler) (pfile);
return 0;
static void do_pragma_once PARAMS ((cpp_reader *));
static void do_pragma_poison PARAMS ((cpp_reader *));
static void do_pragma_system_header PARAMS ((cpp_reader *));
static void do_pragma_dependency PARAMS ((cpp_reader *));
void
_cpp_init_internal_pragmas (pfile)
cpp_reader *pfile;
{
/* top level */
cpp_register_pragma (pfile, 0, "poison", do_pragma_poison);
cpp_register_pragma (pfile, 0, "once", do_pragma_once);
/* GCC namespace */
cpp_register_pragma_space (pfile, "GCC");
cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison);
cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header);
cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
}
static void
do_pragma (pfile)
cpp_reader *pfile;
{
const struct pragma_entry *p;
const cpp_token *tok;
int pop;
const cpp_hashnode *node;
const U_CHAR *name;
size_t len;
p = pfile->pragmas;
new_space:
tok = _cpp_get_token (pfile);
if (tok->type == CPP_EOF)
return;
else if (tok->type != CPP_NAME)
if (tok->type != CPP_NAME)
{
cpp_error (pfile, "malformed #pragma directive");
return;
}
pop = pragma_dispatch (pfile, top_pragmas, tok->val.node);
if (!pop)
pass_thru_directive (pfile);
node = tok->val.node;
name = node->name;
len = node->length;
while (p)
{
if (strlen (p->name) == len && !memcmp (p->name, name, len))
{
if (p->isnspace)
{
p = p->u.space;
goto new_space;
}
else
{
(*p->u.handler) (pfile);
return;
}
}
p = p->next;
}
if (pfile->cb.def_pragma)
(*pfile->cb.def_pragma) (pfile);
}
static int
do_pragma_gcc (pfile)
cpp_reader *pfile;
{
const cpp_token *tok;
tok = _cpp_get_token (pfile);
if (tok->type == CPP_EOF)
return 1;
else if (tok->type != CPP_NAME)
return 0;
return pragma_dispatch (pfile, gcc_pragmas, tok->val.node);
}
static int
static void
do_pragma_once (pfile)
cpp_reader *pfile;
{
@ -755,41 +784,9 @@ do_pragma_once (pfile)
cpp_warning (pfile, "#pragma once outside include file");
else
ip->inc->cmacro = NEVER_REREAD;
return 1;
}
static int
do_pragma_implementation (pfile)
cpp_reader *pfile;
{
/* Be quiet about `#pragma implementation' for a file only if it hasn't
been included yet. */
const cpp_token *tok = _cpp_get_token (pfile);
char *copy;
if (tok->type == CPP_EOF)
return 0;
else if (tok->type != CPP_STRING
|| _cpp_get_token (pfile)->type != CPP_EOF)
{
cpp_error (pfile, "malformed #pragma implementation");
return 1;
}
/* Make a NUL-terminated copy of the string. */
copy = alloca (tok->val.str.len + 1);
memcpy (copy, tok->val.str.text, tok->val.str.len);
copy[tok->val.str.len] = '\0';
if (cpp_included (pfile, copy))
cpp_warning (pfile,
"#pragma implementation for %s appears after file is included",
copy);
return 0;
}
static int
static void
do_pragma_poison (pfile)
cpp_reader *pfile;
{
@ -797,13 +794,6 @@ do_pragma_poison (pfile)
error message. */
const cpp_token *tok;
cpp_hashnode *hp;
int writeit;
/* As a rule, don't include #pragma poison commands in output,
unless the user asks for them. */
writeit = (CPP_OPTION (pfile, debug_output)
|| CPP_OPTION (pfile, dump_macros) == dump_definitions
|| CPP_OPTION (pfile, dump_macros) == dump_names);
for (;;)
{
@ -813,7 +803,7 @@ do_pragma_poison (pfile)
if (tok->type != CPP_NAME)
{
cpp_error (pfile, "invalid #pragma poison directive");
return 1;
return;
}
hp = tok->val.node;
@ -827,7 +817,9 @@ do_pragma_poison (pfile)
hp->type = T_POISON;
}
}
return !writeit;
if (pfile->cb.poison)
(*pfile->cb.poison) (pfile);
}
/* Mark the current header as a system header. This will suppress
@ -836,7 +828,7 @@ do_pragma_poison (pfile)
conforming C, but cannot be certain that their headers appear in a
system include directory. To prevent abuse, it is rejected in the
primary source file. */
static int
static void
do_pragma_system_header (pfile)
cpp_reader *pfile;
{
@ -845,14 +837,12 @@ do_pragma_system_header (pfile)
cpp_warning (pfile, "#pragma system_header outside include file");
else
cpp_make_system_header (pfile, ip, 1);
return 1;
}
/* Check the modified date of the current include file against a specified
file. Issue a diagnostic, if the specified file is newer. We use this to
determine if a fixed header should be refixed. */
static int
static void
do_pragma_dependency (pfile)
cpp_reader *pfile;
{
@ -862,7 +852,7 @@ do_pragma_dependency (pfile)
char left, right;
if (parse_include (pfile, U"pragma dependency", 1, &name, &len, &ab))
return 1;
return;
left = ab ? '<' : '"';
right = ab ? '>' : '"';
@ -876,21 +866,13 @@ do_pragma_dependency (pfile)
cpp_warning (pfile, "current file is older than %c%.*s%c",
left, (int)len, name, right);
if (msg->type != CPP_EOF)
if (msg->type != CPP_EOF
&& _cpp_begin_message (pfile, WARNING, NULL, msg->line, msg->col))
{
U_CHAR *text, *limit;
text = pfile->limit;
_cpp_dump_list (pfile, &pfile->token_list, msg, 0);
limit = pfile->limit;
pfile->limit = text;
/* There must be something non-whitespace after. */
while (*text == ' ')
text++;
cpp_warning (pfile, "%.*s", (int)(limit - text), text);
cpp_output_list (pfile, stderr, &pfile->token_list, msg);
putc ('\n', stderr);
}
}
return 1;
}
/* Just ignore #sccs, on systems where we define it at all. */
@ -1513,15 +1495,21 @@ cpp_buffer *
cpp_pop_buffer (pfile)
cpp_reader *pfile;
{
int wfb;
cpp_buffer *buf = CPP_BUFFER (pfile);
unwind_if_stack (pfile, buf);
if (buf->inc)
wfb = (buf->inc != 0);
if (wfb)
_cpp_pop_file_buffer (pfile, buf);
CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
obstack_free (pfile->buffer_ob, buf);
pfile->buffer_stack_depth--;
if (wfb && pfile->cb.leave_file && CPP_BUFFER (pfile))
(*pfile->cb.leave_file) (pfile);
return CPP_BUFFER (pfile);
}

View File

@ -432,19 +432,9 @@ struct cpp_options
struct cpp_reader
{
/* HACK FIXME. Maybe make into cpp_printer printer later. */
cpp_printer *printer;
/* Top of buffer stack. */
cpp_buffer *buffer;
/* 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. */
unsigned int token_buffer_size;
/* End of the written part of token_buffer. */
unsigned char *limit;
/* Error counter for exit code */
unsigned int errors;
@ -523,6 +513,23 @@ struct cpp_reader
real stack. See cpplib.c */
struct obstack *buffer_ob;
/* Pragma table - dynamic, because a library user can add to the
list of recognized pragmas. */
struct pragma_entry *pragmas;
/* Call backs. */
struct {
void (*enter_file) PARAMS ((cpp_reader *));
void (*leave_file) PARAMS ((cpp_reader *));
void (*include) PARAMS ((cpp_reader *, const unsigned char *,
const unsigned char *, unsigned int, int));
void (*define) PARAMS ((cpp_reader *, cpp_hashnode *));
void (*undef) PARAMS ((cpp_reader *, cpp_hashnode *));
void (*poison) PARAMS ((cpp_reader *));
void (*ident) PARAMS ((cpp_reader *, const cpp_token *));
void (*def_pragma) PARAMS ((cpp_reader *));
} cb;
/* User visible options. */
struct cpp_options opts;
@ -563,23 +570,13 @@ struct cpp_printer
{
FILE *outf; /* stream to write to */
const char *last_fname; /* previous file name */
unsigned int last_id; /* did we just push? */
unsigned int lineno; /* line currently being written */
unsigned int written; /* low water mark in token buffer */
};
#define CPP_FATAL_LIMIT 1000
/* True if we have seen a "fatal" error. */
#define CPP_FATAL_ERRORS(READER) ((READER)->errors >= CPP_FATAL_LIMIT)
/* Macros for manipulating the token_buffer. */
/* Number of characters currently in PFILE's output buffer. */
#define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer))
#define CPP_PWRITTEN(PFILE) ((PFILE)->limit)
#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
#define CPP_BUF_LINE(BUF) ((BUF)->lineno)
@ -641,6 +638,12 @@ extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
extern void cpp_reader_init PARAMS ((cpp_reader *));
extern cpp_printer *cpp_printer_init PARAMS ((cpp_reader *, cpp_printer *));
extern void cpp_register_pragma PARAMS ((cpp_reader *,
const char *, const char *,
void (*) PARAMS ((cpp_reader *))));
extern void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *));
extern int cpp_start_read PARAMS ((cpp_reader *, cpp_printer *, const char *));
extern void cpp_output_tokens PARAMS ((cpp_reader *, cpp_printer *,
unsigned int));
@ -695,9 +698,14 @@ extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
extern void cpp_scan_buffer PARAMS ((cpp_reader *, cpp_printer *));
extern void cpp_scan_buffer_nooutput PARAMS ((cpp_reader *));
extern int cpp_scan_line PARAMS ((cpp_reader *));
extern int cpp_ideq PARAMS ((const cpp_token *,
const char *));
extern void cpp_printf PARAMS ((cpp_reader *, cpp_printer *,
const char *, ...));
extern void cpp_output_list PARAMS ((cpp_reader *, FILE *,
const cpp_toklist *,
const cpp_token *));
/* In cpphash.c */
extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *,
@ -705,11 +713,15 @@ extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *,
extern void cpp_forall_identifiers PARAMS ((cpp_reader *,
int (*) PARAMS ((cpp_reader *,
cpp_hashnode *))));
/* In cppmacro.c */
extern void cpp_dump_definition PARAMS ((cpp_reader *, FILE *,
const cpp_hashnode *));
/* In cppfiles.c */
extern int cpp_included PARAMS ((cpp_reader *, const char *));
extern int cpp_read_file PARAMS ((cpp_reader *, const char *));
extern void cpp_make_system_header PARAMS ((cpp_reader *, cpp_buffer *, int));
extern const char *cpp_syshdr_flags PARAMS ((cpp_reader *, cpp_buffer *));
#ifdef __cplusplus
}

View File

@ -40,7 +40,7 @@ struct macro_info
unsigned char flags;
};
static void dump_funlike_macro PARAMS ((cpp_reader *, cpp_hashnode *));
static void dump_macro_args PARAMS ((FILE *, const cpp_toklist *));
static void count_params PARAMS ((cpp_reader *, struct macro_info *));
static int is__va_args__ PARAMS ((cpp_reader *, const cpp_token *));
@ -554,66 +554,53 @@ _cpp_create_definition (pfile, hp)
return 1;
}
/* Dump the definition of macro MACRO on stdout. The format is suitable
to be read back in again. */
/* Dump the definition of macro MACRO on FP. The format is suitable
to be read back in again. Caller is expected to generate the
"#define NAME" bit. */
void
_cpp_dump_definition (pfile, hp)
cpp_dump_definition (pfile, fp, hp)
cpp_reader *pfile;
cpp_hashnode *hp;
FILE *fp;
const cpp_hashnode *hp;
{
CPP_RESERVE (pfile, hp->length + sizeof "#define ");
CPP_PUTS_Q (pfile, "#define ", sizeof "#define " - 1);
CPP_PUTS_Q (pfile, hp->name, hp->length);
const cpp_toklist *list = hp->value.expansion;
if (hp->type == T_MACRO)
if (hp->type != T_MACRO)
{
if (hp->value.expansion->paramc >= 0)
dump_funlike_macro (pfile, hp);
else
{
const cpp_toklist *list = hp->value.expansion;
list->tokens[0].flags &= ~BOL;
list->tokens[0].flags |= PREV_WHITE;
_cpp_dump_list (pfile, list, list->tokens, 1);
}
cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type);
return;
}
else
cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type);
if (CPP_BUFFER (pfile) == 0 || ! pfile->done_initializing)
CPP_PUTC (pfile, '\n');
if (list->paramc >= 0)
dump_macro_args (fp, list);
putc (' ', fp);
cpp_output_list (pfile, fp, list, list->tokens);
}
static void
dump_funlike_macro (pfile, node)
cpp_reader *pfile;
cpp_hashnode *node;
dump_macro_args (fp, list)
FILE *fp;
const cpp_toklist *list;
{
int i = 0;
const cpp_toklist * list = node->value.expansion;
const U_CHAR *param;
int i;
const U_CHAR *param = list->namebuf;
param = list->namebuf;
CPP_PUTC_Q (pfile, '(');
putc ('(', fp);
for (i = 0; i++ < list->paramc;)
{
unsigned int len;
len = ustrlen (param);
CPP_PUTS (pfile, param, len);
if (!list->flags & VAR_ARGS || ustrcmp (param, U"__VA_ARGS__"))
ufputs (param, fp);
if (i < list->paramc)
CPP_PUTS(pfile, ", ", 2);
fputs (", ", fp);
else if (list->flags & VAR_ARGS)
{
if (!ustrcmp (param, U"__VA_ARGS__"))
pfile->limit -= sizeof (U"__VA_ARGS__") - 1;
CPP_PUTS_Q (pfile, "...", 3);
}
fputs ("...", fp);
param += len + 1;
}
CPP_PUTC (pfile, ')');
list->tokens[0].flags &= ~BOL;
list->tokens[0].flags |= PREV_WHITE;
_cpp_dump_list (pfile, list, list->tokens, 1);
putc (')', fp);
}

View File

@ -30,8 +30,23 @@ const char *progname;
cpp_reader parse_in;
cpp_printer parse_out;
extern int main PARAMS ((int, char **));
int main PARAMS ((int, char **));
/* Callback routines for the parser. Most of these are active only
in specific modes. */
static void cb_define PARAMS ((cpp_reader *, cpp_hashnode *));
static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
const unsigned char *, unsigned int, int));
static void cb_ident PARAMS ((cpp_reader *, const cpp_token *));
static void cb_enter_file PARAMS ((cpp_reader *));
static void cb_leave_file PARAMS ((cpp_reader *));
static void cb_def_pragma PARAMS ((cpp_reader *));
static void do_pragma_implementation PARAMS ((cpp_reader *));
static int dump_macros_helper PARAMS ((cpp_reader *, cpp_hashnode *));
int
main (argc, argv)
int argc;
@ -68,8 +83,30 @@ main (argc, argv)
print = cpp_printer_init (pfile, &parse_out);
if (! print)
return (FATAL_EXIT_CODE);
if (! CPP_OPTION (pfile, no_output))
pfile->printer = print;
/* Set callbacks. */
if (! CPP_OPTION (pfile, no_line_commands)
&& ! CPP_OPTION (pfile, no_output))
{
pfile->cb.enter_file = cb_enter_file;
pfile->cb.leave_file = cb_leave_file;
}
if (CPP_OPTION (pfile, dump_includes))
pfile->cb.include = cb_include;
if (CPP_OPTION (pfile, debug_output)
|| CPP_OPTION (pfile, dump_macros) == dump_names
|| CPP_OPTION (pfile, dump_macros) == dump_definitions)
{
pfile->cb.define = cb_define;
pfile->cb.undef = cb_undef;
pfile->cb.poison = cb_def_pragma;
}
pfile->cb.ident = cb_ident;
pfile->cb.def_pragma = cb_def_pragma;
/* Register one #pragma which needs special handling. */
cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
if (! cpp_start_read (pfile, print, CPP_OPTION (pfile, in_fname)))
return (FATAL_EXIT_CODE);
@ -81,6 +118,9 @@ main (argc, argv)
while (CPP_BUFFER (pfile) != NULL)
cpp_scan_buffer (pfile, print);
if (CPP_OPTION (pfile, dump_macros) == dump_only)
cpp_forall_identifiers (pfile, dump_macros_helper);
cpp_finish (pfile, print);
cpp_cleanup (pfile);
@ -88,3 +128,137 @@ main (argc, argv)
return (FATAL_EXIT_CODE);
return (SUCCESS_EXIT_CODE);
}
/* Callbacks */
static void
cb_ident (pfile, token)
cpp_reader *pfile;
const cpp_token *token;
{
cpp_printf (pfile, &parse_out, "#ident \"%.*s\"\n",
(int) token->val.str.len, token->val.str.text);
}
static void
cb_define (pfile, hash)
cpp_reader *pfile;
cpp_hashnode *hash;
{
cpp_printf (pfile, &parse_out, "#define %s", hash->name);
if (CPP_OPTION (pfile, debug_output)
|| CPP_OPTION (pfile, dump_macros) == dump_definitions)
cpp_dump_definition (pfile, parse_out.outf, hash);
putc ('\n', parse_out.outf);
}
static void
cb_undef (pfile, hash)
cpp_reader *pfile;
cpp_hashnode *hash;
{
cpp_printf (pfile, &parse_out, "#undef %s\n", hash->name);
}
static void
cb_include (pfile, dir, str, len, ab)
cpp_reader *pfile;
const unsigned char *dir;
const unsigned char *str;
unsigned int len;
int ab;
{
int l, r;
if (ab)
l = '<', r = '>';
else
l = '"', r = '"';
cpp_printf (pfile, &parse_out, "#%s %c%.*s%c\n", dir, l, (int) len, str, r);
}
static void
cb_enter_file (pfile)
cpp_reader *pfile;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
cpp_printf (pfile, &parse_out, "# 1 \"%s\"%s%s\n", ip->nominal_fname,
pfile->done_initializing ? " 1" : "",
cpp_syshdr_flags (pfile, ip));
parse_out.lineno = 1;
parse_out.last_fname = ip->nominal_fname;
}
static void
cb_leave_file (pfile)
cpp_reader *pfile;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
cpp_printf (pfile, &parse_out, "# %u \"%s\" 2%s\n", ip->lineno,
ip->nominal_fname, cpp_syshdr_flags (pfile, ip));
parse_out.lineno = ip->lineno;
parse_out.last_fname = ip->nominal_fname;
}
static void
cb_def_pragma (pfile)
cpp_reader *pfile;
{
cpp_printf (pfile, &parse_out, "#pragma ");
cpp_output_list (pfile, parse_out.outf, &pfile->token_list,
pfile->first_directive_token);
putc ('\n', parse_out.outf);
}
static void
do_pragma_implementation (pfile)
cpp_reader *pfile;
{
/* Be quiet about `#pragma implementation' for a file only if it hasn't
been included yet. */
const cpp_token *tok = cpp_get_token (pfile);
char *copy;
if (tok->type != CPP_EOF)
{
if (tok->type != CPP_STRING || cpp_get_token (pfile)->type != CPP_EOF)
{
cpp_error (pfile, "malformed #pragma implementation");
return;
}
/* Make a NUL-terminated copy of the string. */
copy = alloca (tok->val.str.len + 1);
memcpy (copy, tok->val.str.text, tok->val.str.len);
copy[tok->val.str.len] = '\0';
if (cpp_included (pfile, copy))
cpp_warning (pfile,
"#pragma implementation for %s appears after file is included",
copy);
}
/* forward to default-pragma handler. */
cb_def_pragma (pfile);
}
/* Dump out the hash table. */
static int
dump_macros_helper (pfile, hp)
cpp_reader *pfile;
cpp_hashnode *hp;
{
if (hp->type == T_MACRO)
{
cpp_printf (pfile, &parse_out, "#define %s", hp->name);
cpp_dump_definition (pfile, parse_out.outf, hp);
putc ('\n', parse_out.outf);
}
return 1;
}

View File

@ -1,3 +0,0 @@
set torture_compile_xfail "*-*-*"
return 0