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]
Other format: [Raw text]

cpplib: Better trad output, some trad directive handling


Until now traditional output has been in a sorry state; with this
patch it's almost perfect (line numbers still get messed up
in the presence of directives).

It also does most of the work to get directives working; in
particular #define and #undef work perfectly, which eases testing
considerably.  Also, the builtins work too (yeh!), a major
reason for integrating traditional handling.

There are about 2 dozen nits and things I need to fix, none of
which looks too hard.  The most serious issue is that no skipping
is done.

Neil.

	* Makefile.in: Update cppmain.o.
	* cpphash.h (struct cpp_reader): Move some members to a
	nested structure.
	(trad_line): Rename saved_line.
	(_cpp_read_logical_line_trad): Update.
	(_cpp_remove_overlay): New.
	* cppinit.c (cpp_create_reader): No need to set saved_line.
	(cpp_destroy): Update.
	(cpp_read_main_file): Only overlay if compiling.
	* cpplex.c (continue_after_nul): Return false if in directive.
	* cpplib.c (EXPAND): New.
	(directive_table, SEEN_EOL): Update.
	(end_directive): Remove overlay if traditional; don't skip
	line in traditional #define.
	(prepare_directive_trad): New.
	(_cpp_handle_directive, run_directive): Update for traditional
	directives.
	(lex_macro_node): Simplify, don't use lex_identifier_trad.
	* cpplib.h (struct options): Add preprocess_only.
	* cppmain.c: Don't include intl.h.
	(cpp_preprocess_file): Set options->preprocess_only.
	(scan_translation_unit_trad): Fix, and print line numbers.
	* cpptrad.c (check_output_buffer, lex_identifier, scan_parameters,
	maybe_start_funlike, scan_out_logical_line, replace_args_and_push,
	save_replacement_text, _cpp_create_trad_definition): Update for
	variable renaming.
	(_cpp_overlay_buffer): Save line number.
	(_cpp_remove_overlay): Rename from restore_buff, restore line.
	(_cpp_read_logical_line_trad): Don't handle overlays here.
	(scan_out_logical_line): Process directives.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.895
diff -u -p -r1.895 Makefile.in
--- Makefile.in	10 Jun 2002 18:54:31 -0000	1.895
+++ Makefile.in	10 Jun 2002 21:09:08 -0000
@@ -2084,7 +2084,7 @@ libcpp.a: $(LIBCPP_OBJS)
 	$(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS)
 	-$(RANLIB) libcpp.a
 
-cppmain.o:  cppmain.c  $(CONFIG_H) $(CPPLIB_H) intl.h $(SYSTEM_H)
+cppmain.o:  cppmain.c  $(CONFIG_H) $(LIBCPP_DEPS)
 
 cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
 cppexp.o:   cppexp.c   $(CONFIG_H) $(LIBCPP_DEPS)
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.161
diff -u -p -r1.161 cpphash.h
--- cpphash.h	10 Jun 2002 17:20:28 -0000	1.161
+++ cpphash.h	10 Jun 2002 21:09:08 -0000
@@ -406,10 +406,18 @@ struct cpp_reader
   /* Whether cpplib owns the hashtable.  */
   unsigned char our_hashtable;
 
-  /* Traditional preprocessing output buffer.  */
-  uchar *trad_out_base, *trad_out_limit;
-  uchar *trad_out_cur;
-  unsigned int trad_line;
+  /* Traditional preprocessing output buffer (a logical line).  */
+  struct
+  {
+    uchar *base;
+    uchar *limit;
+    uchar *cur;
+    unsigned int first_line;
+  } out;
+
+  /* Used to save the original line number during traditional
+     preprocessing.  */
+  unsigned int saved_line;
 };
 
 /* Character classes.  Based on the more primitive macros in safe-ctype.h.
@@ -510,9 +518,10 @@ extern void _cpp_do_file_change PARAMS (
 extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
 
 /* In cpptrad.c.  */
-extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *, int));
+extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *));
 extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
 					 size_t));
