]> gcc.gnu.org Git - gcc.git/commitdiff
cpphash.h (_cpp_create_definition): Update prototype.
authorNeil Booth <neil@daikokuya.demon.co.uk>
Wed, 5 Jun 2002 20:27:12 +0000 (20:27 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Wed, 5 Jun 2002 20:27:12 +0000 (20:27 +0000)
* cpphash.h (_cpp_create_definition): Update prototype.
(_cpp_push_text_context, _cpp_create_trad_definition): New.
( cpp_lex_identifier_trad): New.
(_cpp_set_trad_context): New.
* cppinit.c (cpp_finish_options): Don't conditionalize builtins.
* cpplib.c (SEEN_EOL): Update.
(lex_macro_node): Update for -traditional.
(cpp_push_buffer, _cpp_pop_buffer): Similarly.
* cppmacro.c (_cpp_create_definition): Split into
create_iso_definition() and _cpp_create_trad_definition().
(warn_of_redefinition): Update prototype; handle traditional
macros.
(_cpp_push_text_context): New.
* cpptrad.c (skip_whitespace, push_replacement_text): New.
(lex_identifier): Call ht_lookup with correct start.
(_cpp_lex_identifier_tradm _cpp_create_trad_definition,
_cpp_set_trad_context): New.
(scan_out_logical_line): Update to handle changing contexts.

From-SVN: r54293

gcc/ChangeLog
gcc/cpphash.h
gcc/cppinit.c
gcc/cpplib.c
gcc/cppmacro.c
gcc/cpptrad.c

index 9fac44231aad9efc20528cec19c210239297ab7c..a51e8cfcced3696886edb8a008da415b6c8da044 100644 (file)
@@ -1,3 +1,24 @@
+2002-06-05  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * cpphash.h (_cpp_create_definition): Update prototype.
+       (_cpp_push_text_context, _cpp_create_trad_definition): New.
+       ( cpp_lex_identifier_trad): New.
+       (_cpp_set_trad_context): New.
+       * cppinit.c (cpp_finish_options): Don't conditionalize builtins.
+       * cpplib.c (SEEN_EOL): Update.
+       (lex_macro_node): Update for -traditional.
+       (cpp_push_buffer, _cpp_pop_buffer): Similarly.
+       * cppmacro.c (_cpp_create_definition): Split into
+       create_iso_definition() and _cpp_create_trad_definition().
+       (warn_of_redefinition): Update prototype; handle traditional
+       macros.
+       (_cpp_push_text_context): New.
+       * cpptrad.c (skip_whitespace, push_replacement_text): New.
+       (lex_identifier): Call ht_lookup with correct start.
+       (_cpp_lex_identifier_tradm _cpp_create_trad_definition,
+       _cpp_set_trad_context): New.
+       (scan_out_logical_line): Update to handle changing contexts.
+
 Wed Jun  5 20:42:31 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
        * config.gcc (sh-*-elf*,  sh64*-*-elf*): Unify.
index 6d3f1b9fb09b25b036e4f325aba27ec765f0e4d4..e508b80ddcf279ba437cc96333f1ef785c4c8096 100644 (file)
@@ -424,8 +424,11 @@ extern int _cpp_begin_message PARAMS ((cpp_reader *, int,
 
 /* In cppmacro.c */
 extern void _cpp_free_definition       PARAMS ((cpp_hashnode *));
-extern int _cpp_create_definition      PARAMS ((cpp_reader *, cpp_hashnode *));
+extern bool _cpp_create_definition     PARAMS ((cpp_reader *, cpp_hashnode *));
 extern void _cpp_pop_context           PARAMS ((cpp_reader *));
+extern void _cpp_push_text_context     PARAMS ((cpp_reader *, cpp_hashnode *,
+                                                const uchar *, const uchar*));
+extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *));
 
 /* In cpphash.c */
 extern void _cpp_init_hashtable                PARAMS ((cpp_reader *, hash_table *));
@@ -478,6 +481,8 @@ extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
 extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *));
 extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
                                         size_t));
