cpplex.c (cpp_output_tokens, [...]): New public interfaces.

* cpplex.c (cpp_output_tokens, cpp_scan_buffer_nooutput): New public
	interfaces.
	(safe_fwrite, output_line_command): New static functions.
	(cpp_expand_to_buffer): Now private to cpplib.
	(cpp_scan_buffer): Take a printer.

	* cpphash.h: Update prototypes.
	* cpplib.h: Update prototypes.
	(cpp_printer): New.
	(cpp_buffer): Remove last_nominal_fname.
	(cpp_reader): Remove lineno.

	* cppmain.c: Use a cpp_printer.
	* fix-header.c: No need to inhibit line commands.  Call
	cpp_start_read with no printer.

	* cpperror.c (cpp_notice_from_errno): Provide default name.
	* cppfiles.c (make_IHASH, _cpp_fake_ihash): New functions.
	(find_include_file, cpp_read_file): Use make_IHASH.
	(file_cleanup): Set control_macro and clear
	input_stack_listing_current here.
	(_cpp_execute_include): Don't output entering-file marker.
	* cpphash.c (special_symbol): Look for the line number in the
	buffer, not the reader.
	(_cpp_macroexpand): No need to disable line commands.
	(_cpp_dump_definition): No need to generate line commands.
	(dump_hash_helper): Remove excess newline from output.
	* cppinit.c (dump_special_to_buffer): No need to generate line
	commands.
	(cpp_printer_init): New.
	(cpp_start_read): Take a printer, and start it up if it's not
	NULL.  No need to generate line commands.
	(cpp_finish): Expect no buffers stacked at all.  Take a
	printer argument, and flush the output buffer if it's not
	NULL.
	* cpplex.c (_cpp_lex_token): Return EOF if there's no buffer.
	Don't put two hashes at the beginning of an assertion.
	(cpp_get_token): Don't increment pfile->lineno or emit line
	commands here.  Return EOF if there's no buffer when we get
	EOF.
	* cpplib.c (do_define, skip_if_group):
	No need to disable line commands.
	(_cpp_output_line_command): Delete function.
	(do_line): Don't emit line commands here, but set things up so
	they will be emitted if necessary.  Use _cpp_fake_ihash to
	make unique nominal_fnames if necessary.
	(do_elif, do_else, _cpp_handle_eof): Call cpp_error_with_line
	with 0 for column, not -1.
	(_cpp_handle_eof): Don't set the control macro here.  Don't
	clear input_stack_listing_current here.  Don't emit line
	commands.

From-SVN: r33159
This commit is contained in:
Zack Weinberg 2000-04-14 23:29:45 +00:00 committed by Zack Weinberg
parent 362c63a5e8
commit f2d5f0cca2
11 changed files with 455 additions and 371 deletions

View file

@ -1,3 +1,57 @@
2000-04-14 Zack Weinberg <zack@wolery.cumb.org>
* cpplex.c (cpp_output_tokens, cpp_scan_buffer_nooutput): New public
interfaces.
(safe_fwrite, output_line_command): New static functions.
(cpp_expand_to_buffer): Now private to cpplib.
(cpp_scan_buffer): Take a printer.
* cpphash.h: Update prototypes.
* cpplib.h: Update prototypes.
(cpp_printer): New.
(cpp_buffer): Remove last_nominal_fname.
(cpp_reader): Remove lineno.
* cppmain.c: Use a cpp_printer.
* fix-header.c: No need to inhibit line commands. Call
cpp_start_read with no printer.
* cpperror.c (cpp_notice_from_errno): Provide default name.
* cppfiles.c (make_IHASH, _cpp_fake_ihash): New functions.
(find_include_file, cpp_read_file): Use make_IHASH.
(file_cleanup): Set control_macro and clear
input_stack_listing_current here.
(_cpp_execute_include): Don't output entering-file marker.
* cpphash.c (special_symbol): Look for the line number in the
buffer, not the reader.
(_cpp_macroexpand): No need to disable line commands.
(_cpp_dump_definition): No need to generate line commands.
(dump_hash_helper): Remove excess newline from output.
* cppinit.c (dump_special_to_buffer): No need to generate line
commands.
(cpp_printer_init): New.
(cpp_start_read): Take a printer, and start it up if it's not
NULL. No need to generate line commands.
(cpp_finish): Expect no buffers stacked at all. Take a
printer argument, and flush the output buffer if it's not
NULL.
* cpplex.c (_cpp_lex_token): Return EOF if there's no buffer.
Don't put two hashes at the beginning of an assertion.
(cpp_get_token): Don't increment pfile->lineno or emit line
commands here. Return EOF if there's no buffer when we get
EOF.
* cpplib.c (do_define, skip_if_group):
No need to disable line commands.
(_cpp_output_line_command): Delete function.
(do_line): Don't emit line commands here, but set things up so
they will be emitted if necessary. Use _cpp_fake_ihash to
make unique nominal_fnames if necessary.
(do_elif, do_else, _cpp_handle_eof): Call cpp_error_with_line
with 0 for column, not -1.
(_cpp_handle_eof): Don't set the control macro here. Don't
clear input_stack_listing_current here. Don't emit line
commands.
2000-04-14 Geoff Keating <geoffk@cygnus.com>
* config/rs6000/sysv4.h (LINK_START_SOLARIS_SPEC): Define to empty

View file

@ -440,5 +440,7 @@ cpp_notice_from_errno (pfile, name)
cpp_reader *pfile;
const char *name;
{
if (name[0] == '\0')
name = "stdout";
cpp_notice (pfile, "%s: %s", name, xstrerror (errno));
}