+extern void _cpp_remove_overlay PARAMS ((cpp_reader *));
 extern cpp_hashnode *_cpp_lex_identifier_trad PARAMS ((cpp_reader *));
 extern void _cpp_set_trad_context PARAMS ((cpp_reader *));
 extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *));
Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppinit.c,v
retrieving revision 1.240
diff -u -p -r1.240 cppinit.c
--- cppinit.c	9 Jun 2002 00:26:31 -0000	1.240
+++ cppinit.c	10 Jun 2002 21:09:08 -0000
@@ -506,7 +506,7 @@ cpp_create_reader (lang)
   /* Initialise the line map.  Start at logical line 1, so we can use
      a line number of zero for special states.  */
   init_line_maps (&pfile->line_maps);
-  pfile->trad_line = pfile->line = 1;
+  pfile->line = 1;
 
   /* Initialize lexer state.  */
   pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
@@ -561,8 +561,8 @@ cpp_destroy (pfile)
   while (CPP_BUFFER (pfile) != NULL)
     _cpp_pop_buffer (pfile);
 
-  if (pfile->trad_out_base)
-    free (pfile->trad_out_base);
+  if (pfile->out.base)
+    free (pfile->out.base);
 
   if (pfile->macro_buffer)
     {
@@ -941,7 +941,8 @@ cpp_read_main_file (pfile, fname, table)
   if (CPP_OPTION (pfile, preprocessed))
     read_original_filename (pfile);
   /* Overlay an empty buffer to seed traditional preprocessing.  */
-  else if (CPP_OPTION (pfile, traditional))
+  else if (CPP_OPTION (pfile, traditional)
+	   && !CPP_OPTION (pfile, preprocess_only))
     _cpp_overlay_buffer (pfile, U"", 0);
 
   return pfile->map->to_file;
Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplex.c,v
retrieving revision 1.210
diff -u -p -r1.210 cpplex.c
--- cpplex.c	10 Jun 2002 17:20:29 -0000	1.210
+++ cpplex.c	10 Jun 2002 21:09:09 -0000
@@ -891,7 +891,16 @@ continue_after_nul (pfile)
 
   buffer->saved_flags = BOL;
   if (CPP_OPTION (pfile, traditional))
-    more = _cpp_read_logical_line_trad (pfile, true);
+    {
+      if (pfile->state.in_directive)
+	return false;
+
+      _cpp_remove_overlay (pfile);
+      more = _cpp_read_logical_line_trad (pfile);
+      _cpp_overlay_buffer (pfile, pfile->out.base,
+			   pfile->out.cur - pfile->out.base);
+      pfile->line = pfile->out.first_line;
+    }
   else
     {
       /* Stop parsing arguments with a CPP_EOF.  When we finally come
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.307
diff -u -p -r1.307 cpplib.c
--- cpplib.c	5 Jun 2002 20:27:11 -0000	1.307
+++ cpplib.c	10 Jun 2002 21:09:09 -0000
@@ -70,11 +70,16 @@ struct pragma_entry
    conditional; IF_COND an opening conditional.  INCL means to treat
    "..." and <...> as q-char and h-char sequences respectively.  IN_I
    means this directive should be handled even if -fpreprocessed is in
-   effect (these are the directives with callback hooks).  */
+   effect (these are the directives with callback hooks).
+
+   EXPAND is set on directives that are always macro-expanded.  If
+   INCL is set, macro expansion is special-cased and EXPAND should not
+   be set.  */
 #define COND		(1 << 0)
 #define IF_COND		(1 << 1)
 #define INCL		(1 << 2)
 #define IN_I		(1 << 3)
+#define EXPAND		(1 << 4)
 
 /* Defines one #-directive, including how to handle it.  */
 typedef void (*directive_handler) PARAMS ((cpp_reader *));
@@ -93,6 +98,7 @@ struct directive
 static void skip_rest_of_line	PARAMS ((cpp_reader *));
 static void check_eol		PARAMS ((cpp_reader *));
 static void start_directive	PARAMS ((cpp_reader *));
+static void prepare_directive_trad PARAMS ((cpp_reader *));
 static void end_directive	PARAMS ((cpp_reader *, int));
 static void directive_diagnostics
 	PARAMS ((cpp_reader *, const directive *, int));
@@ -144,12 +150,12 @@ D(define,	T_DEFINE = 0,	KANDR,     IN_I)
 D(include,	T_INCLUDE,	KANDR,     INCL)	   /*  52262 */ \
 D(endif,	T_ENDIF,	KANDR,     COND)	   /*  45855 */ \
 D(ifdef,	T_IFDEF,	KANDR,     COND | IF_COND) /*  22000 */ \
-D(if,		T_IF,		KANDR,     COND | IF_COND) /*  18162 */ \
+D(if,		T_IF,		KANDR, COND | IF_COND | EXPAND) /*  18162 */ \
 D(else,		T_ELSE,		KANDR,     COND)	   /*   9863 */ \
 D(ifndef,	T_IFNDEF,	KANDR,     COND | IF_COND) /*   9675 */ \
 D(undef,	T_UNDEF,	KANDR,     IN_I)	   /*   4837 */ \
-D(line,		T_LINE,		KANDR,     0)		   /*   2465 */ \
-D(elif,		T_ELIF,		STDC89,    COND)	   /*    610 */ \
+D(line,		T_LINE,		KANDR,     EXPAND)	   /*   2465 */ \
+D(elif,		T_ELIF,		STDC89,    COND | EXPAND)  /*    610 */ \
 D(error,	T_ERROR,	STDC89,    0)		   /*    475 */ \
 D(pragma,	T_PRAGMA,	STDC89,    IN_I)	   /*    195 */ \
 D(warning,	T_WARNING,	EXTENSION, 0)		   /*     22 */ \
@@ -202,8 +208,7 @@ static const directive linemarker_dir =
   do_linemarker, U"#", 1, KANDR, IN_I
 };
 
-#define SEEN_EOL() (CPP_OPTION (pfile, traditional) \
-		    || pfile->cur_token[-1].type == CPP_EOF)
+#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF)
 
 /* Skip any remaining tokens in a directive.  */
 static void