+extern cpp_hashnode *_cpp_lex_identifier_trad PARAMS ((cpp_reader *));
+extern void _cpp_set_trad_context PARAMS ((cpp_reader *));
 
 /* Utility routines and macros.  */
 #define DSC(str) (const uchar *)str, sizeof str - 1
index 580ef35a87de9d25982ac74e5e1b1d155280904d..9d6a105852a7f4c6e3bbb76767f91b589409b25b 100644 (file)
@@ -995,12 +995,10 @@ cpp_finish_options (pfile)
       struct pending_option *p;
 
       _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0);
-      if (!CPP_OPTION (pfile, traditional) /* REMOVEME */)
-       init_builtins (pfile);
+      init_builtins (pfile);
       _cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0);
-      if (!CPP_OPTION (pfile, traditional) /* REMOVEME */)
-       for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
-         (*p->handler) (pfile, p->arg);
+      for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
+       (*p->handler) (pfile, p->arg);
 
       /* Scan -imacros files after -D, -U, but before -include.
         pfile->next_include_file is NULL, so _cpp_pop_buffer does not
index e819ffca4d0920f96fadc2f1e2a13216f09c6f32..acc6f111f4730d23f1125d4f261c6ba5ea8f2547 100644 (file)
@@ -202,7 +202,8 @@ static const directive linemarker_dir =
   do_linemarker, U"#", 1, KANDR, IN_I
 };
 
-#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF)
+#define SEEN_EOL() (CPP_OPTION (pfile, traditional) \
+                   || pfile->cur_token[-1].type == CPP_EOF)
 
 /* Skip any remaining tokens in a directive.  */
 static void
@@ -447,7 +448,6 @@ 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,39 +459,43 @@ 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, discard_comments_in_macro_exp))
+  if (CPP_OPTION (pfile, traditional))
+    node = _cpp_lex_identifier_trad (pfile);
+  else
     {
-      while (token->type == CPP_COMMENT)
-       token = _cpp_lex_token (pfile);
-    }
+      const cpp_token *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)
-    {
       if (token->type == CPP_EOF)
-       cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
-                  pfile->directive->name);
-      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 (token->val.node));
+       {
+         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
-       cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
-
-      return 0;
+       node = NULL;
     }
 
-  node = token->val.node;
-  if (node->flags & NODE_POISONED)
-    return 0;
-
-  if (node == pfile->spec_nodes.n_defined)
-    {
-      cpp_error (pfile, DL_ERROR, "\"%s\" cannot be used as a macro name",
-                NODE_NAME (node));
-      return 0;
-    }
+  if (!node)
+    cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
+  else if (node->flags & NODE_OPERATOR)
+    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;
 
-  return node;
+  return NULL;
 }
 
 /* Process a #define directive.  Most work is done in cppmacro.c.  */
@@ -1890,6 +1894,9 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
 
   pfile->buffer = new;
 
+  if (CPP_OPTION (pfile, traditional))
+    _cpp_set_trad_context (pfile);
+
   return new;
 }
 
@@ -1934,6 +1941,9 @@ _cpp_pop_buffer (pfile)
            _cpp_maybe_push_include_file (pfile);
        }
     }
+
+  if (pfile->buffer && CPP_OPTION (pfile, traditional))
+    _cpp_set_trad_context (pfile);
 }
 
 /* Enter all recognised directives in the hash table.  */
index ae5dfa92ec966d9af0244b0020e33ef5a4171a09..0b1f0ffc9fea351d5e6bd79c92cfe37549a17e2d 100644 (file)
@@ -62,13 +62,14 @@ static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
 static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, cpp_macro *,
                                  macro_arg *));
 static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
+static bool create_iso_definition PARAMS ((cpp_reader *, cpp_macro *));
 
 /* #define directive parsing and handling.  */
 
 static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
 static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
