This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[NeilB@earthling.net: cpplib: New file cppoutput.c]


The non-diagnostic output routines for cpplib are scattered around,
and generally, uhm, not pretty.  So as a first step to cleaning them
up, I'd like to group them together in a separate file.

This patch is after applying my lexer cleanup patch (anyone care to OK
that, please)?  No logic changes, just code shuffling.  OK to commit?

Neil.

	* 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.

diff -upN lexer/cpphash.h lexer2/cpphash.h
--- lexer/cpphash.h	Mon Sep 18 21:04:08 2000
+++ lexer2/cpphash.h	Tue Sep 19 18:59:20 2000
@@ -231,6 +231,7 @@ extern void _cpp_pop_file_buffer	PARAMS 
 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	PARA
 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 P
 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 -upN lexer/cpplex.c lexer2/cpplex.c
--- lexer/cpplex.c	Tue Sep 19 00:33:13 2000
+++ lexer2/cpplex.c	Tue Sep 19 18:58:43 2000
@@ -44,6 +44,8 @@ o Correct pastability test for CPP_NAME 
 #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};
@@ -93,10 +95,6 @@ static int pop_context PARAMS ((cpp_read
 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));
@@ -118,7 +116,6 @@ static void lex_line PARAMS ((cpp_reader
 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 *));
 
@@ -126,8 +123,6 @@ static cpp_token *stringify_arg PARAMS (
 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 *,
@@ -138,14 +133,11 @@ static const cpp_token *special_symbol P
 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) == '-') && \
@@ -197,167 +189,6 @@ _cpp_token_spellings [N_TTYPES] = {TTYPE
 #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 <.  */
@@ -567,9 +398,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
@@ -1716,152 +1544,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
@@ -1881,7 +1563,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
@@ -2503,8 +2185,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;
@@ -2653,7 +2335,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)
 	    {
@@ -2963,8 +2645,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;
 {
@@ -3004,7 +2686,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 -upN lexer/cppmacro.c lexer2/cppmacro.c
--- lexer/cppmacro.c	Mon Sep 18 19:13:50 2000
+++ lexer2/cppmacro.c	Tue Sep 19 18:53:08 2000
@@ -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 *));
 
@@ -575,57 +574,6 @@ _cpp_create_definition (pfile, hp)
   hp->value.expansion = list;
 
   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
diff -upN lexer/cppoutput.c lexer2/cppoutput.c
--- lexer/cppoutput.c	Thu Jan  1 01:00:00 1970
+++ lexer2/cppoutput.c	Tue Sep 19 19:09:09 2000
@@ -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);
+}
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.514
diff -u -p -r1.514 Makefile.in
--- Makefile.in	2000/09/19 03:26:10	1.514
+++ Makefile.in	2000/09/19 18:25:45
@@ -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) $(LIB
 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
Index: po/POTFILES.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/po/POTFILES.in,v
retrieving revision 1.28
diff -u -p -r1.28 POTFILES.in
--- POTFILES.in	2000/09/13 07:09:48	1.28
+++ POTFILES.in	2000/09/19 18:25:47
@@ -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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]