View file

@ -34,6 +34,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static IHASH *redundant_include_p PARAMS ((cpp_reader *, IHASH *,
struct file_name_list *));
static IHASH *make_IHASH PARAMS ((const char *, const char *,
struct file_name_list *,
unsigned int, IHASH **));
static struct file_name_map *read_name_map
PARAMS ((cpp_reader *, const char *));
static char *read_filename_string PARAMS ((int, FILE *));
@ -154,6 +157,46 @@ cpp_included (pfile, fname)
return (ptr != NULL);
}
/* Create an IHASH entry and insert it in SLOT. */
static IHASH *
make_IHASH (name, fname, path, hash, slot)
const char *name, *fname;
struct file_name_list *path;
unsigned int hash;
IHASH **slot;
{
IHASH *ih;
if (path == ABSOLUTE_PATH)
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
ih->nshort = ih->name;
}
else
{
char *s;
if ((s = strstr (name, fname)) != NULL)
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
ih->nshort = ih->name + (s - name);
}
else
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
+ strlen (fname) + 1);
ih->nshort = ih->name + strlen (name) + 1;
strcpy ((char *)ih->nshort, fname);
}
}
strcpy ((char *)ih->name, name);
ih->foundhere = path;
ih->control_macro = NULL;
ih->hash = hash;
ih->next_this_file = *slot;
*slot = ih;
return ih;
}
static int
file_cleanup (pbuf, pfile)
cpp_buffer *pbuf;
@ -163,6 +206,12 @@ file_cleanup (pbuf, pfile)
free ((PTR) pbuf->buf);
if (pfile->system_include_depth)
pfile->system_include_depth--;
if (pfile->potential_control_macro)
{
pbuf->ihash->control_macro = pfile->potential_control_macro;
pfile->potential_control_macro = 0;
}
pfile->input_stack_listing_current = 0;
return 0;
}
@ -265,41 +314,34 @@ find_include_file (pfile, fname, search_start, ihash, before)
if (f == -1)
return -1;
if (path == ABSOLUTE_PATH)
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
ih->nshort = ih->name;
}
else
{
char *s;
if ((s = strstr (name, fname)) != NULL)
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
ih->nshort = ih->name + (s - name);
}
else
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
+ strlen (fname) + 1);
ih->nshort = ih->name + strlen (name) + 1;
strcpy ((char *)ih->nshort, fname);
}
}
strcpy ((char *)ih->name, name);
ih->foundhere = path;
ih->control_macro = NULL;
ih->hash = dummy.hash;
ih->next_this_file = *slot;
*slot = ih;
ih = make_IHASH (name, fname, path, dummy.hash, slot);
*before = 0;
*ihash = ih;
return f;
}
/* Create a dummy IHASH entry for FNAME, and return its name pointer.
This is used by #line. */
const char *
_cpp_fake_ihash (pfile, fname)
cpp_reader *pfile;
const char *fname;
{
IHASH *ih, **slot;
IHASH dummy;
dummy.nshort = fname;
dummy.hash = _cpp_calc_hash (fname, strlen (fname));
slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
(const void *)&dummy,
dummy.hash, 1);
if (*slot)
return (*slot)->name;
ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
return ih->name;
}
/* The file_name_map structure holds a mapping of file names for a
particular directory. This mapping is read from the file named
FILE_NAME_MAP_FILE in that directory. Such a file can be used to
@ -594,14 +636,12 @@ _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
fprintf (stderr, " %s\n", ihash->name);
}
/* Actually process the file */
/* Actually process the file. */
if (no_reinclude)
ihash->control_macro = (const U_CHAR *) "";
if (read_include_file (pfile, fd, ihash))
{
_cpp_output_line_command (pfile, enter_file);
if (angle_brackets)
pfile->system_include_depth++; /* Decremented in file_cleanup. */
}
@ -637,17 +677,7 @@ cpp_read_file (pfile, fname)
return 1; /* Already included. */
}
else
{
ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (fname));
ih->control_macro = 0;
ih->foundhere = ABSOLUTE_PATH; /* well sort of ... */
ih->hash = dummy.hash;
strcpy ((char *)ih->name, fname);
ih->nshort = ih->name;
ih->next_this_file = *slot;
*slot = ih;
}
ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
if (*fname == '\0')
f = 0;

View file