-static int warn_of_redefinition PARAMS ((const cpp_hashnode *,
-                                        const cpp_macro *));
+static bool warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *,
+                                         const cpp_macro *));
 static int save_parameter PARAMS ((cpp_reader *, cpp_macro *, cpp_hashnode *));
 static int parse_params PARAMS ((cpp_reader *, cpp_macro *));
 static void check_trad_stringification PARAMS ((cpp_reader *,
@@ -917,6 +918,22 @@ push_token_context (pfile, macro, first, count)
   LAST (context).token = first + count;
 }
 
+/* Push a traditional macro's replacement text.  */
+void
+_cpp_push_text_context (pfile, macro, start, end)
+     cpp_reader *pfile;
+     cpp_hashnode *macro;
+     const uchar *start, *end;
+{
+  cpp_context *context = next_context (pfile);
+
+  context->direct_p = true;
+  context->macro = macro;
+  context->buff = NULL;
+  CUR (context) = start;
+  RLIMIT (context) = end;
+}
+
 /* Expand an argument ARG before replacing parameters in a
    function-like macro.  This works by pushing a context with the
    argument's tokens, and then expanding that into a temporary buffer
@@ -1127,8 +1144,9 @@ _cpp_backup_tokens (pfile, count)
 /* #define directive parsing and handling.  */
 
 /* Returns non-zero if a macro redefinition warning is required.  */
-static int
-warn_of_redefinition (node, macro2)
+static bool
+warn_of_redefinition (pfile, node, macro2)
+     cpp_reader *pfile;
      const cpp_hashnode *node;
      const cpp_macro *macro2;
 {
@@ -1137,7 +1155,7 @@ warn_of_redefinition (node, macro2)
 
   /* Some redefinitions need to be warned about regardless.  */
   if (node->flags & NODE_WARN)
-    return 1;
+    return true;
 
   /* Redefinition of a macro is allowed if and only if the old and new
      definitions are the same.  (6.10.3 paragraph 2).  */
@@ -1148,19 +1166,22 @@ warn_of_redefinition (node, macro2)
       || macro1->paramc != macro2->paramc
       || macro1->fun_like != macro2->fun_like
       || macro1->variadic != macro2->variadic)
-    return 1;
-
-  /* Check each token.  */
-  for (i = 0; i < macro1->count; i++)
-    if (! _cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
-      return 1;
+    return true;
 
   /* Check parameter spellings.  */
   for (i = 0; i < macro1->paramc; i++)
     if (macro1->params[i] != macro2->params[i])
-      return 1;
+      return true;
 
-  return 0;
+  /* Check the replacement text or tokens.  */
+  if (CPP_OPTION (pfile, traditional))
+    return memcmp (macro1->exp.text, macro2->exp.text, macro1->count);
+
+  for (i = 0; i < macro1->count; i++)
+    if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
+      return true;
+
+  return false;
 }
 
 /* Free the definition of hashnode H.  */
@@ -1316,24 +1337,13 @@ lex_expansion_token (pfile, macro)
   return token;
 }
 
-/* Parse a macro and save its expansion.  Returns non-zero on success.  */
-int
-_cpp_create_definition (pfile, node)
+static bool
+create_iso_definition (pfile, macro)
      cpp_reader *pfile;
-     cpp_hashnode *node;
+     cpp_macro *macro;
 {
-  cpp_macro *macro;
-  cpp_token *token, *saved_cur_token;
+  cpp_token *token;
   const cpp_token *ctoken;
-  unsigned int i, ok = 1;
-
-  macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
-  macro->line = pfile->directive_line;
-  macro->params = 0;
-  macro->paramc = 0;
-  macro->variadic = 0;
-  macro->count = 0;
-  macro->fun_like = 0;
 
   /* Get the first token of the expansion (or the '(' of a
      function-like macro).  */
@@ -1341,10 +1351,10 @@ _cpp_create_definition (pfile, node)
 
   if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE))
     {
-      ok = parse_params (pfile, macro);
+      bool ok = parse_params (pfile, macro);
       macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
       if (!ok)
-       goto cleanup2;
+       return false;
 
       /* Success.  Commit the parameter array.  */
       BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
@@ -1354,8 +1364,6 @@ _cpp_create_definition (pfile, node)
     cpp_error (pfile, DL_PEDWARN,
               "ISO C requires whitespace after the macro name");
 
-  saved_cur_token = pfile->cur_token;
-
   if (macro->fun_like)
     token = lex_expansion_token (pfile, macro);
   else
@@ -1381,10 +1389,9 @@ _cpp_create_definition (pfile, node)
          /* Let assembler get away with murder.  */
          else if (CPP_OPTION (pfile, lang) != CLK_ASM)
            {
-             ok = 0;
              cpp_error (pfile, DL_ERROR,
                         "'#' is not followed by a macro parameter");
-             goto cleanup1;
+             return false;
            }
        }
 
