m4-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU M4 source repository branch, master, updated. cvs-readonly-114


From: Eric Blake
Subject: [SCM] GNU M4 source repository branch, master, updated. cvs-readonly-114-g9f8edd9
Date: Tue, 13 May 2008 17:40:10 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU M4 source repository".

http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=9f8edd91d4dcab4e1735f02253c32a55c62f2aac

The branch, master has been updated
       via  9f8edd91d4dcab4e1735f02253c32a55c62f2aac (commit)
       via  4fab2788576b9e10374138be453620a05c95c7be (commit)
      from  43173c1ade54a595a488e750dfba700c89b9fdb8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9f8edd91d4dcab4e1735f02253c32a55c62f2aac
Author: Eric Blake <address@hidden>
Date:   Tue May 13 09:30:04 2008 -0600

    Fix frozen file regression in diversions from 2007-01-21.
    
    * m4/output.c (insert_diversion_helper): Add parameter.
    (m4_insert_file): Move contents...
    (insert_file): ...to this new helper, with added parameter.
    (m4_insert_diversion, m4_undivert_all, m4_freeze_diversions):
    Update callers.
    * src/freeze.c (produce_mem_dump): Simplify.
    (produce_syntax_dump, produce_module_dump): Add parameter.
    * tests/freeze.at (large diversion): Test for this.
    
    Signed-off-by: Eric Blake <address@hidden>

commit 4fab2788576b9e10374138be453620a05c95c7be
Author: Eric Blake <address@hidden>
Date:   Tue May 13 06:25:46 2008 -0600

    Improve error message when frozen file is invalid.
    
    * src/freeze.c (decode_char): Add parameter.  Allow \<newline>
    line continuations.
    (reload_frozen_state): Track current line.
    * tests/freeze.at (loading format 1, loading format 2): Update to
    test this.
    
    Signed-off-by: Eric Blake <address@hidden>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog       |   19 ++++++++++++
 m4/output.c     |   51 +++++++++++++++++++++----------
 src/freeze.c    |   89 ++++++++++++++++++++++++++++++++-----------------------
 tests/freeze.at |   42 +++++++++++++++++++-------
 4 files changed, 136 insertions(+), 65 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 05234af..18e5d0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-05-13  Eric Blake  <address@hidden>
+
+       Fix frozen file regression in diversions from 2007-01-21.
+       * m4/output.c (insert_diversion_helper): Add parameter.
+       (m4_insert_file): Move contents...
+       (insert_file): ...to this new helper, with added parameter.
+       (m4_insert_diversion, m4_undivert_all, m4_freeze_diversions):
+       Update callers.
+       * src/freeze.c (produce_mem_dump): Simplify.
+       (produce_syntax_dump, produce_module_dump): Add parameter.
+       * tests/freeze.at (large diversion): Test for this.
+
+       Improve error message when frozen file is invalid.
+       * src/freeze.c (decode_char): Add parameter.  Allow \<newline>
+       line continuations.
+       (reload_frozen_state): Track current line.
+       * tests/freeze.at (loading format 1, loading format 2): Update to
+       test this.
+
 2008-05-10  Eric Blake  <address@hidden>
 
        Detect integer overflow when loading frozen file.
diff --git a/m4/output.c b/m4/output.c
index c903d99..d3c5507 100644
--- a/m4/output.c
+++ b/m4/output.c
@@ -27,6 +27,7 @@
 #include "exitfail.h"
 #include "gl_avltree_oset.h"
 #include "intprops.h"
+#include "quotearg.h"
 #include "xvasprintf.h"
 
 /* Define this to see runtime debug output.  Implied by DEBUG.  */
@@ -740,19 +741,16 @@ m4_make_diversion (m4 *context, int divnum)
 }
 
 /* Insert a FILE into the current output file, in the same manner
-   diversions are handled.  This allows files to be included, without
-   having them rescanned by m4.  */
-void
-m4_insert_file (m4 *context, FILE *file)
+   diversions are handled.  If ESCAPED, ensure the output is all
+   ASCII.  */
+static void
+insert_file (m4 *context, FILE *file, bool escaped)
 {
   char buffer[COPY_BUFFER_SIZE];
   size_t length;
+  char *str = buffer;
 
-  /* Optimize out inserting into a sink.  */
-
-  if (!output_diversion)
-    return;
-
+  assert (output_diversion);
   /* Insert output by big chunks.  */
   for (;;)
     {
@@ -762,16 +760,29 @@ m4_insert_file (m4 *context, FILE *file)
                  _("reading inserted file"));
       if (length == 0)
        break;
-      m4_output_text (context, buffer, length);
+      if (escaped)
+       str = quotearg_style_mem (escape_quoting_style, buffer, length);
+      m4_output_text (context, str, escaped ? strlen (str) : length);
     }
 }
 