@@ -249,6 +254,14 @@ end_directive (pfile, skip_line)
      cpp_reader *pfile;
      int skip_line;
 {
+  if (CPP_OPTION (pfile, traditional))
+    {
+      if (pfile->directive == &dtable[T_DEFINE])
+	skip_line = false;
+      else
+	_cpp_remove_overlay (pfile);
+    }
+
   /* We don't skip for an assembler #.  */
   if (skip_line)
     {
@@ -267,6 +280,27 @@ end_directive (pfile, skip_line)
   pfile->directive = 0;
 }
 
+/* Prepare to handle the directive in pfile->directive.  */
+static void
+prepare_directive_trad (pfile)
+     cpp_reader *pfile;
+{
+  if (pfile->directive == &dtable[T_DEFINE])
+    CUR (pfile->context) = pfile->buffer->cur;
+  else
+    {
+      bool no_expand = ! (pfile->directive->flags & EXPAND);
+
+      if (no_expand)
+	pfile->state.prevent_expansion++;
+      _cpp_read_logical_line_trad (pfile);
+      if (no_expand)
+	pfile->state.prevent_expansion--;
+      _cpp_overlay_buffer (pfile, pfile->out.base,
+			   pfile->out.cur - pfile->out.base);
+    }
+}
+
 /* Output diagnostics for a directive DIR.  INDENTED is non-zero if
    the '#' was indented.  */
 static void
@@ -405,6 +439,8 @@ _cpp_handle_directive (pfile, indented)
 	  ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
 
       pfile->directive = dir;
+      if (CPP_OPTION (pfile, traditional))
+	prepare_directive_trad (pfile);
       (*pfile->directive->handler) (pfile);
     }
   else if (skip == 0)
