OSDN Git Service

* cpphash.h (struct cpp_macro): Put comments on their own lines.
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Jun 2002 06:03:13 +0000 (06:03 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Jun 2002 06:03:13 +0000 (06:03 +0000)
(_cpp_expansions_different_trad): New.
* cppmacro.c (warn_of_redefinition): Fix for traditional case.
* cpptrad.c (canonicalize_text): New.
(scan_out_logical_line): Handle no arguments correctly.
(save_replacement_text): Commit memory when finished.
(_cpp_expansions_different_trad): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54432 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 94b77eb..0f6cf2e 100644 (file)
@@ -1,3 +1,13 @@
+2002-06-10  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * cpphash.h (struct cpp_macro): Put comments on their own lines.
+       (_cpp_expansions_different_trad): New.
+       * cppmacro.c (warn_of_redefinition): Fix for traditional case.
+       * cpptrad.c (canonicalize_text): New.
+       (scan_out_logical_line): Handle no arguments correctly.
+       (save_replacement_text): Commit memory when finished.
+       (_cpp_expansions_different_trad): New.
+
 2002-06-10  Tim Josling  <tej@melbpc.org.au>
 
        * gengtype.c (unnamed enum containing BASE_FILE_*): Add languages
index 6baf211..6d41ead 100644 (file)
@@ -69,18 +69,35 @@ struct dummy
    Variadic macros cannot occur with traditional cpp.  */
 struct cpp_macro
 {
-  cpp_hashnode **params;       /* Parameters, if any.  */
+  /* Parameters, if any.  */
+  cpp_hashnode **params;
+
+  /* Replacement tokens (ISO) or replacement text (traditional).  See
+     comment at top of cpptrad.c for how traditional function-like
+     macros are encoded.  */
   union
   {
-    cpp_token *tokens;         /* Tokens of replacement list (ISO).  */
-    const uchar *text;         /* Expansion text (traditional).  */
+    cpp_token *tokens;
+    const uchar *text;
   } exp;
-  unsigned int line;           /* Starting line number.  */
-  unsigned int count;          /* Number of tokens / bytes in expansion.  */
-  unsigned short paramc;       /* Number of parameters.  */
-  unsigned int fun_like : 1;   /* If a function-like macro.  */
-  unsigned int variadic : 1;   /* If a variadic macro.  */
-  unsigned int syshdr   : 1;   /* If macro defined in system header.  */
+
+  /* Definition line number.  */
+  unsigned int line;
+
+  /* Number of tokens in expansion, or bytes for traditional macros.  */
+  unsigned int count;
+
+  /* Number of parameters.  */
+  unsigned short paramc;
+
+  /* If a function-like macro.  */
+  unsigned int fun_like : 1;
+
+  /* If a variadic macro.  */
+  unsigned int variadic : 1;
+
+  /* If macro defined in system header.  */
+  unsigned int syshdr   : 1;
 };
 
 /* A generic memory buffer, and operations on it.  */
@@ -499,6 +516,7 @@ extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
 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 *));
+extern bool _cpp_expansions_different_trad PARAMS ((cpp_macro *, cpp_macro *));
 
 /* Utility routines and macros.  */
 #define DSC(str) (const uchar *)str, sizeof str - 1
index d517948..a9ca6cf 100644 (file)
@@ -1176,9 +1176,9 @@ warn_of_redefinition (pfile, node, macro2)
      definitions are the same.  (6.10.3 paragraph 2).  */
   macro1 = node->value.macro;
 
-  /* The quick failures.  */
-  if (macro1->count != macro2->count
-      || macro1->paramc != macro2->paramc
+  /* Don't check count here as it can be different in valid
+     traditional redefinitions with just whitespace differences.  */
+  if (macro1->paramc != macro2->paramc
       || macro1->fun_like != macro2->fun_like
       || macro1->variadic != macro2->variadic)
     return true;
@@ -1190,11 +1190,12 @@ warn_of_redefinition (pfile, node, macro2)
 
   /* Check the replacement text or tokens.  */
   if (CPP_OPTION (pfile, traditional))
-    return memcmp (macro1->exp.text, macro2->exp.text, macro1->count);
+    return _cpp_expansions_different_trad (macro1, macro2);
 
-  for (i = 0; i < macro1->count; i++)
-    if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
-      return true;
+  if (macro1->count == macro2->count)
+    for (i = 0; i < macro1->count; i++)
+      if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
+       return true;
 
   return false;
 }