+/* Insert a FILE into the current output file, in the same manner
+   diversions are handled.  This allows files to be included, without
+   having them rescanned by m4.  */
+void
+m4_insert_file (m4 *context, FILE *file)
+{
+  /* Optimize out inserting into a sink.  */
+  if (output_diversion)
+    insert_file (context, file, false);
+}
+
 /* Insert DIVERSION living at NODE into the current output file.  The
    diversion is NOT placed on the expansion obstack, because it must
-   not be rescanned.  When the file is closed, it is deleted by the
-   system.  */
+   not be rescanned.  If ESCAPED, ensure the output is ASCII.  When
+   the file is closed, it is deleted by the system.  */
 static void
-insert_diversion_helper (m4 *context, m4_diversion *diversion)
+insert_diversion_helper (m4 *context, m4_diversion *diversion, bool escaped)
 {
   assert (diversion->divnum > 0
          && diversion->divnum != m4_get_current_diversion (context));
@@ -779,7 +790,13 @@ insert_diversion_helper (m4 *context, m4_diversion 
*diversion)
   if (output_diversion)
     {
       if (diversion->size)
-       m4_output_text (context, diversion->u.buffer, diversion->used);
+       {
+         char *str = diversion->u.buffer;
+         size_t len = diversion->used;
+         if (escaped)
+           str = quotearg_style_mem (escape_quoting_style, str, len);
+         m4_output_text (context, str, escaped ? strlen (str) : len);
+       }
       else
        {
          assert (diversion->used);
@@ -836,7 +853,7 @@ m4_insert_diversion (m4 *context, int divnum)
     {
       m4_diversion *diversion = (m4_diversion *) elt;
       if (diversion->divnum == divnum)
-       insert_diversion_helper (context, diversion);
+       insert_diversion_helper (context, diversion, false);
     }
 }
 
@@ -852,7 +869,7 @@ m4_undivert_all (m4 *context)
     {
       m4_diversion *diversion = (m4_diversion *) elt;
       if (diversion->divnum != divnum)
-       insert_diversion_helper (context, diversion);
+       insert_diversion_helper (context, diversion, false);
     }
   gl_oset_iterator_free (&iter);
 }
@@ -902,7 +919,7 @@ m4_freeze_diversions (m4 *context, FILE *file)
                        (unsigned long int) file_stat.st_size);
            }
 
-         insert_diversion_helper (context, diversion);
+         insert_diversion_helper (context, diversion, true);
          putc ('\n', file);
 
          last_inserted = diversion->divnum;
diff --git a/src/freeze.c b/src/freeze.c
index 186b69b..0b48ac6 100644
--- a/src/freeze.c
+++ b/src/freeze.c
@@ -25,6 +25,7 @@
 #include "m4.h"
 
 #include "binary-io.h"
+#include "quotearg.h"
 
 static void  produce_mem_dump          (FILE *, const char *, size_t);
 static void  produce_resyntax_dump     (m4 *, FILE *);
@@ -34,7 +35,7 @@ static        void  produce_symbol_dump       (m4 *, FILE *, 
m4_symbol_table *);
 static void *dump_symbol_CB            (m4_symbol_table *, const char *,
                                         m4_symbol *, void *);
 static void  issue_expect_message      (m4 *, int);