@ -911,7 +911,7 @@ special_symbol (hp, pfile)
case T_SPECLINE:
ip = cpp_file_buffer (pfile);
CPP_RESERVE (pfile, 10);
sprintf (CPP_PWRITTEN (pfile), "%u", CPP_BUF_LINE (pfile));
sprintf (CPP_PWRITTEN (pfile), "%u", CPP_BUF_LINE (ip));
CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
return;
@ -1025,7 +1025,6 @@ _cpp_macroexpand (pfile, hp)
/* Skip over the opening parenthesis. */
CPP_OPTION (pfile, discard_comments)++;
CPP_OPTION (pfile, no_line_commands)++;
pfile->no_macro_expand++;
pfile->no_directives++;
@ -1058,7 +1057,6 @@ _cpp_macroexpand (pfile, hp)
}
while (token == CPP_COMMA);
CPP_OPTION (pfile, discard_comments)--;
CPP_OPTION (pfile, no_line_commands)--;
pfile->no_macro_expand--;
pfile->no_directives--;
if (token != CPP_RPAREN)
@ -1221,9 +1219,9 @@ _cpp_macroexpand (pfile, hp)
if (args[ap->argno].expand_length < 0)
{
args[ap->argno].expanded = CPP_WRITTEN (pfile);
cpp_expand_to_buffer (pfile,
ARG_BASE + args[ap->argno].raw,
args[ap->argno].raw_length);
_cpp_expand_to_buffer (pfile,
ARG_BASE + args[ap->argno].raw,
args[ap->argno].raw_length);
args[ap->argno].expand_length
= CPP_WRITTEN (pfile) - args[ap->argno].expanded;
@ -1611,9 +1609,6 @@ _cpp_dump_definition (pfile, sym, len, defn)
long len;
DEFINITION *defn;
{
if (pfile->lineno == 0)
_cpp_output_line_command (pfile, same_file);
CPP_RESERVE (pfile, len + sizeof "#define ");
CPP_PUTS_Q (pfile, "#define ", sizeof "#define " -1);
CPP_PUTS_Q (pfile, sym, len);
@ -1691,7 +1686,7 @@ _cpp_dump_definition (pfile, sym, len, defn)
if (*x == '\r') x += 2, i -= 2;
if (i > 0) CPP_PUTS (pfile, x, i);
}
if (pfile->lineno == 0)
if (CPP_BUFFER (pfile) == 0 || ! pfile->done_initializing)
CPP_PUTC (pfile, '\n');
CPP_NUL_TERMINATE (pfile);
}
@ -1706,10 +1701,7 @@ dump_hash_helper (h, p)
cpp_reader *pfile = (cpp_reader *)p;
if (hp->type == T_MACRO)
{
_cpp_dump_definition (pfile, hp->name, hp->length, hp->value.defn);
CPP_PUTC (pfile, '\n');
}
_cpp_dump_definition (pfile, hp->name, hp->length, hp->value.defn);
return 1;
}

View file

@ -263,9 +263,6 @@ extern unsigned char _cpp_IStable[256];
#define ADJACENT_TO_MARK(PFILE) \
(CPP_BUFFER(PFILE)->cur - CPP_BUFFER(PFILE)->mark == 1)
/* Last arg to output_line_command. */
enum file_change_code {same_file, rename_file, enter_file, leave_file};
/* In cpphash.c */
extern HASHNODE *_cpp_make_hashnode PARAMS ((const U_CHAR *, size_t,
enum node_type,
@ -293,6 +290,7 @@ extern void _cpp_execute_include PARAMS ((cpp_reader *, char *,
unsigned int, int,
struct file_name_list *));
extern void _cpp_init_include_hash PARAMS ((cpp_reader *));
extern const char *_cpp_fake_ihash PARAMS ((cpp_reader *, const char *));
/* In cppexp.c */
extern int _cpp_parse_expr PARAMS ((cpp_reader *));
@ -301,6 +299,8 @@ extern int _cpp_parse_expr PARAMS ((cpp_reader *));
extern void _cpp_parse_name PARAMS ((cpp_reader *, int));
extern void _cpp_skip_rest_of_line PARAMS ((cpp_reader *));
extern void _cpp_skip_hspace PARAMS ((cpp_reader *));
extern void _cpp_expand_to_buffer PARAMS ((cpp_reader *,
const unsigned char *, int));
extern int _cpp_parse_assertion PARAMS ((cpp_reader *));
extern enum cpp_ttype _cpp_lex_token PARAMS ((cpp_reader *));
extern long _cpp_read_and_prescan PARAMS ((cpp_reader *, cpp_buffer *,
@ -315,8 +315,5 @@ extern enum cpp_ttype _cpp_get_define_token
/* In cpplib.c */
extern int _cpp_handle_directive PARAMS ((cpp_reader *));
extern void _cpp_handle_eof PARAMS ((cpp_reader *));
extern void _cpp_output_line_command PARAMS ((cpp_reader *,
enum file_change_code));
#endif

View file

@ -521,12 +521,11 @@ dump_special_to_buffer (pfile, macro_name)
{
static const char define_directive[] = "#define ";
int macro_name_length = strlen (macro_name);
_cpp_output_line_command (pfile, same_file);
CPP_RESERVE (pfile, sizeof(define_directive) + macro_name_length);
CPP_PUTS_Q (pfile, define_directive, sizeof(define_directive)-1);
CPP_PUTS_Q (pfile, macro_name, macro_name_length);
CPP_PUTC_Q (pfile, ' ');
cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
_cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
CPP_PUTC (pfile, '\n');
}
@ -554,6 +553,31 @@ cpp_reader_init (pfile)
_cpp_init_include_hash (pfile);
}
/* Initialize a cpp_printer structure. As a side effect, open the
output file. */
cpp_printer *
cpp_printer_init (pfile, print)
cpp_reader *pfile;
cpp_printer *print;
{
memset (print, '\0', sizeof (cpp_printer));
if (CPP_OPTION (pfile, out_fname) == NULL)
CPP_OPTION (pfile, out_fname) = "";
if (CPP_OPTION (pfile, out_fname)[0] == '\0')
print->outf = stdout;
else
{
print->outf = fopen (CPP_OPTION (pfile, out_fname), "w");
if (! print->outf)
{
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
return NULL;
}
}
return print;
}
/* Free resources used by PFILE.
This is the cpp_reader 'finalizer' or 'destructor' (in C++ terminology). */
void
@ -829,8 +853,9 @@ initialize_standard_includes (pfile)
*/
int
cpp_start_read (pfile, fname)
cpp_start_read (pfile, print, fname)
cpp_reader *pfile;
cpp_printer *print;
const char *fname;
{
struct pending_option *p, *q;
@ -915,6 +940,14 @@ cpp_start_read (pfile, fname)
CPP_BUFFER (pfile)->lineno = 0;
if (print)
{
print->lineno = 0;
print->last_fname = CPP_BUFFER (pfile)->nominal_fname;
print->last_bsd = pfile->buffer_stack_depth;
print->written = CPP_WRITTEN (pfile);
}
/* Install __LINE__, etc. */
initialize_builtins (pfile);
@ -927,42 +960,32 @@ cpp_start_read (pfile, fname)
free (p);
p = q;
}
pfile->done_initializing = 1;
CPP_BUFFER (pfile)->lineno = 1;
if (CPP_OPTION (pfile, preprocessed))
/* If we've already processed this code, we want to trust the #line
directives in the input. But we still need to update our line
counter accordingly. */
pfile->lineno = CPP_BUFFER (pfile)->lineno;
else
_cpp_output_line_command (pfile, same_file);
pfile->only_seen_white = 2;
CPP_BUFFER (pfile)->lineno = 1;
if (print && ! CPP_OPTION (pfile, no_output))
cpp_output_tokens (pfile, print);
/* The -imacros files can be scanned now, but the -include files
have to be pushed onto the include stack and processed later,
in the main loop calling cpp_get_token. */
CPP_OPTION (pfile, no_output)++;
p = CPP_OPTION (pfile, pending)->imacros_head;
while (p)
{
if (cpp_read_file (pfile, p->arg))
cpp_scan_buffer (pfile);
cpp_scan_buffer_nooutput (pfile);
q = p->next;
free (p);
p = q;
}
CPP_OPTION (pfile, no_output)--;
p = CPP_OPTION (pfile, pending)->include_head;
while (p)
{
if (cpp_read_file (pfile, p->arg))
_cpp_output_line_command (pfile, enter_file);
if (cpp_read_file (pfile, p->arg)
&& print && ! CPP_OPTION (pfile, no_output))
cpp_output_tokens (pfile, print);
q = p->next;
free (p);
p = q;
@ -979,13 +1002,16 @@ cpp_start_read (pfile, fname)
clear macro definitions, such that you could call cpp_start_read
with a new filename to restart processing. */
void
cpp_finish (pfile)
cpp_finish (pfile, print)
cpp_reader *pfile;
cpp_printer *print;
{
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)))
cpp_ice (pfile, "buffers still stacked in cpp_finish");
while (CPP_BUFFER (pfile))
cpp_pop_buffer (pfile);
if (CPP_BUFFER (pfile))
{
cpp_ice (pfile, "buffers still stacked in cpp_finish");
while (CPP_BUFFER (pfile))
cpp_pop_buffer (pfile);
}
/* Don't write the deps file if preprocessing has failed. */
if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0)
@ -1015,6 +1041,14 @@ cpp_finish (pfile)
if (CPP_OPTION (pfile, dump_macros) == dump_only)
_cpp_dump_macro_hash (pfile);
/* Flush any pending output. */
if (print)
{
cpp_output_tokens (pfile, print);
if (ferror (print->outf) || fclose (print->outf))
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
}
}
static void