@@ -1401,10 +1408,9 @@ _cpp_create_definition (pfile, node)
 
          if (macro->count == 0 || token->type == CPP_EOF)
            {
-             ok = 0;
              cpp_error (pfile, DL_ERROR,
                         "'##' cannot appear at either end of a macro expansion");
-             goto cleanup1;
+             return false;
            }
 
          token[-1].flags |= PASTE_LEFT;
@@ -1425,25 +1431,68 @@ _cpp_create_definition (pfile, node)
   /* Commit the memory.  */
   BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
 
-  /* Implement the macro-defined-to-itself optimisation.  */
-  if (macro->count == 1 && !macro->fun_like
-      && macro->exp.tokens[0].type == CPP_NAME
-      && macro->exp.tokens[0].val.node == node)
-    node->flags |= NODE_DISABLED;
+  return true;
+}
+
+/* Parse a macro and save its expansion.  Returns non-zero on success.  */
+bool
+_cpp_create_definition (pfile, node)
+     cpp_reader *pfile;
+     cpp_hashnode *node;
+{
+  cpp_macro *macro;
+  unsigned int i;
+  bool ok;
 
+  macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
+  macro->line = pfile->directive_line;
+  macro->params = 0;
+  macro->paramc = 0;
+  macro->variadic = 0;
+  macro->count = 0;
+  macro->fun_like = 0;
   /* To suppress some diagnostics.  */
   macro->syshdr = pfile->map->sysp != 0;
 
+  if (CPP_OPTION (pfile, traditional))
+    ok = _cpp_create_trad_definition (pfile, macro);
+  else
+    {
+      cpp_token *saved_cur_token = pfile->cur_token;
+
+      ok = create_iso_definition (pfile, macro);
+
+      /* Restore lexer position because of games lex_expansion_token()
+        plays lexing the macro.  We set the type for SEEN_EOL() in
+        cpplib.c.
+
+        Longer term we should lex the whole line before coming here,
+        and just copy the expansion.  */
+      saved_cur_token[-1].type = pfile->cur_token[-1].type;
+      pfile->cur_token = saved_cur_token;
+
+      /* Stop the lexer accepting __VA_ARGS__.  */
+      pfile->state.va_args_ok = 0;
+    }
+
+  /* Clear the fast argument lookup indices.  */
+  for (i = macro->paramc; i-- > 0; )
+    macro->params[i]->arg_index = 0;
+
+  if (!ok)
+    return ok;
+
   if (node->type != NT_VOID)
     {
-      if (warn_of_redefinition (node, macro))
+      if (warn_of_redefinition (pfile, node, macro))
        {
          cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0,
                               "\"%s\" redefined", NODE_NAME (node));
 
          if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
-           cpp_error_with_line (pfile, DL_PEDWARN, node->value.macro->line, 0,
-                           "this is the location of the previous definition");
+           cpp_error_with_line (pfile, DL_PEDWARN,
+                                node->value.macro->line, 0,
+                        "this is the location of the previous definition");
        }
       _cpp_free_definition (node);
     }
@@ -1454,21 +1503,6 @@ _cpp_create_definition (pfile, node)
   if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
     node->flags |= NODE_WARN;
 