@@ -436,6 +472,8 @@ run_directive (pfile, dir_no, buf, count
   /* We don't want a leading # to be interpreted as a directive.  */
   pfile->buffer->saved_flags = 0;
   pfile->directive = &dtable[dir_no];
+  if (CPP_OPTION (pfile, traditional))
+    prepare_directive_trad (pfile);
   (void) (*pfile->directive->handler) (pfile);
   end_directive (pfile, 1);
   _cpp_pop_buffer (pfile);
@@ -447,7 +485,7 @@ static cpp_hashnode *
 lex_macro_node (pfile)
      cpp_reader *pfile;
 {
-  cpp_hashnode *node;
+  const cpp_token *token = _cpp_lex_token (pfile);
 
   /* The token immediately after #define must be an identifier.  That
      identifier may not be "defined", per C99 6.10.8p4.
@@ -459,41 +497,31 @@ lex_macro_node (pfile)
      Note that if we're copying comments into macro expansions, we
      could encounter comment tokens here, so eat them all up first.  */
 
-  if (CPP_OPTION (pfile, traditional))
-    node = _cpp_lex_identifier_trad (pfile);
-  else
+  if (! CPP_OPTION (pfile, discard_comments_in_macro_exp))
     {
-      const cpp_token *token = _cpp_lex_token (pfile);
+      while (token->type == CPP_COMMENT)
+	token = _cpp_lex_token (pfile);
+    }
 
-      if (! CPP_OPTION (pfile, discard_comments_in_macro_exp))
-	{
-	  while (token->type == CPP_COMMENT)
-	    token = _cpp_lex_token (pfile);
-	}
+  if (token->type == CPP_NAME)
+    {
+      cpp_hashnode *node = token->val.node;
 
-      if (token->type == CPP_EOF)
-	{
-	  cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
-		     pfile->directive->name);
-	  return NULL;
-	}
-	
-      if (token->type == CPP_NAME || (token->flags & NAMED_OP))
-	node = token->val.node;
-      else
-	node = NULL;
+      if (node == pfile->spec_nodes.n_defined)
+	cpp_error (pfile, DL_ERROR,
+		   "\"defined\" cannot be used as a macro name");
+      else if (! (node->flags & NODE_POISONED))
+	return node;
     }
-
-  if (!node)
-    cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
-  else if (node->flags & NODE_OPERATOR)
+  else if (token->flags & NAMED_OP)
     cpp_error (pfile, DL_ERROR,
        "\"%s\" cannot be used as a macro name as it is an operator in C++",
-	       NODE_NAME (node));
-  else if (node == pfile->spec_nodes.n_defined)
-    cpp_error (pfile, DL_ERROR, "\"defined\" cannot be used as a macro name");
-  else if (! (node->flags & NODE_POISONED))
-    return node;
+	       NODE_NAME (token->val.node));
+  else if (token->type == CPP_EOF)
+    cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
+	       pfile->directive->name);
+  else
+    cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
 
   return NULL;
 }
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.223
diff -u -p -r1.223 cpplib.h
--- cpplib.h	7 Jun 2002 22:20:11 -0000	1.223
+++ cpplib.h	10 Jun 2002 21:09:10 -0000
@@ -393,6 +393,9 @@ struct cpp_options
   /* True for traditional preprocessing.  */
   unsigned char traditional;
 
+  /* True if only preprocessing and not compiling.  */
+  unsigned char preprocess_only;
+
   /* Target-specific features set by the front end or client.  */
 
   /* Precision for target CPP arithmetic, target characters, target
Index: cppmain.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmain.c,v
retrieving revision 1.97
diff -u -p -r1.97 cppmain.c
--- cppmain.c	10 Jun 2002 17:20:29 -0000	1.97
+++ cppmain.c	10 Jun 2002 21:09:10 -0000
@@ -25,7 +25,6 @@ Foundation, 59 Temple Place - Suite 330,
 #include "system.h"
 #include "cpplib.h"
 #include "cpphash.h"
-#include "intl.h"
 
 /* Encapsulates state used to convert the stream of tokens coming from
    cpp_get_token back into a text file.  */