index 7ba9d92..4a76f96 100644 (file)
@@ -89,6 +89,8 @@ static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *,
                                         const uchar *, struct fun_macro *));
 static void save_argument PARAMS ((struct fun_macro *, size_t));
 static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *));
+static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t,
+                                        uchar *));
 
 /* Ensures we have N bytes' space in the output buffer, and
    reallocates it if not.  */
@@ -557,16 +559,11 @@ scan_out_logical_line (pfile, macro)
                  pfile->state.parsing_args = 0;
                  save_argument (&fmacro, out - pfile->trad_out_base);
 
-                 /* A single whitespace argument is no argument.  */
-                 if (fmacro.argc == 1 && m->paramc == 0)
-                   {
-                     const uchar *p = pfile->trad_out_base;
-                     p += fmacro.args[0];
-                     while (is_space (*p))
-                       p++;
-                     if (p == pfile->trad_out_base + fmacro.args[1])
-                       fmacro.argc = 0;
-                   }
+                 /* A single zero-length argument is no argument.  */
+                 if (fmacro.argc == 1
+                     && m->paramc == 0
+                     && out == pfile->trad_out_base + 1)
+                   fmacro.argc = 0;
 
                  if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
                    {
@@ -758,11 +755,11 @@ save_replacement_text (pfile, macro, arg_index)
       /* Lex the rest into the start of the output buffer.  */
       pfile->trad_out_cur = pfile->trad_out_base;
 
-      /* If this is the end of the macro, count up the bytes of text
-        in the replacement list, excluding the parameter names, and
-        save this in macro->count, else store the total bytes in the
-        replacement text so far (including block headers).  */
       macro->count += blen;
+
+      /* If we've finished, commit the memory.  */
+      if (arg_index == 0)
+       BUFF_FRONT (pfile->a_buff) += macro->count;
     }
 }
 
@@ -814,6 +811,95 @@ _cpp_create_trad_definition (pfile, macro)
   return true;
 }
 
+/* Copy SRC of length LEN to DEST, but convert all contiguous
+   whitespace to a single space, provided it is not in quotes.  The
+   quote currently in effect is pointed to by PQUOTE, and is updated
+   by the function.  Returns the number of bytes copied.  */
+static size_t
+canonicalize_text (dest, src, len, pquote)
+     uchar *dest;
+     const uchar *src;
+     size_t len;
+     uchar *pquote;
+{
+  uchar *orig_dest = dest;
+  uchar quote = *pquote;
+
+  while (len)
+    {
+      if (is_space (*src) && !quote)
+       {
+         do
+           src++, len--;
+         while (len && is_space (*src));
+         *dest++ = ' ';
+       }
+      else
+       {
+         if (*src == '\'' || *src == '"')
+           {
+             if (!quote)
+               quote = *src;
+             else if (quote == *src)
+               quote = 0;
+           }
+         *dest++ = *src++, len--;
+       }
+    }
+
+  *pquote = quote;
+  return dest - orig_dest;
+}
+
+/* Returns true if MACRO1 and MACRO2 have expansions different other
+   than in the form of their whitespace.  */
+bool
+_cpp_expansions_different_trad (macro1, macro2)
+     cpp_macro *macro1, *macro2;
+{
+  uchar *p1 = xmalloc (macro1->count + macro2->count);
+  uchar *p2 = p1 + macro1->count;
+  uchar quote1 = 0, quote2;
+  bool mismatch;
+  size_t len1, len2;
+
+  if (macro1->paramc > 0)
+    {
+      const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;
+
+      mismatch = true;
+      for (;;)
+       {
+         struct block *b1 = (struct block *) exp1;
+         struct block *b2 = (struct block *) exp2;
+
+         if (b1->arg_index != b2->arg_index)
+           break;
+
+         len1 = canonicalize_text (p1, b1->text, b1->text_len, &quote1);
+         len2 = canonicalize_text (p2, b2->text, b2->text_len, &quote2);
+         if (len1 != len2 || memcmp (p1, p2, len1))
+           break;
+         if (b1->arg_index == 0)
+           {
+             mismatch = false;
+             break;
+           }
+         exp1 += BLOCK_LEN (b1->text_len);
+         exp2 += BLOCK_LEN (b2->text_len);
+       }
+    }
+  else
+    {
+      len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, &quote1);
+      len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, &quote2);
+      mismatch = (len1 != len2 || memcmp (p1, p2, len1));
+    }
+
+  free (p1);
+  return mismatch;
+}
+
 /* Prepare to be able to scan the current buffer.  */
 void
 _cpp_set_trad_context (pfile)