- cleanup1:
-
-  /* Set type for SEEN_EOL() in cpplib.c, restore the lexer position.  */
-  saved_cur_token[-1].type = pfile->cur_token[-1].type;
-  pfile->cur_token = saved_cur_token;
-
- cleanup2:
-
-  /* Stop the lexer accepting __VA_ARGS__.  */
-  pfile->state.va_args_ok = 0;
-
-  /* Clear the fast argument lookup indices.  */
-  for (i = macro->paramc; i-- > 0; )
-    macro->params[i]->arg_index = 0;
-
   return ok;
 }
 
index 4f4d97c9ca7eefbede90c5c99c5e0d98aeca032c..6397248733323a3e845161c51920b1ae6dc60166 100644 (file)
@@ -23,16 +23,19 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Lexing TODO: Handle -C, maybe -CC, and space in escaped newlines.
    Stop cpplex.c from recognizing comments and directives during its
-   lexing pass.  Get rid of line_base usage - seems pointless?  */
+   lexing pass.  Get rid of line_base usage - seems pointless?  Do we
+   get escaped newline at EOF correct?  */
 
 static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
 static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
                                                   const uchar *));
+static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *));
 static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
 static const uchar *skip_comment PARAMS ((cpp_reader *, const uchar *));
 static void scan_out_logical_line PARAMS ((cpp_reader *pfile));
 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 *));
 
 /* Ensures we have N bytes' space in the output buffer, and
    reallocates it if not.  */
@@ -118,6 +121,47 @@ skip_comment (pfile, cur)
   return cur;
 }
 
+/* Skip any horizontal whitespace and comments beginning at CUR,
+   returning the following character.  */
+static const uchar *
+skip_whitespace (pfile, cur)
+     cpp_reader *pfile;
+     const uchar *cur;
+{
+  const uchar *tmp;
+
+  for (;;)
+    {
+      while (is_nvspace (*cur) && *cur != 0)
+       cur++;
+
+      if (*cur == '\0' && cur != RLIMIT (pfile->context))
+       continue;
+
+      if (*cur == '\\')
+       {
+         tmp = cur;
+         cur = skip_escaped_newlines (pfile, cur);
+         if (tmp != cur)
+           continue;
+       }
+
+      if (*cur == '/')
+       {
+         tmp = skip_escaped_newlines (pfile, cur + 1);
+         if (*tmp == '*')
+           {
+             cur = skip_comment (pfile, tmp + 1);
+             continue;
+           }
+       }
+
+      break;
+    }
+
+  return 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.  */
@@ -128,6 +172,7 @@ lex_identifier (pfile, cur)
 {
   size_t len;
   uchar *out = pfile->trad_out_cur;
+  cpp_hashnode *result;
 
   do
     {
@@ -140,9 +185,27 @@ lex_identifier (pfile, cur)
 
   CUR (pfile->context) = cur;
   len = out - pfile->trad_out_cur;
+  result = (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->trad_out_cur,
+                                      len, HT_ALLOC);
   pfile->trad_out_cur = out;
-  return (cpp_hashnode *) ht_lookup (pfile->hash_table, pfile->trad_out_cur,
-                                    len, HT_ALLOC);
+  return result;
+}
+
+/* Reads an identifier, returning its hashnode.  If the next token is
+   not an identifier, returns NULL.  */
+cpp_hashnode *
+_cpp_lex_identifier_trad (pfile)
+     cpp_reader *pfile;
+{
+  const uchar *cur = skip_whitespace (pfile, CUR (pfile->context));
+
+  if (!ISIDST (*cur))
+    {
+      CUR (pfile->context) = cur;
+      return NULL;
+    }
+
+  return lex_identifier (pfile, cur);
 }
 
 /* Overlays the true file buffer temporarily with text of length LEN
@@ -226,11 +289,14 @@ static void
 scan_out_logical_line (pfile)
      cpp_reader *pfile;
 {
-  cpp_context *context = pfile->context;
-  const uchar *cur = CUR (context);
+  cpp_context *context;
+  const uchar *cur;
   unsigned int c, quote = 0;
   uchar *out;
 
+ new_context:
+  context = pfile->context;
+  cur = CUR (context);
   check_output_buffer (pfile, RLIMIT (context) - cur);
   out = pfile->trad_out_cur;
 
@@ -246,6 +312,16 @@ scan_out_logical_line (pfile)
        case '\0':
          if (cur - 1 != RLIMIT (context))
            break;
+
+         /* If this is a macro's expansion, pop it.  */
+         if (context->prev)
+           {
+             pfile->trad_out_cur = out - 1;
+             _cpp_pop_context (pfile);
+             goto new_context;
+           }
+
+         /* Premature end of file.  Fake a new line.  */
          cur--;
          if (!pfile->buffer->from_stage3)
            cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
@@ -254,11 +330,10 @@ scan_out_logical_line (pfile)
 
        case '\r': case '\n':
          cur = handle_newline (pfile, cur - 1);
+         out[-1] = '\0';
        finish_output:
-         out[-1] = '\n';
-         out[0] = '\0';
          CUR (context) = cur;
-         pfile->trad_out_cur = out;
+         pfile->trad_out_cur = out - 1;
          return;
 
        case '"':
@@ -309,6 +384,13 @@ scan_out_logical_line (pfile)
 
            pfile->trad_out_cur = --out;
            node = lex_identifier (pfile, cur - 1);
+           if (node->type == NT_MACRO)
+             {
+               /* Remove the macro name from the output.  */
+               pfile->trad_out_cur = out;
+               push_replacement_text (pfile, node);
+               goto new_context;
+             }
            out = pfile->trad_out_cur;
            cur = CUR (context);
          }
@@ -319,3 +401,69 @@ scan_out_logical_line (pfile)
        }
     }
 }