@@ -73,6 +72,10 @@ cpp_preprocess_file (pfile)
 {
   options = cpp_get_options (pfile);
 
+  /* Let preprocessor know if it's only preprocessing.  It would be
+     nice to lose this somehow.  */
+  options->preprocess_only = 1;
+
   /* Initialize the printer structure.  Setting print.line to -1 here
      is a trick to guarantee that the first token of the file will
      cause a linemarker to be output by maybe_print_line.  */
@@ -221,20 +224,22 @@ check_multiline_token (str)
       print.line++;
 }
 
+/* Writes out a traditionally preprocessed file.  */
 static void
 scan_translation_unit_trad (pfile)
      cpp_reader *pfile;
 {
-  bool more;
-  size_t len;
-
-  do
+  for (;;)
     {
-      more = _cpp_read_logical_line_trad (pfile, false);
-      len = pfile->trad_out_cur - pfile->trad_out_base;
-      fwrite (pfile->trad_out_base, 1, len, print.outf);
+      size_t len;
+
+      if (!_cpp_read_logical_line_trad (pfile))
+	break;
+      len = pfile->out.cur - pfile->out.base;
+      maybe_print_line (print.map, pfile->out.first_line);
+      fwrite (pfile->out.base, 1, len, print.outf);
+      print.printed = 1;
     }
-  while (more);
 }
 
 /* If the token read on logical line LINE needs to be output on a
Index: cpptrad.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpptrad.c,v
retrieving revision 1.8
diff -u -p -r1.8 cpptrad.c
--- cpptrad.c	10 Jun 2002 17:20:30 -0000	1.8
+++ cpptrad.c	10 Jun 2002 21:09:10 -0000
@@ -80,7 +80,6 @@ static cpp_hashnode *lex_identifier PARA
 static const uchar *skip_comment PARAMS ((cpp_reader *, const uchar *));
 static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *));
 static void check_output_buffer PARAMS ((cpp_reader *, size_t));
-static void restore_buff PARAMS ((cpp_reader *));
 static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
 static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
 static void save_replacement_text PARAMS ((cpp_reader *, cpp_macro *,
@@ -99,15 +98,15 @@ check_output_buffer (pfile, n)
      cpp_reader *pfile;
      size_t n;
 {
-  if (n > (size_t) (pfile->trad_out_limit - pfile->trad_out_cur))
+  if (n > (size_t) (pfile->out.limit - pfile->out.cur))
     {
-      size_t size = pfile->trad_out_cur - pfile->trad_out_base;
+      size_t size = pfile->out.cur - pfile->out.base;
       size_t new_size = (size + n) * 3 / 2;
 
-      pfile->trad_out_base
-	= (uchar *) xrealloc (pfile->trad_out_base, new_size);
-      pfile->trad_out_limit = pfile->trad_out_base + new_size;
-      pfile->trad_out_cur = pfile->trad_out_base + size;
+      pfile->out.base
+	= (uchar *) xrealloc (pfile->out.base, new_size);
+      pfile->out.limit = pfile->out.base + new_size;
+      pfile->out.cur = pfile->out.base + size;
     }
 }
 
@@ -219,14 +218,14 @@ skip_whitespace (pfile, cur)
 
 /* Lexes and outputs an identifier starting at CUR, which is assumed
    to point to a valid first character of an identifier.  Returns
-   the hashnode, and updates trad_out_cur.  */
+   the hashnode, and updates out.cur.  */
 static cpp_hashnode *
 lex_identifier (pfile, cur)
      cpp_reader *pfile;
      const uchar *cur;
 {
   size_t len;
-  uchar *out = pfile->trad_out_cur;
+  uchar *out = pfile->out.cur;
   cpp_hashnode *result;
 
   do
@@ -239,10 +238,10 @@ lex_identifier (pfile, cur)
   while (is_numchar (*cur));
 
   CUR (pfile->context) = cur;
-  len = out - pfile->trad_out_cur;
-  result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->trad_out_cur,
+  len = out - pfile->out.cur;
+  result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->out.cur,
 				       len, HT_ALLOC);
