aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNeil Booth <neilb@earthling.net>2000-09-25 22:34:53 +0000
committerNeil Booth <neil@gcc.gnu.org>2000-09-25 22:34:53 +0000
commit7de4d00450a017b0edbbbf620dcfc5d9326f163c (patch)
treee04909d8f7efef588ecf5b034183af04dbc5316d /gcc
parentdcbd43e030914368ca0b5c089dc32cf8a208113d (diff)
downloadgcc-7de4d00450a017b0edbbbf620dcfc5d9326f163c.zip
gcc-7de4d00450a017b0edbbbf620dcfc5d9326f163c.tar.gz
gcc-7de4d00450a017b0edbbbf620dcfc5d9326f163c.tar.bz2
cpphash.h (_cpp_digraph_spellings, [...]): New library-internal prototypes.
* cpphash.h (_cpp_digraph_spellings, _cpp_process_directive, _cpp_can_paste): New library-internal prototypes. * cpplex.c (dump_param_spelling, output_line_command, output_token, cpp_scan_buffer, cpp_scan_buffer_nooutput, cpp_printf, cpp_output_list): Move to cppoutput.c. (process_directive, can_paste, digraph_spellings): Add _cpp_ prefix. * cppmacro.c (dump_macro_args, cpp_dump_definition) Move to cppoutput.c. * cppoutput.c (dump_macro_args, cpp_dump_definition, output_token, dump_param_spelling, output_line_command, cpp_scan_buffer, cpp_scan_buffer_nooutput, cpp_printf, cpp_output_list): Moved from elsewhere. * Makefile.in: Add cppoutput.c. * po/POTFILES.in: Add cppoutput.c. From-SVN: r36634
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/cpphash.h4
-rw-r--r--gcc/cpplex.c336
-rw-r--r--gcc/cppmacro.c52
-rw-r--r--gcc/cppoutput.c390
-rw-r--r--gcc/po/POTFILES.in1
7 files changed, 423 insertions, 380 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d80a03c..17a3315 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+Mon 25-Sep-2000 23:31:45 BST Neil Booth <neilb@earthling.net>
+
+ * cpphash.h (_cpp_digraph_spellings, _cpp_process_directive,
+ _cpp_can_paste): New library-internal prototypes.
+ * cpplex.c (dump_param_spelling, output_line_command,
+ output_token, cpp_scan_buffer, cpp_scan_buffer_nooutput,
+ cpp_printf, cpp_output_list): Move to cppoutput.c.
+ (process_directive, can_paste, digraph_spellings): Add _cpp_ prefix.
+ * cppmacro.c (dump_macro_args, cpp_dump_definition) Move to
+ cppoutput.c.
+ * cppoutput.c (dump_macro_args, cpp_dump_definition, output_token,
+ dump_param_spelling, output_line_command, cpp_scan_buffer,
+ cpp_scan_buffer_nooutput, cpp_printf, cpp_output_list): Moved
+ from elsewhere.
+ * Makefile.in: Add cppoutput.c.
+ * po/POTFILES.in: Add cppoutput.c.
+
2000-09-25 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64.c (ia64_print_operand): Define 'e' as 64-n.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 953fab18..f5cd9dc 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1792,7 +1792,7 @@ PREPROCESSOR_DEFINES = \
-DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\"
LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \
- cpphash.o cpperror.o cppinit.o cppdefault.o \
+ cpphash.o cpperror.o cppinit.o cppdefault.o cppoutput.o \
mkdeps.o prefix.o version.o mbchar.o @extra_cpp_objs@
LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
@@ -1814,6 +1814,7 @@ cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS) defaults.h
cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS)
cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS)
+cppoutput.o: cppoutput.c $(CONFIG_H) $(LIBCPP_DEPS)
cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 8f569e7..fed1cf4 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -231,6 +231,7 @@ extern void _cpp_pop_file_buffer PARAMS ((cpp_reader *, cpp_buffer *));
extern int _cpp_parse_expr PARAMS ((cpp_reader *));
/* In cpplex.c */
+extern const unsigned char *_cpp_digraph_spellings[];
extern void _cpp_skip_rest_of_line PARAMS ((cpp_reader *));
extern void _cpp_free_temp_tokens PARAMS ((cpp_reader *));
extern void _cpp_init_input_buffer PARAMS ((cpp_reader *));
@@ -247,6 +248,7 @@ extern void _cpp_reserve_name_space PARAMS ((cpp_toklist *, unsigned int));
extern void _cpp_expand_name_space PARAMS ((cpp_toklist *, unsigned int));
extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
const cpp_token *));
+extern void _cpp_process_directive PARAMS ((cpp_reader *, const cpp_token *));
extern void _cpp_run_directive PARAMS ((cpp_reader *,
const struct directive *,
const char *, size_t,
@@ -257,6 +259,8 @@ extern const cpp_token *_cpp_get_token PARAMS ((cpp_reader *));
extern const cpp_token *_cpp_get_raw_token PARAMS ((cpp_reader *));
extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token*));
extern const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *));
+extern enum cpp_ttype _cpp_can_paste PARAMS ((cpp_reader *, const cpp_token *,
+ const cpp_token *, int *));
/* In cpplib.c */
extern const struct directive *_cpp_check_directive
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 720574b..c07c721 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -41,6 +41,8 @@ o Correct pastability test for CPP_NAME and CPP_NUMBER.
#include "cpphash.h"
#include "symcat.h"
+const unsigned char *_cpp_digraph_spellings [] = {U"%:", U"%:%:", U"<:",
+ U":>", U"<%", U"%>"};
static const cpp_token placemarker_token = {0, 0, CPP_PLACEMARKER,
0 UNION_INIT_ZERO};
static const cpp_token eof_token = {0, 0, CPP_EOF, 0 UNION_INIT_ZERO};
@@ -90,10 +92,6 @@ static int pop_context PARAMS ((cpp_reader *));
static int push_macro_context PARAMS ((cpp_reader *, const cpp_token *));
static void push_arg_context PARAMS ((cpp_reader *, const cpp_token *));
static void free_macro_args PARAMS ((macro_args *));
-static void dump_param_spelling PARAMS ((FILE *, const cpp_toklist *,
- unsigned int));
-static void output_line_command PARAMS ((cpp_reader *, cpp_printer *,
- unsigned int));
static cppchar_t handle_newline PARAMS ((cpp_buffer *, cppchar_t));
static cppchar_t skip_escaped_newlines PARAMS ((cpp_buffer *, cppchar_t));
@@ -115,7 +113,6 @@ static void lex_line PARAMS ((cpp_reader *, cpp_toklist *));
static void lex_token PARAMS ((cpp_reader *, cpp_token *));
static int lex_next PARAMS ((cpp_reader *, int));
-static void process_directive PARAMS ((cpp_reader *, const cpp_token *));
static int is_macro_disabled PARAMS ((cpp_reader *, const cpp_toklist *,
const cpp_token *));
@@ -123,8 +120,6 @@ 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 *, 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 *,
@@ -135,14 +130,11 @@ static const cpp_token *special_symbol PARAMS ((cpp_reader *, cpp_hashnode *,
static cpp_token *duplicate_token PARAMS ((cpp_reader *, const cpp_token *));
static const cpp_token *maybe_paste_with_next PARAMS ((cpp_reader *,
const cpp_token *));
-static enum cpp_ttype can_paste PARAMS ((cpp_reader *, const cpp_token *,
- const cpp_token *, int *));
static unsigned int prevent_macro_expansion PARAMS ((cpp_reader *));
static void restore_macro_expansion PARAMS ((cpp_reader *, unsigned int));
static cpp_token *get_temp_token PARAMS ((cpp_reader *));
static void release_temp_tokens PARAMS ((cpp_reader *));
static U_CHAR * quote_string PARAMS ((U_CHAR *, const U_CHAR *, unsigned int));
-static void process_directive PARAMS ((cpp_reader *, const cpp_token *));
#define VALID_SIGN(c, prevc) \
(((c) == '+' || (c) == '-') && \
@@ -194,167 +186,6 @@ _cpp_token_spellings [N_TTYPES] = {TTYPE_TABLE };
#undef OP
#undef TK
-/* 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, line)
- cpp_reader *pfile;
- cpp_printer *print;
- unsigned int line;
-{
- cpp_buffer *ip = CPP_BUFFER (pfile);
-
- if (line == 0)
- return;
-
- /* End the previous line of text. */
- if (pfile->need_newline)
- {
- putc ('\n', print->outf);
- print->lineno++;
- }
- pfile->need_newline = 0;
-
- if (CPP_OPTION (pfile, no_line_commands))
- return;
-
- /* 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.)
-
- '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)
- {
- putc ('\n', print->outf);
- print->lineno++;
- }
- return;
- }
-
- 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;
-}
-
-/* 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_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
-
- 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);
- print->lineno++;
- }
- pfile->need_newline = 0;
-
- vfprintf (print->outf, fmt, ap);
- va_end (ap);
-}
-
-/* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output. */
-
-void
-cpp_scan_buffer_nooutput (pfile)
- cpp_reader *pfile;
-{
- cpp_buffer *stop = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
- const cpp_token *token;
-
- /* In no-output mode, we can ignore everything but directives. */
- for (;;)
- {
- token = _cpp_get_token (pfile);
-
- if (token->type == CPP_EOF)
- {
- cpp_pop_buffer (pfile);
- if (CPP_BUFFER (pfile) == stop)
- break;
- }
-
- if (token->type == CPP_HASH && token->flags & BOL
- && pfile->token_list.directive)
- {
- process_directive (pfile, token);
- continue;
- }
-
- _cpp_skip_rest_of_line (pfile);
- }
-}
-
-/* Scan until CPP_BUFFER (pfile) is exhausted, writing output to PRINT. */
-void
-cpp_scan_buffer (pfile, print)
- cpp_reader *pfile;
- cpp_printer *print;
-{
- cpp_buffer *stop = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
- const cpp_token *token, *prev = 0;
-
- for (;;)
- {
- token = _cpp_get_token (pfile);
- if (token->type == CPP_EOF)
- {
- cpp_pop_buffer (pfile);
-
- if (CPP_BUFFER (pfile) == stop)
- return;
-
- prev = 0;
- continue;
- }
-
- if (token->flags & BOL)
- {
- output_line_command (pfile, print, token->line);
- prev = 0;
-
- if (token->type == CPP_HASH && pfile->token_list.directive)
- {
- process_directive (pfile, token);
- continue;
- }
- }
-
- if (token->type != CPP_PLACEMARKER)
- {
- output_token (pfile, print->outf, token, prev, 1);
- pfile->need_newline = 1;
- }
-
- prev = token;
- }
-}
-
/* Helper routine used by parse_include, which can't see spell_token.
Reinterpret the current line as an h-char-sequence (< ... >); we are
looking at the first token after the <. */
@@ -564,9 +395,6 @@ cpp_ideq (token, string)
return !ustrcmp (token->val.node->name, (const U_CHAR *)string);
}
-static const unsigned char *digraph_spellings [] = {U"%:", U"%:%:", U"<:",
- U":>", U"<%", U"%>"};
-
/* Call when meeting a newline. Returns the character after the newline
(or carriage-return newline combination), or EOF. */
static cppchar_t
@@ -1714,152 +1542,6 @@ lex_line (pfile, list)
pfile->state.in_lex_line = 0;
}
-/* Write the spelling of a token TOKEN, with any appropriate
- 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, fp, token, prev, white)
- cpp_reader *pfile;
- FILE *fp;
- const cpp_token *token, *prev;
- int white;
-{
- if (white)
- {
- 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);
- }
-
- 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:
- {
- int left, right, tag;
- switch (token->type)
- {
- case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
- case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
- case CPP_OSTRING: left = '"'; right = '"'; tag = '@'; break;
- case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
- case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
- case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
- default: left = '\0'; right = '\0'; tag = '\0'; break;
- }
- if (tag) putc (tag, fp);
- if (left) putc (left, fp);
- fwrite (token->val.str.text, 1, token->val.str.len, fp);
- if (right) putc (right, 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
@@ -1879,7 +1561,7 @@ spell_token (pfile, token, buffer)
unsigned char c;
if (token->flags & DIGRAPH)
- spelling = digraph_spellings[token->type - CPP_FIRST_DIGRAPH];
+ spelling = _cpp_digraph_spellings[token->type - CPP_FIRST_DIGRAPH];
else if (token->flags & NAMED_OP)
goto spell_ident;
else
@@ -2501,8 +2183,8 @@ duplicate_token (pfile, token)
what the resulting token is. Returns CPP_EOF if the tokens cannot
be pasted, or the appropriate type for the merged token if they
can. */
-static enum cpp_ttype
-can_paste (pfile, token1, token2, digraph)
+enum cpp_ttype
+_cpp_can_paste (pfile, token1, token2, digraph)
cpp_reader * pfile;
const cpp_token *token1, *token2;
int* digraph;
@@ -2651,7 +2333,7 @@ maybe_paste_with_next (pfile, token)
else
{
int digraph = 0;
- enum cpp_ttype type = can_paste (pfile, token, second, &digraph);
+ enum cpp_ttype type = _cpp_can_paste (pfile, token, second, &digraph);
if (type == CPP_EOF)
{
@@ -2961,8 +2643,8 @@ _cpp_push_token (pfile, token)
/* Handle a preprocessing directive. TOKEN is the CPP_HASH token
introducing the directive. */
-static void
-process_directive (pfile, token)
+void
+_cpp_process_directive (pfile, token)
cpp_reader *pfile;
const cpp_token *token;
{
@@ -3002,7 +2684,7 @@ cpp_get_token (pfile)
if (token->type == CPP_HASH && token->flags & BOL
&& pfile->token_list.directive)
{
- process_directive (pfile, token);
+ _cpp_process_directive (pfile, token);
continue;
}
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index 82dfd7f..321b318 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -40,7 +40,6 @@ struct macro_info
unsigned char flags;
};
-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 *));
@@ -577,57 +576,6 @@ _cpp_create_definition (pfile, hp)
return 1;
}
-/* 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, fp, hp)
- cpp_reader *pfile;
- FILE *fp;
- const cpp_hashnode *hp;
-{
- const cpp_toklist *list = hp->value.expansion;
-
- if (hp->type != T_MACRO)
- {
- cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type);
- return;
- }
-
- if (list->paramc >= 0)
- dump_macro_args (fp, list);
-
- putc (' ', fp);
- cpp_output_list (pfile, fp, list, list->tokens);
-}
-
-static void
-dump_macro_args (fp, list)
- FILE *fp;
- const cpp_toklist *list;
-{
- int i;
- const U_CHAR *param = list->namebuf;
-
- putc ('(', fp);
- for (i = 0; i++ < list->paramc;)
- {
- unsigned int len;
-
- len = ustrlen (param);
- if (!(list->flags & VAR_ARGS) || ustrcmp (param, U"__VA_ARGS__"))
- ufputs (param, fp);
- if (i < list->paramc)
- fputs (", ", fp);
- else if (list->flags & VAR_ARGS)
- fputs ("...", fp);
-
- param += len + 1;
- }
- putc (')', fp);
-}
-
/* Warn if a token in `string' matches one of the function macro
arguments in `info'. This function assumes that the macro is a
function macro and not an object macro. */
diff --git a/gcc/cppoutput.c b/gcc/cppoutput.c
new file mode 100644
index 0000000..53433ce
--- /dev/null
+++ b/gcc/cppoutput.c
@@ -0,0 +1,390 @@
+/* CPP Library - non-diagnostic output.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Per Bothner, 1994-95.
+ Based on CCCP program by Paul Rubin, June 1986
+ Adapted to ANSI C, Richard Stallman, Jan 1987
+ Broken out to separate file, Sep 2000
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "intl.h"
+#include "cpplib.h"
+#include "cpphash.h"
+
+static void output_line_command PARAMS ((cpp_reader *, cpp_printer *,
+ unsigned int));
+static void output_token PARAMS ((cpp_reader *, FILE *, const cpp_token *,
+ const cpp_token *, int));
+static void dump_macro_args PARAMS ((FILE *, const cpp_toklist *));
+static void dump_param_spelling PARAMS ((FILE *, const cpp_toklist *,
+ unsigned int));
+
+/* Scan until CPP_BUFFER (PFILE) is exhausted, discarding output. Used
+ for handling -imacros, -dM, -M and -MM. */
+void
+cpp_scan_buffer_nooutput (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *stop = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
+ const cpp_token *token;
+
+ /* In no-output mode, we can ignore everything but directives. */
+ for (;;)
+ {
+ token = _cpp_get_token (pfile);
+
+ if (token->type == CPP_EOF)
+ {
+ cpp_pop_buffer (pfile);
+ if (CPP_BUFFER (pfile) == stop)
+ break;
+ }
+
+ if (token->type == CPP_HASH && token->flags & BOL
+ && pfile->token_list.directive)
+ {
+ _cpp_process_directive (pfile, token);
+ continue;
+ }
+
+ _cpp_skip_rest_of_line (pfile);
+ }
+}
+
+/* Scan until CPP_BUFFER (pfile) is exhausted, writing output to PRINT. */
+void
+cpp_scan_buffer (pfile, print)
+ cpp_reader *pfile;
+ cpp_printer *print;
+{
+ cpp_buffer *stop = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
+ const cpp_token *token, *prev = 0;
+
+ for (;;)
+ {
+ token = _cpp_get_token (pfile);
+ if (token->type == CPP_EOF)
+ {
+ cpp_pop_buffer (pfile);
+
+ if (CPP_BUFFER (pfile) == stop)
+ return;
+
+ prev = 0;
+ continue;
+ }
+
+ if (token->flags & BOL)
+ {
+ output_line_command (pfile, print, token->line);
+ prev = 0;
+
+ if (token->type == CPP_HASH && pfile->token_list.directive)
+ {
+ _cpp_process_directive (pfile, token);
+ continue;
+ }
+ }
+
+ if (token->type != CPP_PLACEMARKER)
+ {
+ output_token (pfile, print->outf, token, prev, 1);
+ pfile->need_newline = 1;
+ }
+
+ prev = token;
+ }
+}
+
+/* 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, line)
+ cpp_reader *pfile;
+ cpp_printer *print;
+ unsigned int line;
+{
+ cpp_buffer *ip = CPP_BUFFER (pfile);
+
+ if (line == 0)
+ return;
+
+ /* End the previous line of text. */
+ if (pfile->need_newline)
+ {
+ putc ('\n', print->outf);
+ print->lineno++;
+ }
+ pfile->need_newline = 0;
+
+ if (CPP_OPTION (pfile, no_line_commands))
+ return;
+
+ /* 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.)
+
+ '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)
+ {
+ putc ('\n', print->outf);
+ print->lineno++;
+ }
+ return;
+ }
+
+ 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;
+}
+
+/* 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, with any appropriate
+ 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, fp, token, prev, white)
+ cpp_reader *pfile;
+ FILE *fp;
+ const cpp_token *token, *prev;
+ int white;
+{
+ if (white)
+ {
+ 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 _cpp_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
+ && (_cpp_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);
+ }
+
+ switch (TOKEN_SPELL (token))
+ {
+ case SPELL_OPERATOR:
+ {
+ const unsigned char *spelling;
+
+ if (token->flags & DIGRAPH)
+ spelling = _cpp_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:
+ {
+ int left, right, tag;
+ switch (token->type)
+ {
+ case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
+ case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
+ case CPP_OSTRING: left = '"'; right = '"'; tag = '@'; break;
+ case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
+ case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
+ case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
+ default: left = '\0'; right = '\0'; tag = '\0'; break;
+ }
+ if (tag) putc (tag, fp);
+ if (left) putc (left, fp);
+ fwrite (token->val.str.text, 1, token->val.str.len, fp);
+ if (right) putc (right, 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);
+}
+
+/* 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, fp, hp)
+ cpp_reader *pfile;
+ FILE *fp;
+ const cpp_hashnode *hp;
+{
+ const cpp_toklist *list = hp->value.expansion;
+
+ if (hp->type != T_MACRO)
+ {
+ cpp_ice (pfile, "invalid hash type %d in dump_definition", hp->type);
+ return;
+ }
+
+ if (list->paramc >= 0)
+ dump_macro_args (fp, list);
+
+ putc (' ', fp);
+ cpp_output_list (pfile, fp, list, list->tokens);
+}
+
+static void
+dump_macro_args (fp, list)
+ FILE *fp;
+ const cpp_toklist *list;
+{
+ int i;
+ const U_CHAR *param = list->namebuf;
+
+ putc ('(', fp);
+ for (i = 0; i++ < list->paramc;)
+ {
+ unsigned int len;
+
+ len = ustrlen (param);
+ if (!(list->flags & VAR_ARGS) || ustrcmp (param, U"__VA_ARGS__"))
+ ufputs (param, fp);
+ if (i < list->paramc)
+ fputs (", ", fp);
+ else if (list->flags & VAR_ARGS)
+ fputs ("...", fp);
+
+ param += len + 1;
+ }
+ putc (')', fp);
+}
+
+/* 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_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
+
+ 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);
+ print->lineno++;
+ }
+ pfile->need_newline = 0;
+
+ vfprintf (print->outf, fmt, ap);
+ va_end (ap);
+}
diff --git a/gcc/po/POTFILES.in b/gcc/po/POTFILES.in
index 1621153..66eccf9 100644
--- a/gcc/po/POTFILES.in
+++ b/gcc/po/POTFILES.in
@@ -599,6 +599,7 @@ cpplex.c
cpplib.c
cpplib.h
cppmain.c
+cppoutput.c
cppspec.c
#crtstuff.c is part of the GCC library
cse.c