+
+/* Push a context holding the replacement text of the macro NODE on
+   the context stack.  Doesn't yet handle special built-ins or
+   function-like macros.  */
+static void
+push_replacement_text (pfile, node)
+     cpp_reader *pfile;
+     cpp_hashnode *node;
+{
+  cpp_macro *macro = node->value.macro;
+
+  _cpp_push_text_context (pfile, node,
+                         macro->exp.text,
+                         macro->exp.text + macro->count);
+}
+
+/* Analyze and save the replacement text of a macro.  */
+bool
+_cpp_create_trad_definition (pfile, macro)
+     cpp_reader *pfile;
+     cpp_macro *macro;
+{
+  const uchar *cur, *limit;
+  uchar *exp;
+  size_t len;
+
+  /* Skip leading whitespace now.  */
+  CUR (pfile->context) = skip_whitespace (pfile, CUR (pfile->context));
+
+  pfile->trad_out_cur = pfile->trad_out_base;
+  scan_out_logical_line (pfile);
+
+  /* Skip trailing white space.  */
+  cur = pfile->trad_out_base;
+  limit = pfile->trad_out_cur;
+  while (limit > cur && is_space (limit[-1]))
+    limit--;
+
+  len = (size_t) (limit - cur);
+  exp = _cpp_unaligned_alloc (pfile, len + 1);
+  memcpy (exp, cur, len);
+  exp[len] = '\0';
+
+  macro->exp.text = exp;
+  /* Include NUL.  */
+  macro->count = len;
+
+  return true;
+}
+
+/* Prepare to be able to scan the current buffer.  */
+void
+_cpp_set_trad_context (pfile)
+     cpp_reader *pfile;
+{
+  cpp_buffer *buffer = pfile->buffer;
+  cpp_context *context = pfile->context;
+
+  if (pfile->context->prev)
+    abort ();
+
+  pfile->trad_out_cur = pfile->trad_out_base;
+  CUR (context) = buffer->cur;
+  RLIMIT (context) = buffer->rlimit;
+  check_output_buffer (pfile, RLIMIT (context) - CUR (context));
+}
This page took 0.103924 seconds and 5 git commands to generate.