View file

@ -47,6 +47,10 @@ static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *));
static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
static void null_warning PARAMS ((cpp_reader *, unsigned int));
static void safe_fwrite PARAMS ((cpp_reader *, const U_CHAR *,
size_t, FILE *));
static void output_line_command PARAMS ((cpp_reader *, cpp_printer *));
/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
void
@ -116,70 +120,131 @@ cpp_pop_buffer (pfile)
return CPP_BUFFER (pfile);
}
/* Scan until CPP_BUFFER (PFILE) is exhausted into PFILE->token_buffer.
Pop the buffer when done. */
void
cpp_scan_buffer (pfile)
/* 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;
{
cpp_buffer *buffer = CPP_BUFFER (pfile);
enum cpp_ttype token;
if (CPP_OPTION (pfile, no_output))
size_t count;
while (len)
{
long old_written = CPP_WRITTEN (pfile);
/* In no-output mode, we can ignore everything but directives. */
for (;;)
{
if (! pfile->only_seen_white)
_cpp_skip_rest_of_line (pfile);
token = cpp_get_token (pfile);
if (token == CPP_EOF) /* Should not happen ... */
break;
if (token == CPP_POP && CPP_BUFFER (pfile) == buffer)
{
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) != NULL)
cpp_pop_buffer (pfile);
break;
}
}
CPP_SET_WRITTEN (pfile, old_written);
}
else
{
for (;;)
{
token = cpp_get_token (pfile);
if (token == CPP_EOF) /* Should not happen ... */
break;
if (token == CPP_POP && CPP_BUFFER (pfile) == buffer)
{
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) != NULL)
cpp_pop_buffer (pfile);
break;
}
}
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));
}
/*
* Rescan a string (which may have escape marks) into pfile's buffer.
* Place the result in pfile->token_buffer.
*
* The input is copied before it is scanned, so it is safe to pass
* it something from the token_buffer that will get overwritten
* (because it follows CPP_WRITTEN). This is used by do_include.
*/
/* Notify the compiler proper that the current line number has jumped,
or the current file name has changed. */
static void
output_line_command (pfile, print)
cpp_reader *pfile;
cpp_printer *print;
{
unsigned int line;
cpp_buffer *ip;
enum { same = 0, enter, leave, rname } change;
static const char * const codes[] = { "", " 1", " 2", "" };
if (CPP_OPTION (pfile, no_line_commands))
return;
ip = cpp_file_buffer (pfile);
if (ip == NULL)
return;
line = CPP_BUF_LINE (ip);
// fprintf (print->outf, "[%u %u", print->lineno, line);
/* 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
{
if (pfile->buffer_stack_depth == print->last_bsd)
change = rname;
else
{
if (pfile->buffer_stack_depth > print->last_bsd)
change = enter;
else
change = leave;
print->last_bsd = pfile->buffer_stack_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
&& line >= print->lineno && line < print->lineno + 8)
{
while (line > print->lineno)
{
putc ('\n', print->outf);
print->lineno++;
}
// putc(']', print->outf);
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->system_header_p ? " 3" : "",
(ip->system_header_p == 2) ? " 4" : "");
else
#endif
fprintf (print->outf, "# %u \"%s\"%s%s\n", line, ip->nominal_fname,
codes[change],
ip->system_header_p ? " 3" : "");
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. */
void
cpp_expand_to_buffer (pfile, buf, length)
cpp_output_tokens (pfile, print)
cpp_reader *pfile;
cpp_printer *print;
{
if (CPP_PWRITTEN (pfile)[-1] == '\n' && print->lineno)
print->lineno++;
safe_fwrite (pfile, pfile->token_buffer,
CPP_WRITTEN (pfile) - print->written, print->outf);
output_line_command (pfile, print);
CPP_SET_WRITTEN (pfile, print->written);
}
/* Scan a string (which may have escape marks), perform macro expansion,
and write the result to the token_buffer. */
void
_cpp_expand_to_buffer (pfile, buf, length)
cpp_reader *pfile;
const U_CHAR *buf;
int length;
{
register cpp_buffer *ip;
U_CHAR *buf1;
int save_no_output;
cpp_buffer *ip;
enum cpp_ttype token;
if (length < 0)
{
@ -188,27 +253,85 @@ cpp_expand_to_buffer (pfile, buf, length)
}
/* Set up the input on the input stack. */
buf1 = (U_CHAR *) alloca (length + 1);
memcpy (buf1, buf, length);
buf1[length] = 0;
ip = cpp_push_buffer (pfile, buf1, length);
ip = cpp_push_buffer (pfile, buf, length);
if (ip == NULL)
return;
ip->has_escapes = 1;
/* Scan the input, create the output. */
save_no_output = CPP_OPTION (pfile, no_output);
CPP_OPTION (pfile, no_output) = 0;
CPP_OPTION (pfile, no_line_commands)++;
cpp_scan_buffer (pfile);
CPP_OPTION (pfile, no_line_commands)--;
CPP_OPTION (pfile, no_output) = save_no_output;
for (;;)
{
token = cpp_get_token (pfile);
if (token == CPP_EOF)
break;
if (token == CPP_POP && CPP_BUFFER (pfile) == ip)
{
cpp_pop_buffer (pfile);
break;
}
}
CPP_NUL_TERMINATE (pfile);
}
/* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output.
Then pop the buffer. */
void
cpp_scan_buffer_nooutput (pfile)
cpp_reader *pfile;
{
cpp_buffer *buffer = CPP_BUFFER (pfile);
enum cpp_ttype token;
unsigned int old_written = CPP_WRITTEN (pfile);
/* In no-output mode, we can ignore everything but directives. */
for (;;)
{
if (! pfile->only_seen_white)
_cpp_skip_rest_of_line (pfile);
token = cpp_get_token (pfile);
if (token == CPP_EOF)
break;
if (token == CPP_POP && CPP_BUFFER (pfile) == buffer)
{
cpp_pop_buffer (pfile);
break;
}
}
CPP_SET_WRITTEN (pfile, old_written);
}
/* Scan until CPP_BUFFER (pfile) is exhausted, writing output to PRINT.
Then pop the buffer. */
void
cpp_scan_buffer (pfile, print)
cpp_reader *pfile;
cpp_printer *print;
{
cpp_buffer *buffer = CPP_BUFFER (pfile);
enum cpp_ttype token;
for (;;)
{
token = cpp_get_token (pfile);
if ((token == CPP_POP && !CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
|| token == CPP_EOF || token == CPP_VSPACE
/* XXX Temporary kluge - force flush after #include only */
|| (token == CPP_DIRECTIVE
&& CPP_BUFFER (pfile)->nominal_fname != print->last_fname))
{
cpp_output_tokens (pfile, print);
if (token == CPP_EOF)
return;
if (token == CPP_POP && CPP_BUFFER (pfile) == buffer)
{
cpp_pop_buffer (pfile);
return;
}
}
}
}
/* Return the topmost cpp_buffer that corresponds to a file (not a macro). */
cpp_buffer *
@ -706,6 +829,9 @@ _cpp_lex_token (pfile)
register int c, c2;
enum cpp_ttype token;
if (CPP_BUFFER (pfile) == NULL)
return CPP_EOF;
get_next:
c = GETC();
switch (c)
@ -749,6 +875,7 @@ _cpp_lex_token (pfile)
hash:
if (pfile->parsing_if_directive)
{
CPP_ADJUST_WRITTEN (pfile, -1);
if (_cpp_parse_assertion (pfile))
return CPP_ASSERTION;
return CPP_OTHER;
@ -1227,12 +1354,6 @@ cpp_get_token (pfile)
if (pfile->only_seen_white == 0)
pfile->only_seen_white = 1;
CPP_BUMP_LINE (pfile);
if (! CPP_OPTION (pfile, no_line_commands))
{
pfile->lineno++;
if (CPP_BUFFER (pfile)->lineno != pfile->lineno)
_cpp_output_line_command (pfile, same_file);
}
return token;
case CPP_HSPACE:
@ -1256,15 +1377,15 @@ cpp_get_token (pfile)
return CPP_NAME;
case CPP_EOF:
if (CPP_BUFFER (pfile) == NULL)
return CPP_EOF;
if (CPP_BUFFER (pfile)->manual_pop)
/* If we've been reading from redirected input, the
frontend will pop the buffer. */
return CPP_EOF;
else if (CPP_BUFFER (pfile)->seen_eof)
{
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) == NULL)
return CPP_EOF;
if (CPP_BUFFER (pfile)->seen_eof)
{
cpp_pop_buffer (pfile);
goto get_next;
}

View file

@ -352,7 +352,6 @@ do_define (pfile)
pfile->no_macro_expand++;
pfile->parsing_define_directive++;
CPP_OPTION (pfile, discard_comments)++;
CPP_OPTION (pfile, no_line_commands)++;
here = CPP_WRITTEN (pfile);
len = get_macro_name (pfile);
@ -453,85 +452,9 @@ do_define (pfile)
pfile->no_macro_expand--;
pfile->parsing_define_directive--;
CPP_OPTION (pfile, discard_comments)--;
CPP_OPTION (pfile, no_line_commands)--;
return 0;
}
/*
* write out a #line command, for instance, after an #include file.
* FILE_CHANGE says whether we are entering a file, leaving, or neither.
*/
void
_cpp_output_line_command (pfile, file_change)
cpp_reader *pfile;
enum file_change_code file_change;
{
unsigned int line;
cpp_buffer *ip;
if (CPP_OPTION (pfile, no_line_commands)
|| CPP_OPTION (pfile, no_output))
return;
ip = cpp_file_buffer (pfile);
line = ip->lineno;
/* If the current file has not changed, we omit the #line if it would
appear to be a no-op, and we output a few newlines instead
if we want to increase the line number by a small amount.
We cannot do this if pfile->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 (file_change == same_file && pfile->lineno != 0)
{
if (line == pfile->lineno)
return;
/* If the inherited line number is a little too small,
output some newlines instead of a #line command. */
if (line > pfile->lineno && line < pfile->lineno + 8)
{
CPP_RESERVE (pfile, 20);
while (line > pfile->lineno)
{
CPP_PUTC_Q (pfile, '\n');
pfile->lineno++;
}
return;
}
}
CPP_RESERVE (pfile, 4 * strlen (ip->nominal_fname) + 50);
CPP_PUTS_Q (pfile, "# ", 2);
sprintf ((char *) CPP_PWRITTEN (pfile), "%u ", line);
CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile)));
_cpp_quote_string (pfile, ip->nominal_fname);
if (file_change != same_file && file_change != rename_file)
{
CPP_PUTC_Q (pfile, ' ');
CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2');
}
/* Tell cc1 if following text comes from a system header file. */
if (ip->system_header_p)
{
CPP_PUTC_Q (pfile, ' ');
CPP_PUTC_Q (pfile, '3');
}
#ifndef NO_IMPLICIT_EXTERN_C
/* Tell cc1plus if following text should be treated as C. */
if (ip->system_header_p == 2 && CPP_OPTION (pfile, cplusplus))
{
CPP_PUTC_Q (pfile, ' ');
CPP_PUTC_Q (pfile, '4');
}
#endif
CPP_PUTC_Q (pfile, '\n');
pfile->lineno = line;
}
/* Handle #include and #import. */
static unsigned int
@ -713,9 +636,8 @@ do_line (pfile)
cpp_reader *pfile;
{
cpp_buffer *ip = CPP_BUFFER (pfile);
int new_lineno;
unsigned int new_lineno;
long old_written = CPP_WRITTEN (pfile);
enum file_change_code file_change = same_file;
enum cpp_ttype token;
char *x;
@ -727,7 +649,7 @@ do_line (pfile)
goto bad_line_directive;
}
new_lineno = strtol (pfile->token_buffer + old_written, &x, 10);
new_lineno = strtoul (pfile->token_buffer + old_written, &x, 10);
if (x[0] != '\0')
{
cpp_error (pfile, "token after `#line' is not an integer");
@ -746,21 +668,22 @@ do_line (pfile)
U_CHAR *end_name = CPP_PWRITTEN (pfile) - 1;
int action_number = 0;
file_change = rename_file;
if (read_line_number (pfile, &action_number))
{
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "garbage at end of `#line' command");
/* This is somewhat questionable: change the buffer stack
depth so that output_line_command thinks we've stacked
another buffer. */
if (action_number == 1)
{
file_change = enter_file;
pfile->buffer_stack_depth++;
read_line_number (pfile, &action_number);
}
else if (action_number == 2)
{
file_change = leave_file;
pfile->buffer_stack_depth--;
read_line_number (pfile, &action_number);
}
if (action_number == 3)
@ -779,29 +702,11 @@ do_line (pfile)
if (strcmp (fname, ip->nominal_fname))
{
const char *newname, *oldname;
if (!strcmp (fname, ip->ihash->name))
newname = ip->ihash->name;
else if (ip->last_nominal_fname
&& !strcmp (fname, ip->last_nominal_fname))
newname = ip->last_nominal_fname;
ip->nominal_fname = ip->ihash->name;
else
newname = xstrdup (fname);
oldname = ip->nominal_fname;
ip->nominal_fname = newname;
if (ip->last_nominal_fname
&& ip->last_nominal_fname != oldname
&& ip->last_nominal_fname != newname
&& ip->last_nominal_fname != ip->ihash->name)
free ((void *) ip->last_nominal_fname);
if (newname == ip->ihash->name)
ip->last_nominal_fname = NULL;
else
ip->last_nominal_fname = oldname;
}
ip->nominal_fname = _cpp_fake_ihash (pfile, fname);
}
}
else if (token != CPP_VSPACE && token != CPP_EOF)
{
@ -814,7 +719,6 @@ do_line (pfile)
we must store a line number now that is one less. */
ip->lineno = new_lineno - 1;
CPP_SET_WRITTEN (pfile, old_written);
_cpp_output_line_command (pfile, file_change);
return 0;
bad_line_directive:
@ -1259,7 +1163,7 @@ do_elif (pfile)
if (pfile->if_stack->type == T_ELSE)
{
cpp_error (pfile, "`#elif' after `#else'");
cpp_error_with_line (pfile, pfile->if_stack->lineno, -1,
cpp_error_with_line (pfile, pfile->if_stack->lineno, 0,
"the conditional began here");
}
pfile->if_stack->type = T_ELIF;
@ -1506,7 +1410,6 @@ skip_if_group (pfile)
old_written = CPP_WRITTEN (pfile);
pfile->no_macro_expand++;
CPP_OPTION (pfile, no_line_commands)++;
for (;;)
{
/* We are at the end of a line. Only cpp_get_token knows how to
@ -1514,7 +1417,6 @@ skip_if_group (pfile)
token = cpp_get_token (pfile);
if (token == CPP_POP)
break; /* Caller will issue error. */
else if (token != CPP_VSPACE)
cpp_ice (pfile, "cpp_get_token returned %d in skip_if_group", token);
CPP_SET_WRITTEN (pfile, old_written);
@ -1533,7 +1435,6 @@ skip_if_group (pfile)
}
CPP_SET_WRITTEN (pfile, old_written);
pfile->no_macro_expand--;
CPP_OPTION (pfile, no_line_commands)--;
return ret;
}
@ -1565,7 +1466,7 @@ do_else (pfile)
if (pfile->if_stack->type == T_ELSE)
{
cpp_error (pfile, "`#else' after `#else'");
cpp_error_with_line (pfile, pfile->if_stack->lineno, -1,
cpp_error_with_line (pfile, pfile->if_stack->lineno, 0,
"the conditional began here");
}
pfile->if_stack->type = T_ELSE;
@ -1628,7 +1529,6 @@ void
_cpp_handle_eof (pfile)
cpp_reader *pfile;
{
cpp_buffer *next_buf = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
struct if_stack *ifs, *nifs;
/* Unwind the conditional stack and generate error messages. */
@ -1636,7 +1536,7 @@ _cpp_handle_eof (pfile)
ifs != CPP_BUFFER (pfile)->if_stack;
ifs = nifs)
{
cpp_error_with_line (pfile, ifs->lineno, -1,
cpp_error_with_line (pfile, ifs->lineno, 0,
"unterminated `#%s' conditional",
dtable[ifs->type].name);
@ -1644,26 +1544,6 @@ _cpp_handle_eof (pfile)
free (ifs);
}
pfile->if_stack = ifs;
if (pfile->potential_control_macro)
{
CPP_BUFFER (pfile)->ihash->control_macro
= pfile->potential_control_macro;
pfile->potential_control_macro = 0;
}
if (CPP_BUFFER (pfile)->nominal_fname && next_buf != NULL)
{
/* We're about to return from an #include file.
Emit #line information now (as part of the CPP_POP) result.
But the #line refers to the file we will pop to. */
cpp_buffer *cur_buffer = CPP_BUFFER (pfile);
CPP_BUFFER (pfile) = next_buf;
pfile->input_stack_listing_current = 0;
_cpp_output_line_command (pfile, leave_file);
CPP_BUFFER (pfile) = cur_buffer;
}
CPP_BUFFER (pfile)->seen_eof = 1;
}

View file

@ -31,6 +31,7 @@ extern "C" {
typedef struct cpp_reader cpp_reader;
typedef struct cpp_buffer cpp_buffer;
typedef struct cpp_options cpp_options;
typedef struct cpp_printer cpp_printer;
enum cpp_ttype
{
@ -74,8 +75,6 @@ struct cpp_buffer
/* Filename specified with #line command. */
const char *nominal_fname;
/* Last filename specified with #line command. */
const char *last_nominal_fname;
/* Actual directory of this file, used only for "" includes */
struct file_name_list *actual_dir;
@ -98,6 +97,8 @@ struct cpp_buffer
/* True if this is a header file included using <FILENAME>. */
char system_header_p;
/* True if end-of-file has already been hit once in this buffer. */
char seen_eof;
/* True if buffer contains escape sequences.
@ -352,8 +353,6 @@ struct cpp_reader
struct if_stack *if_stack;
const unsigned char *potential_control_macro;
unsigned int lineno;
/* Buffer of -M output. */
struct deps *deps;
@ -402,6 +401,19 @@ struct cpp_reader
unsigned char done_initializing;
};
/* struct cpp_printer encapsulates state used to convert the stream of
tokens coming from cpp_get_token back into a text file. Not
everyone wants to do that, hence we separate the function. */
struct cpp_printer
{
FILE *outf; /* stream to write to */
const char *last_fname; /* previous file name */
unsigned int last_bsd; /* 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)
@ -427,9 +439,11 @@ extern enum cpp_ttype cpp_get_token PARAMS ((cpp_reader *));
extern enum cpp_ttype cpp_get_non_space_token PARAMS ((cpp_reader *));
extern void cpp_reader_init PARAMS ((cpp_reader *));
extern int cpp_start_read PARAMS ((cpp_reader *, const char *));
extern void cpp_finish PARAMS ((cpp_reader *));
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
extern cpp_printer *cpp_printer_init PARAMS ((cpp_reader *, cpp_printer *));
extern int cpp_start_read PARAMS ((cpp_reader *, cpp_printer *, const char *));
extern void cpp_output_tokens PARAMS ((cpp_reader *, cpp_printer *));
extern void cpp_finish PARAMS ((cpp_reader *, cpp_printer *));
extern void cpp_cleanup PARAMS ((cpp_reader *));
extern cpp_buffer *cpp_file_buffer PARAMS((cpp_reader *));
extern void cpp_define PARAMS ((cpp_reader *, const char *));
@ -463,17 +477,19 @@ extern void cpp_pedwarn_with_line PARAMS ((cpp_reader *, int, int, const char *m
ATTRIBUTE_PRINTF_4;
extern void cpp_pedwarn_with_file_and_line PARAMS ((cpp_reader *, const char *, int, int, const char *msgid, ...))
ATTRIBUTE_PRINTF_5;
extern void cpp_error_from_errno PARAMS ((cpp_reader *, const char *));
extern void cpp_notice_from_errno PARAMS ((cpp_reader *, const char *));
extern void cpp_error_from_errno PARAMS ((cpp_reader *, const char *));
extern void cpp_notice_from_errno PARAMS ((cpp_reader *, const char *));
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
const unsigned char *, long));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
/* In cpplex.c */
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
const unsigned char *, long));
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 void cpp_expand_to_buffer PARAMS ((cpp_reader *,
/* In cpphash.c */
extern int cpp_defined PARAMS ((cpp_reader *,
const unsigned char *, int));
extern void cpp_scan_buffer PARAMS ((cpp_reader *));
/* In cppfiles.c */
extern int cpp_included PARAMS ((cpp_reader *, const char *));

View file

@ -28,6 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
const char *progname;
cpp_reader parse_in;
cpp_printer parse_out;
extern int main PARAMS ((int, char **));
@ -38,10 +39,8 @@ main (argc, argv)
{
char *p;
cpp_reader *pfile = &parse_in;
cpp_printer *print;
int argi = 1; /* Next argument to handle. */
enum cpp_ttype kind;
FILE *out;
const char *out_fname;
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && p[-1] != '/') --p;
@ -63,64 +62,24 @@ main (argc, argv)
if (CPP_FATAL_ERRORS (pfile))
return (FATAL_EXIT_CODE);
if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
/* Open the output now. We must do so even if no_output is on,
because there may be other output than from the actual
preprocessing (e.g. from -dM). */
print = cpp_printer_init (pfile, &parse_out);
if (! print)
return (FATAL_EXIT_CODE);
/* Now that we know the input file is valid, open the output. */
out_fname = CPP_OPTION (pfile, out_fname);
if (*out_fname == '\0')
{
out_fname = "stdout";
out = stdout;
}
if (! cpp_start_read (pfile, print, CPP_OPTION (pfile, in_fname)))
return (FATAL_EXIT_CODE);
if (CPP_OPTION (pfile, no_output))
while (CPP_BUFFER (pfile) != NULL)
cpp_scan_buffer_nooutput (pfile);
else
{
out = fopen (out_fname, "w");
if (!out)
{
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
return (FATAL_EXIT_CODE);
}
}
if (! CPP_OPTION (pfile, no_output))
{
do
{
kind = cpp_get_token (pfile);
if (CPP_WRITTEN (pfile) >= BUFSIZ || kind == CPP_EOF)
{
size_t rem, count = CPP_WRITTEN (pfile);
rem = fwrite (parse_in.token_buffer, 1, count, out);
if (rem < count)
/* Write error. */
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
CPP_SET_WRITTEN (pfile, 0);
}
}
while (kind != CPP_EOF);
}
else
{
do
{
cpp_scan_buffer (pfile);
kind = cpp_get_token (pfile);
}
while (kind != CPP_EOF);
CPP_SET_WRITTEN (pfile, 0);
}
cpp_finish (pfile);
if (fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (pfile), out)
< CPP_WRITTEN (pfile))
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
if (ferror (out) || fclose (out))
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
while (CPP_BUFFER (pfile) != NULL)
cpp_scan_buffer (pfile, print);
cpp_finish (pfile, print);
cpp_cleanup (pfile);
if (parse_in.errors)

View file

@ -628,14 +628,13 @@ read_scan_file (in_fname, argc, argv)
so ignore warnings and errors. */
CPP_OPTION (&scan_in, inhibit_warnings) = 1;
CPP_OPTION (&scan_in, inhibit_errors) = 1;
CPP_OPTION (&scan_in, no_line_commands) = 1;
i = cpp_handle_options (&scan_in, argc, argv);
if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
if (CPP_FATAL_ERRORS (&scan_in))
exit (FATAL_EXIT_CODE);
if (! cpp_start_read (&scan_in, in_fname))
if (! cpp_start_read (&scan_in, 0, in_fname))
exit (FATAL_EXIT_CODE);
scan_decls (&scan_in, argc, argv);