Commit 58fea6af by Zack Weinberg

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
parent 8cd8f856
......@@ -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,70 +91,101 @@ 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;
if (ip)
switch (code)
{
if (file == NULL)
file = ip->nominal_fname;
if (line == 0)
line = _cpp_get_line (pfile, &col);
print_containing_files (pfile, ip);
print_file_and_line (file, line,
CPP_OPTION (pfile, show_column) ? col : 0);
}
else
fprintf (stderr, "%s: ", progname);
switch (is_error)
{
case 0:
case WARNING:
if (! CPP_OPTION (pfile, warnings_are_errors))
{
fprintf (stderr, _("warning: "));
break;
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 fall through */
case 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;
case 2:
/* Fatal errors cannot be inhibited. */
case FATAL:
pfile->errors = CPP_FATAL_LIMIT;
break;
case 3:
case ICE:
fprintf (stderr, _("internal error: "));
pfile->errors = CPP_FATAL_LIMIT;
break;
default:
cpp_ice (pfile, "bad is_error(%d) in v_message", is_error);
}
vfprintf (stderr, _(msg), ap);
putc ('\n', stderr);
if (ip)
{
if (file == NULL)
file = ip->nominal_fname;
if (line == 0)
line = _cpp_get_line (pfile, &col);
print_containing_files (pfile, ip);
print_file_and_line (file, line,
CPP_OPTION (pfile, show_column) ? col : 0);
}
else
fprintf (stderr, "%s: ", progname);
if (is_warning)
fputs (_("warning: "), 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);
}
......
......@@ -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:
......
......@@ -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
......@@ -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));
}
......
......@@ -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
}
......
......@@ -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);
}
......@@ -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;
}
set torture_compile_xfail "*-*-*"
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