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:
parent
8cd8f856b3
commit
58fea6afd9
169
gcc/cpperror.c
169
gcc/cpperror.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
458
gcc/cpplex.c
458
gcc/cpplex.c
|
@ -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--)
|
||||
*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, ' ');
|
||||
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
|
||||
|
||||
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. */
|
||||
|
||||
|
|
368
gcc/cpplib.c
368
gcc/cpplib.c
|
@ -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;
|
||||
|
||||
for (; table->name; table++)
|
||||
if (strlen (table->name) == len && !memcmp (p, table->name, len))
|
||||
return (*table->handler) (pfile);
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
54
gcc/cpplib.h
54
gcc/cpplib.h
|
@ -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);
|
||||
}
|
||||
|
|
182
gcc/cppmain.c
182
gcc/cppmain.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
set torture_compile_xfail "*-*-*"
|
||||
|
||||
return 0
|
Loading…
Reference in New Issue