-  pfile->trad_out_cur = out;
+  pfile->out.cur = out;
   return result;
 }
 
@@ -281,11 +280,13 @@ _cpp_overlay_buffer (pfile, start, len)
   buffer->cur = start;
   buffer->line_base = start;
   buffer->rlimit = start + len;
+
+  pfile->saved_line = pfile->line;
 }
 
 /* Restores a buffer overlaid by _cpp_overlay_buffer().  */
-static void
-restore_buff (pfile)
+void
+_cpp_remove_overlay (pfile)
      cpp_reader *pfile;
 {
   cpp_buffer *buffer = pfile->buffer;
@@ -293,23 +294,17 @@ restore_buff (pfile)
   buffer->cur = buffer->saved_cur;
   buffer->rlimit = buffer->saved_rlimit;
   buffer->line_base = buffer->saved_line_base;
+
+  pfile->line = pfile->saved_line;
 }
 
 /* Reads a logical line into the output buffer.  Returns TRUE if there
    is more text left in the buffer.  */
 bool
-_cpp_read_logical_line_trad (pfile, overlay)
+_cpp_read_logical_line_trad (pfile)
      cpp_reader *pfile;
-     int overlay;
 {
   cpp_buffer *buffer;
-  unsigned int first_line = 0;
-
-  if (overlay)
-    {
-      restore_buff (pfile);
-      first_line = pfile->line = pfile->trad_line;
-    }
 
   buffer = pfile->buffer;
   if (buffer->cur == buffer->rlimit)
@@ -329,18 +324,11 @@ _cpp_read_logical_line_trad (pfile, over
 
   CUR (pfile->context) = buffer->cur;
   RLIMIT (pfile->context) = buffer->rlimit;
-  pfile->trad_out_cur = pfile->trad_out_base;
+  pfile->out.cur = pfile->out.base;
+  pfile->out.first_line = pfile->line;
   scan_out_logical_line (pfile, NULL);
   buffer->cur = CUR (pfile->context);
 
-  if (overlay)
-    {
-      pfile->trad_line = pfile->line;
-      pfile->line = first_line;
-      _cpp_overlay_buffer (pfile, pfile->trad_out_base,
-			   pfile->trad_out_cur - pfile->trad_out_base);
-    }
-
   return true;
 }
 
@@ -360,7 +348,7 @@ maybe_start_funlike (pfile, node, start,
   macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t));
   macro->args = (size_t *) BUFF_FRONT (macro->buff);
   macro->node = node;
-  macro->offset = start - pfile->trad_out_base;
+  macro->offset = start - pfile->out.base;
   macro->argc = 0;
 
   pfile->state.parsing_args = 1;
@@ -400,7 +388,7 @@ scan_out_logical_line (pfile, macro)
   context = pfile->context;
   cur = CUR (context);
   check_output_buffer (pfile, RLIMIT (context) - cur);