-static int   decode_char               (FILE *);
+static int   decode_char               (m4 *, FILE *, bool *);
 
 
 /* Dump an ASCII-encoded representation of LEN bytes at MEM to FILE.
@@ -42,34 +43,9 @@ static       int   decode_char               (FILE *);
 static void
 produce_mem_dump (FILE *file, const char *mem, size_t len)
 {
-  while (len--)
-    {
-      int ch = to_uchar (*mem++);
-      switch (ch)
-       {
-       case '\a': putc ('\\', file); putc ('a', file); break;
-       case '\b': putc ('\\', file); putc ('b', file); break;
-       case '\f': putc ('\\', file); putc ('f', file); break;
-       case '\n': putc ('\\', file); putc ('n', file); break;
-       case '\r': putc ('\\', file); putc ('r', file); break;
-       case '\t': putc ('\\', file); putc ('t', file); break;
-       case '\v': putc ('\\', file); putc ('v', file); break;
-       case '\\': putc ('\\', file); putc ('\\', file); break;
-       default:
-         if (ch >= 0x7f || ch < 0x20)
-           {
-             int digit = ch / 16;
-             ch %= 16;
-             digit += digit > 9 ? 'a' - 10 : '0';
-             ch += ch > 9 ? 'a' - 10 : '0';
-             putc ('\\', file);
-             putc ('x', file);
-             putc (digit, file);
-           }
-         putc (ch, file);
-         break;
-       }
-    }
+  char *quoted = quotearg_style_mem (escape_quoting_style, mem, len);
+  /* Any errors will be detected by ferror later.  */
+  fwrite (quoted, strlen (quoted), 1, file);
 }
 
 
@@ -294,13 +270,19 @@ issue_expect_message (m4 *context, int expected)
    unrecognized escape sequence.  */
 
 static int
-decode_char (FILE *in)
+decode_char (m4 *context, FILE *in, bool *advance_line)
 {
   int ch = getc (in);
   int next;
   int value = 0;
 
-  if (ch == '\\')
+  if (*advance_line)
+    {
+      m4_set_current_line (context, m4_get_current_line (context) + 1);
+      *advance_line = false;
+    }
+
+  while (ch == '\\')
     {
       ch = getc (in);
       switch (ch)
@@ -314,6 +296,11 @@ decode_char (FILE *in)
        case 'v': return '\v';
        case '\\': return '\\';
 
+       case '\n':
+         ch = getc (in);
+         m4_set_current_line (context, m4_get_current_line (context) + 1);
+         continue;
+
        case 'x': case 'X':
          next = getc (in);
          if (next >= '0' && next <= '9')
@@ -360,6 +347,8 @@ decode_char (FILE *in)
        }
     }
 
+  if (ch == '\n')
+    *advance_line = true;
   return ch;
 }
 
@@ -378,9 +367,22 @@ reload_frozen_state (m4 *context, const char *name)
   char *string[3];
   size_t allocated[3];
   int number[3] = {0};
-
-#define GET_CHARACTER                                          \
-  (character = getc (file))
+  bool advance_line = true;
+
+#define GET_CHARACTER                                                  \
+  do                                                                   \
+    {                                                                  \
+      if (advance_line)                                                        
\
+       {                                                               \
+         m4_set_current_line (context,                                 \
+                              m4_get_current_line (context) + 1);      \
+         advance_line = false;                                         \
+       }                                                               \
+      character = getc (file);                                         \
+      if (character == '\n')                                           \
+       advance_line = true;                                            \
+    }                                                                  \
+  while (0)
 
 #define GET_NUMBER(Number, AllowNeg)                           \
   do                                                           \
@@ -404,12 +406,14 @@ reload_frozen_state (m4 *context, const char *name)
     {                                                          \
       size_t len = (StrLen);                                   \
       char *p;                                                 \
+      int ch;                                                  \
       CHECK_ALLOCATION ((Buf), (BufSize), len);                        \
       p = (Buf);                                               \
       while (len-- > 0)                                                \
        {                                                       \
-         int ch = (version > 1 ? decode_char (File)            \
-                   : getc (File));                             \
+         ch = (version > 1                                     \
+               ? decode_char (context, File, &advance_line)    \
+               : getc (File));                                 \
          if (ch == EOF)                                        \
            m4_error (context, EXIT_FAILURE, 0, NULL,           \
                      _("premature end of frozen file"));       \
@@ -452,12 +456,19 @@ reload_frozen_state (m4 *context, const char *name)
            GET_CHARACTER;                                      \
          VALIDATE ('\n');                                      \
        }                                                       \
+      else if (character == '\\')                              \
+       {                                                       \
+         GET_CHARACTER;                                        \
+         VALIDATE ('\n');                                      \
+         continue;                                             \
+       }                                                       \
     }                                                          \
   while (character == '\n')
 
   file = m4_path_search (context, name, (char **)NULL);
   if (file == NULL)
     m4_error (context, EXIT_FAILURE, errno, NULL, _("cannot open `%s'"), name);
+  m4_set_current_file (context, name);
 
   allocated[0] = 100;
   string[0] = xcharalloc (allocated[0]);
