aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplex.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r--gcc/cpplex.c460
1 files changed, 210 insertions, 250 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 0ee0a3d..d7ae494 100644
--- a/gcc/cpplex.c
+++ b/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;
-{
- 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++;
+cpp_printf VPARAMS ((cpp_reader *pfile, cpp_printer *print,
+ const char *fmt, ...))
+{
+ 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;
-
- CPP_RESERVE (pfile, token->col);
- buffer = pfile->limit;
-
- while (spaces--)
- *buffer++ = ' ';
- pfile->limit = buffer;
+ int dummy;
+
+ if (token->col && (token->flags & BOL))
+ {
+ /* Supply enough whitespace to put this token in its original
+ column. Don't bother trying to reconstruct tabs; we can't
+ get it right in general, and nothing ought to care. (Yes,
+ some things do care; the fault lies with them.) */
+ unsigned int spaces = token->col - 1;
+
+ while (spaces--)
+ putc (' ', fp);
+ }
+ else if (token->flags & PREV_WHITE)
+ putc (' ', fp);
+ else
+ /* Check for and prevent accidental token pasting.
+ In addition to the cases handled by can_paste, consider
+
+ 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);
}
- else if (token->flags & PREV_WHITE)
- CPP_PUTC (pfile, ' ');
- else if (prev)
+
+ switch (TOKEN_SPELL (token))
{
- /* 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, ' ');
+ 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;
- CPP_RESERVE (pfile, TOKEN_LEN (token));
- pfile->limit = spell_token (pfile, token, pfile->limit);
+ 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. */