-  out = pfile->trad_out_cur;
+  out = pfile->out.cur;
 
   for (;;)
     {
@@ -418,7 +406,7 @@ scan_out_logical_line (pfile, macro)
 	  /* If this is a macro's expansion, pop it.  */
 	  if (context->prev)
 	    {
-	      pfile->trad_out_cur = out - 1;
+	      pfile->out.cur = out - 1;
 	      _cpp_pop_context (pfile);
 	      goto new_context;
 	    }
@@ -491,7 +479,7 @@ scan_out_logical_line (pfile, macro)
 	    {
 	      cpp_hashnode *node;
 
-	      pfile->trad_out_cur = --out;
+	      pfile->out.cur = --out;
 	      node = lex_identifier (pfile, cur - 1);
 
 	      if (node->type == NT_MACRO
@@ -504,7 +492,7 @@ scan_out_logical_line (pfile, macro)
 		    {
 		      /* Remove the object-like macro's name from the
 			 output, and push its replacement text.  */
-		      pfile->trad_out_cur = out;
+		      pfile->out.cur = out;
 		      push_replacement_text (pfile, node);
 		      goto new_context;
 		    }
@@ -513,11 +501,11 @@ scan_out_logical_line (pfile, macro)
 		{
 		  /* Found a parameter in the replacement text of a
 		     #define.  Remove its name from the output.  */
-		  pfile->trad_out_cur = out;
+		  pfile->out.cur = out;
 		  save_replacement_text (pfile, macro, node->arg_index);
 		}
 
-	      out = pfile->trad_out_cur;
+	      out = pfile->out.cur;
 	      cur = CUR (context);
 	    }
 	  break;
@@ -528,7 +516,7 @@ scan_out_logical_line (pfile, macro)
 	      paren_depth++;
 	      if (pfile->state.parsing_args == 1)
 		{
-		  const uchar *p = pfile->trad_out_base + fmacro.offset;
+		  const uchar *p = pfile->out.base + fmacro.offset;
 
 		  /* Invoke a prior function-like macro if there is only
 		     white space in-between.  */
@@ -541,7 +529,7 @@ scan_out_logical_line (pfile, macro)
 		    {
 		      pfile->state.parsing_args = 2;
 		      paren_depth = 1;
-		      out = pfile->trad_out_base + fmacro.offset;
+		      out = pfile->out.base + fmacro.offset;
 		      fmacro.args[0] = fmacro.offset;
 		    }
 		  else
@@ -552,7 +540,7 @@ scan_out_logical_line (pfile, macro)
 
 	case ',':
 	  if (quote == 0 && pfile->state.parsing_args == 2 && paren_depth == 1)
-	    save_argument (&fmacro, out - pfile->trad_out_base);
+	    save_argument (&fmacro, out - pfile->out.base);
 	  break;
 
 	case ')':
@@ -564,19 +552,19 @@ scan_out_logical_line (pfile, macro)
 		  cpp_macro *m = fmacro.node->value.macro;
 
 		  pfile->state.parsing_args = 0;
-		  save_argument (&fmacro, out - pfile->trad_out_base);
+		  save_argument (&fmacro, out - pfile->out.base);
 
 		  /* A single zero-length argument is no argument.  */
 		  if (fmacro.argc == 1
 		      && m->paramc == 0
-		      && out == pfile->trad_out_base + 1)
+		      && out == pfile->out.base + 1)
 		    fmacro.argc = 0;
 
 		  if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
 		    {
 		      /* Remove the macro's invocation from the
 			 output, and push its replacement text.  */
-		      pfile->trad_out_cur = (pfile->trad_out_base
+		      pfile->out.cur = (pfile->out.base
 					     + fmacro.offset);
 		      CUR (context) = cur;
 		      replace_args_and_push (pfile, &fmacro);
@@ -586,6 +574,21 @@ scan_out_logical_line (pfile, macro)
 	    }
 	  break;
 
+	case '#':
+	  /* At start of a line it's a directive.  */
+	  if (out - 1 == pfile->out.base && !pfile->state.in_directive)
+	    {
+	      /* This is a kludge.  We want to have the ISO
+		 preprocessor lex the next token.  */
+	      pfile->buffer->cur = cur;
+	      if (_cpp_handle_directive (pfile, false /* indented */))
+		{
+		  cur = CUR (context);
+		  goto done;
+		}
+	    }
+	  break;
+
 	default:
 	  break;
 	}
@@ -594,7 +597,7 @@ scan_out_logical_line (pfile, macro)
  done:
   out[-1] = '\0';
   CUR (context) = cur;
-  pfile->trad_out_cur = out - 1;
+  pfile->out.cur = out - 1;
   if (fmacro.buff)
     _cpp_release_buff (pfile, fmacro.buff);
 }
@@ -660,7 +663,7 @@ replace_args_and_push (pfile, fmacro)
 	    break;
 	  arglen = (fmacro->args[b->arg_index]
 		    - fmacro->args[b->arg_index - 1] - 1);
-	  memcpy (p, pfile->trad_out_base + fmacro->args[b->arg_index - 1],
+	  memcpy (p, pfile->out.base + fmacro->args[b->arg_index - 1],
 		  arglen);
 	  p += arglen;
 	  exp += BLOCK_LEN (b->text_len);
@@ -676,7 +679,7 @@ replace_args_and_push (pfile, fmacro)
 }
 
 /* Read and record the parameters, if any, of a function-like macro
-   definition.  Destroys pfile->trad_out_cur.
+   definition.  Destroys pfile->out.cur.
 
    Returns true on success, false on failure (syntax error or a
    duplicate parameter).  On success, CUR (pfile->context) is just
@@ -717,7 +720,7 @@ scan_parameters (pfile, macro)
   return ok;
 }
 
-/* Save the text from pfile->trad_out_base to pfile->trad_out_cur as
+/* Save the text from pfile->out.base to pfile->out.cur as
    the replacement text for the current macro, followed by argument
    ARG_INDEX, with zero indicating the end of the replacement
    text.  */
@@ -727,7 +730,7 @@ save_replacement_text (pfile, macro, arg
      cpp_macro *macro;
      unsigned int arg_index;
 {
-  size_t len = pfile->trad_out_cur - pfile->trad_out_base;
+  size_t len = pfile->out.cur - pfile->out.base;
   uchar *exp;
 
   if (macro->paramc == 0)
@@ -735,7 +738,7 @@ save_replacement_text (pfile, macro, arg
       /* Object-like and function-like macros without parameters
 	 simply store their NUL-terminated replacement text.  */
       exp = _cpp_unaligned_alloc (pfile, len + 1);
-      memcpy (exp, pfile->trad_out_base, len);
+      memcpy (exp, pfile->out.base, len);
       exp[len] = '\0';
       macro->exp.text = exp;
       macro->count = len;
@@ -757,10 +760,10 @@ save_replacement_text (pfile, macro, arg
       /* Write out the block information.  */
       block->text_len = len;
       block->arg_index = arg_index;
-      memcpy (block->text, pfile->trad_out_base, len);
+      memcpy (block->text, pfile->out.base, len);
 
       /* Lex the rest into the start of the output buffer.  */
-      pfile->trad_out_cur = pfile->trad_out_base;
+      pfile->out.cur = pfile->out.base;
 
       macro->count += blen;
 
@@ -780,6 +783,8 @@ _cpp_create_trad_definition (pfile, macr
   const uchar *cur;
   uchar *limit;
 
+  CUR (pfile->context) = pfile->buffer->cur;
+
   /* Is this a function-like macro?  */
   if (* CUR (pfile->context) == '(')
     {
@@ -799,7 +804,7 @@ _cpp_create_trad_definition (pfile, macr
   /* Skip leading whitespace in the replacement text.  */
   CUR (pfile->context) = skip_whitespace (pfile, CUR (pfile->context));
 
-  pfile->trad_out_cur = pfile->trad_out_base;
+  pfile->out.cur = pfile->out.base;
   pfile->state.prevent_expansion++;
   scan_out_logical_line (pfile, macro);
   pfile->state.prevent_expansion--;
@@ -808,11 +813,11 @@ _cpp_create_trad_definition (pfile, macr
     return false;
 
   /* Skip trailing white space.  */
-  cur = pfile->trad_out_base;
-  limit = pfile->trad_out_cur;
+  cur = pfile->out.base;
+  limit = pfile->out.cur;
   while (limit > cur && is_space (limit[-1]))
     limit--;
-  pfile->trad_out_cur = limit;
+  pfile->out.cur = limit;
   save_replacement_text (pfile, macro, 0);
 
   return true;
@@ -918,7 +923,7 @@ _cpp_set_trad_context (pfile)
   if (pfile->context->prev)
     abort ();
 
-  pfile->trad_out_cur = pfile->trad_out_base;
+  pfile->out.cur = pfile->out.base;
   CUR (context) = buffer->cur;
   RLIMIT (context) = buffer->rlimit;
   check_output_buffer (pfile, RLIMIT (context) - CUR (context));


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