@@ -773,7 +784,11 @@ ill-formed frozen file, version 2 directive `%c' 
encountered"), 'T');
   free (string[0]);
   free (string[1]);
   free (string[2]);
-  fclose (file);
+  if (ferror (file) || fclose (file) != 0)
+    m4_error (context, EXIT_FAILURE, errno, NULL,
+             _("unable to read frozen state"));
+  m4_set_current_file (context, NULL);
+  m4_set_current_line (context, 0);
 
 #undef GET_STRING
 #undef GET_CHARACTER
diff --git a/tests/freeze.at b/tests/freeze.at
index 56933b7..74dc3e9 100644
--- a/tests/freeze.at
+++ b/tests/freeze.at
@@ -27,9 +27,10 @@ AT_SETUP([large diversion])
 AT_KEYWORDS([frozen])
 
 # Check that large diversions are handled across freeze boundaries.
-
+# Also check for escape character handling.
 AT_DATA([[frozen.m4]], [M4_ONE_MEG_DEFN[divert(2)f
 divert(1)hi
+a\nb
 ]])
 
 AT_DATA([[unfrozen.m4]],
@@ -138,6 +139,15 @@ bar${1}
 [[m4:input.m4:5: Warning: popdef: undefined macro `my_define'
 ]])
 
+dnl Test rejection of v2 features in a v1 frozen file
+AT_DATA([bogus.m4f], [[V1
+M2
+m4
+]])
+AT_CHECK_M4([-R bogus.m4f], [1], [],
+[[m4:bogus.m4f:2: ill-formed frozen file, version 2 directive `M' encountered
+]])
+
 AT_CLEANUP
 
 
@@ -167,6 +177,10 @@ builtinbuiltingnu
 # introduced 2007-05-28 and fixed 2007-05-31.
 D-1,5
 12345
+# Check line continuations.
+D1,3
+a\n\
+b
 # Zero can be implied
 D,
 
@@ -193,13 +207,15 @@ AT_CHECK_M4([-R frozen.m4f input.m4], [0],
 
 bar
        '7 \
-]])
+a
+b]])
 
 dnl We don't support anything larger than format 2; make sure of that...
-AT_DATA([bogus.m4f], [[V3
+AT_DATA([bogus.m4f], [[# comments aren't continued\
+V3
 ]])
 AT_CHECK_M4([-R bogus.m4f], [63], [],
-[[m4: frozen file version 3 greater than max supported of 2
+[[m4:bogus.m4f:2: frozen file version 3 greater than max supported of 2
 ]])
 
 dnl Check that V appears.
@@ -207,7 +223,7 @@ AT_DATA([bogus.m4f], [[# not really a frozen file
 oops
 ]])
 AT_CHECK_M4([-R bogus.m4f], [1], [],
-[[m4: expecting character `V' in frozen file
+[[m4:bogus.m4f:2: expecting character `V' in frozen file
 ]])
 
 dnl M4_DIVNUM_TEST(number, [out-of-bounds])
@@ -220,8 +236,12 @@ M2
 m4
 M3
 gnu
+T1,5
+a\n\n\n\n\n
 F6,6,2
-divnumdivnumm4
+divnum\
+divnumm4\
+
 F6,6,2
 divertdivertm4
 F6,6,2
@@ -231,16 +251,16 @@ hi
 
 ]])
 AT_CHECK_M4([-R frozen.m4f in.m4], m4_ifval([$2], [1], [0]),
-m4_ifval([$2], [], [[$1
-]m4_if(m4_substr([$1], [0], [1]), [-], [], [[hi
-]])]), m4_ifval([$2], [[m4: integer overflow in frozen file
+m4_ifval([$2], [], [m4_bpatsubst([$1], [^0*])
+m4_if(m4_substr([$1], [0], [1]), [-], [], [[hi
+]])]), m4_ifval([$2], [[m4:frozen.m4f:16: integer overflow in frozen file
 ]]))
 ])
 
 AT_DATA([in.m4], [[define(d,divnum)divert(0)d
 ]])
-M4_DIVNUM_TEST([2147483647])
-M4_DIVNUM_TEST([2147483648], [:])
+M4_DIVNUM_TEST([02147483647])
+M4_DIVNUM_TEST([02147483648], [:])
 M4_DIVNUM_TEST([-2147483648])
 M4_DIVNUM_TEST([-2147483649], [:])
 


hooks/post-receive
--
GNU M4 source repository




reply via email to

[Prev in Thread] Current Thread [Next in Thread]