m4-patches
[Top][All Lists]
Advanced

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

Re: proposal for version mismatch


From: Eric Blake
Subject: Re: proposal for version mismatch
Date: Thu, 27 Jul 2006 07:28:16 -0600
User-agent: Thunderbird 1.5.0.4 (Windows/20060516)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Eric Blake on 7/18/2006 9:32 AM:
> 2006-07-18  Eric Blake  <address@hidden>
> 
>       * src/m4.h (EXIT_MISMATCH): Define.
>       * src/freeze.c (reload_frozen_state): Detect version mismatch, by
>       exiting with status 63.
>       * src/m4.c (usage): Document this.
>       * doc/m4.texinfo (Invoking m4, Using frozen files): Likewise.
>       * NEWS: Likewise.

Ported to head as follows.  We are closer to passing the frozen file
format 1 test; I still need to get placeholders working, and update the
testsuite to deal with the warning that head produces when popdef'ing an
undefined macro (1.4.x did not warn in this case).  But at least head can
now parse frozen files from m4 1.4.x, minus unknown macros, rather than
rejecting the frozen file as ill-formed.

2006-07-27  Eric Blake  <address@hidden>

        * m4/system_.h (EXIT_MISMATCH): Define.
        * src/main.c (main): Don't clear syntax table for version 1.
        (usage): Document exit status.
        * src/freeze.c (reload_frozen_state): Port GET_DIRECTIVE from the
        branch, and require V directive to appear first in file.  Fix
        broken logic for detecting F and T in version 1 files.

- --
Life is short - so eat dessert first!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEyL9w84KuGfSFAYARAtE9AKCLZTnUe6A1BiJWUBwMPB4iWo7L+ACgnB4+
RYHJ5RK62+ASISgfaZvf8rc=
=HQjs
-----END PGP SIGNATURE-----
Index: m4/system_.h
===================================================================
RCS file: /sources/m4/m4/m4/system_.h,v
retrieving revision 1.12
diff -u -p -r1.12 system_.h
--- m4/system_.h        1 May 2005 11:10:05 -0000       1.12
+++ m4/system_.h        27 Jul 2006 13:24:14 -0000
@@ -1,5 +1,5 @@
 /* GNU m4 -- A simple macro processor
-   Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright 2000, 2001, 2003, 2006 Free Software Foundation, Inc.
 
    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
@@ -46,6 +46,11 @@
 #include <gnu/xalloc.h>
 #include <gnu/xstrndup.h>
 
+/* In addition to EXIT_SUCCESS and EXIT_FAILURE, m4 can fail with version
+   mismatch when trying to load a frozen file produced by a newer m4 than
+   the version doing the reload.  */
+#define EXIT_MISMATCH 63
+
 /* This is okay in an installed file, because it will not change the
    behaviour of the including program whether ENABLE_NLS is defined
    or not.  */
Index: src/freeze.c
===================================================================
RCS file: /sources/m4/m4/src/freeze.c,v
retrieving revision 1.44
diff -u -p -r1.44 freeze.c
--- src/freeze.c        13 Jul 2006 23:35:16 -0000      1.44
+++ src/freeze.c        27 Jul 2006 13:24:15 -0000
@@ -163,8 +163,8 @@ produce_symbol_dump (m4 *context, FILE *
 }
 
 static void *
-dump_symbol_CB (m4_symbol_table *symtab, const char *symbol_name, m4_symbol 
*symbol,
-               void *userdata)
+dump_symbol_CB (m4_symbol_table *symtab, const char *symbol_name,
+               m4_symbol *symbol, void *userdata)
 {
   lt_dlhandle   handle         = SYMBOL_HANDLE (symbol);
   const char   *module_name    = handle ? m4_get_module_name (handle) : NULL;
@@ -361,7 +361,7 @@ void
 reload_frozen_state (m4 *context, const char *name)
 {
   FILE *file;
-  int version = 0;
+  int version;
   int character;
   int operation;
   char syntax;
@@ -416,6 +416,22 @@ reload_frozen_state (m4 *context, const 
     }                                                          \
   while (0)
 
+  /* Skip comments (`#' at beginning of line) and blank lines, setting
+     character to the next directive or to EOF.  */
+
+#define GET_DIRECTIVE \
+  do                                                            \
+    {                                                           \
+      GET_CHARACTER;                                            \
+      if (character == '#')                                     \
+        {                                                       \
+          while (character != EOF && character != '\n')         \
+            GET_CHARACTER;                                      \
+          VALIDATE ('\n');                                      \
+        }                                                       \
+    }                                                           \
+  while (character == '\n')
+
   file = m4_path_search (context, name, (char **)NULL);
   if (file == NULL)
     M4ERROR ((EXIT_FAILURE, errno, _("Cannot open %s"), name));
@@ -427,317 +443,338 @@ reload_frozen_state (m4 *context, const 
   allocated[2] = 100;
   string[2] = xmalloc ((size_t) allocated[2]);
 
-  while (GET_CHARACTER, character != EOF)
-    switch (character)
+  /* Validate format version.  Accept both `1' (m4 1.3 and 1.4.x) and
+     `2' (m4 2.0).  */
+  GET_DIRECTIVE;
+  VALIDATE ('V');
+  GET_CHARACTER;
+  GET_NUMBER (version);
+  switch (version)
+    {
+    case 2:
       {
-      default:
-       M4ERROR ((EXIT_FAILURE, 0, _("Ill-formed frozen file")));
-
-      case '\n':
+       int ch;
 
-       /* Skip empty lines.  */
-
-       break;
-
-      case '#':
+       /* Take care not to mix frozen state with startup state.  */
+       for (ch = 256; --ch > 0;)
+         context->syntax->table[ch] = 0;
+      }
+      break;
+    case 1:
+      {
+       //      sleep(100);
+       m4__module_open (context, "m4", NULL);
+       if (m4_get_no_gnu_extensions_opt (context))
+         m4__module_open (context, "traditional", NULL);
+       else
+         m4__module_open (context, "gnu", NULL);
+      }
+      break;
+    default:
+      if (version > 2)
+       M4ERROR ((EXIT_MISMATCH, 0,
+                 "frozen file version %d greater than max supported of 2",
+                 version));
+      else
+       M4ERROR ((EXIT_FAILURE, 0,
+                 "ill-formed frozen file, version directive expected"));
+    }
+  VALIDATE ('\n');
 
-       /* Comments are introduced by `#' at beginning of line, and are
-          ignored.  */
+  GET_DIRECTIVE;
+  while (character != EOF)
+    {
+      switch (character)
+       {
+       default:
+         M4ERROR ((EXIT_FAILURE, 0,
+                   _("ill-formed frozen file, unknown directive %c"),
+                   character));
 
-       while (character != EOF && character != '\n')
+       case 'F':
          GET_CHARACTER;
-       VALIDATE ('\n');
-       break;
-
-      case 'F':
-       GET_CHARACTER;
 
-       /* Get string lengths. */
+         /* Get string lengths. */
 
-       GET_NUMBER (number[0]);
-       VALIDATE (',');
-       GET_CHARACTER;
-       GET_NUMBER (number[1]);
+         GET_NUMBER (number[0]);
+         VALIDATE (',');
+         GET_CHARACTER;
+         GET_NUMBER (number[1]);
 
-       if ((character == ',') && (version > 1))
-         {
-           /* 'F' operator accepts an optional third argument for
-              format versions 2 or later.  */
-           GET_CHARACTER;
-           GET_NUMBER (number[2]);
-         }
-       else if (version > 1)
-         {
-           number[2] = 0;
-         }
-       else
-         {
-           /* 3 argument 'F' operations are invalid for format version 1.  */
-           M4ERROR ((EXIT_FAILURE, 0, _("Ill-formed frozen file")));
-         }
+         if (character == ',')
+           {
+             if (version > 1)
+               {
+                 /* 'F' operator accepts an optional third argument for
+                    format versions 2 or later.  */
+                 GET_CHARACTER;
+                 GET_NUMBER (number[2]);
+               }
+             else
+               /* 3 argument 'F' operations are invalid for format
+                  version 1.  */
+               M4ERROR ((EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive encountered")));
+           }
+         else
+           {
+             number[2] = 0;
+           }
 
-       VALIDATE ('\n');
+         VALIDATE ('\n');
 
 
-       /* Get string contents.  */
+         /* Get string contents.  */
 
-       GET_STRING (file, string[0], allocated[0], number[0]);
-       GET_STRING (file, string[1], allocated[1], number[1]);
-       if ((number[2] > 0)  && (version > 1))
+         GET_STRING (file, string[0], allocated[0], number[0]);
+         GET_STRING (file, string[1], allocated[1], number[1]);
          GET_STRING (file, string[2], allocated[2], number[2]);
-       VALIDATE ('\n');
+         VALIDATE ('\n');
 
-       /* Enter a macro having a builtin function as a definition.  */
-       {
-         const m4_builtin *bp = NULL;
-         lt_dlhandle handle   = 0;
+         /* Enter a macro having a builtin function as a definition.  */
+         {
+           const m4_builtin *bp;
+           lt_dlhandle handle   = 0;
 
-         if (number[2] > 0)
-           handle = m4__module_find (string[2]);
+           if (number[2] > 0)
+             handle = m4__module_find (string[2]);
 
-         if (handle)
            bp = m4_builtin_find_by_name (handle, string[1]);
 
-         if (bp)
-           {
-             m4_symbol_value *token = xzalloc (sizeof *token);
-
-             if (bp->groks_macro_args)
-               BIT_SET (VALUE_FLAGS (token), VALUE_MACRO_ARGS_BIT);
-             if (bp->blind_if_no_args)
-               BIT_SET (VALUE_FLAGS (token), VALUE_BLIND_ARGS_BIT);
+           if (bp)
+             {
+               m4_symbol_value *token = xzalloc (sizeof *token);
 
-             m4_set_symbol_value_func (token, bp->func);
-             VALUE_HANDLE (token)      = handle;
-             VALUE_MIN_ARGS (token)    = bp->min_args;
-             VALUE_MAX_ARGS (token)    = bp->max_args;
+               if (bp->groks_macro_args)
+                 BIT_SET (VALUE_FLAGS (token), VALUE_MACRO_ARGS_BIT);
+               if (bp->blind_if_no_args)
+                 BIT_SET (VALUE_FLAGS (token), VALUE_BLIND_ARGS_BIT);
+
+               m4_set_symbol_value_func (token, bp->func);
+               VALUE_HANDLE (token)    = handle;
+               VALUE_MIN_ARGS (token)  = bp->min_args;
+               VALUE_MAX_ARGS (token)  = bp->max_args;
 
-             m4_symbol_pushdef (M4SYMTAB, string[0], token);
-           }
-         else
-           M4ERROR ((m4_get_warning_status_opt (context), 0,
-                     _("`%s' from frozen file not found in builtin table!"),
-                     string[0]));
-       }
-       break;
+               m4_symbol_pushdef (M4SYMTAB, string[0], token);
+             }
+           else
+             M4ERROR ((m4_get_warning_status_opt (context), 0,
+                       _("`%s' from frozen file not found in builtin table!"),
+                       string[0]));
+         }
+         break;
 
-      case 'M':
+       case 'M':
 
-       /* Load a module, but *without* perturbing the symbol table.
-          Note that any expansion from loading the module which would
-          have been seen when loading it originally is discarded
-          when loading it from a frozen file. */
+         /* Load a module, but *without* perturbing the symbol table.
+            Note that any expansion from loading the module which would
+            have been seen when loading it originally is discarded
+            when loading it from a frozen file. */
 
-       if (version < 2)
-         {
-           /* 'M' operator is not supported in format version 1. */
-           M4ERROR ((EXIT_FAILURE, 0, _("Ill-formed frozen file")));
-         }
+         if (version < 2)
+           {
+             /* 'M' operator is not supported in format version 1. */
+             M4ERROR ((EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive encountered")));
+           }
 
-       GET_CHARACTER;
-       GET_NUMBER (number[0]);
-       VALIDATE ('\n');
-       GET_STRING (file, string[0], allocated[0], number[0]);
-       VALIDATE ('\n');
+         GET_CHARACTER;
+         GET_NUMBER (number[0]);
+         VALIDATE ('\n');
+         GET_STRING (file, string[0], allocated[0], number[0]);
+         VALIDATE ('\n');
 
-       m4__module_open (context, string[0], NULL);
+         m4__module_open (context, string[0], NULL);
 
-       break;
+         break;
 
-      case 'R':
+       case 'R':
 
-       if (version < 2)
-         {
-           /* 'R' operator is not supported in format version 1. */
-           M4ERROR ((EXIT_FAILURE, 0, _("Ill-formed frozen file")));
-         }
+         if (version < 2)
+           {
+             /* 'R' operator is not supported in format version 1. */
+             M4ERROR ((EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive encountered")));
+           }
 
-       GET_CHARACTER;
-       GET_NUMBER (number[0]);
-       VALIDATE ('\n');
-       GET_STRING (file, string[0], allocated[0], number[0]);
-       VALIDATE ('\n');
-
-       m4_set_regexp_syntax_opt (context,
-                                 m4_regexp_syntax_encode (string[0]));
-       if (m4_get_regexp_syntax_opt (context) < 0)
-         {
-           M4ERROR ((EXIT_FAILURE, 0,
-                     _("Unknown regexp syntax code %s"), string[0]));
-         }
+         GET_CHARACTER;
+         GET_NUMBER (number[0]);
+         VALIDATE ('\n');
+         GET_STRING (file, string[0], allocated[0], number[0]);
+         VALIDATE ('\n');
 
-       break;
+         m4_set_regexp_syntax_opt (context,
+                                   m4_regexp_syntax_encode (string[0]));
+         if (m4_get_regexp_syntax_opt (context) < 0)
+           {
+             M4ERROR ((EXIT_FAILURE, 0,
+                       _("Unknown regexp syntax code %s"), string[0]));
+           }
 
-      case 'S':
+         break;
 
-       if (version < 2)
-         {
-           /* 'S' operator is not supported in format version 1. */
-           M4ERROR ((EXIT_FAILURE, 0, _("Ill-formed frozen file")));
-         }
+       case 'S':
 
-       GET_CHARACTER;
-       syntax = character;
-       GET_CHARACTER;
-       GET_NUMBER (number[0]);
-       VALIDATE ('\n');
+         if (version < 2)
+           {
+             /* 'S' operator is not supported in format version 1. */
+             M4ERROR ((EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive encountered")));
+           }
 
-       CHECK_ALLOCATION(string[0], allocated[0], number[0]);
-       if (number[0] > 0)
-         {
-           int i;
+         GET_CHARACTER;
+         syntax = character;
+         GET_CHARACTER;
+         GET_NUMBER (number[0]);
+         VALIDATE ('\n');
 
-           for (i = 0; i < number[0]; ++i)
-             {
-               int ch = decode_char (file);
+         CHECK_ALLOCATION(string[0], allocated[0], number[0]);
+         if (number[0] > 0)
+           {
+             int i;
 
-               if (ch < 0)
-                 M4ERROR ((EXIT_FAILURE, 0,
-                           _("Premature end of frozen file")));
+             for (i = 0; i < number[0]; ++i)
+               {
+                 int ch = decode_char (file);
+
+                 if (ch < 0)
+                   M4ERROR ((EXIT_FAILURE, 0,
+                             _("Premature end of frozen file")));
 
-               string[0][i] = (unsigned char) ch;
-             }
-         }
-       string[0][number[0]] = '\0';
+                 string[0][i] = (unsigned char) ch;
+               }
+           }
+         string[0][number[0]] = '\0';
 
-       if ((m4_set_syntax (context->syntax, syntax, string[0]) < 0)
-           && (syntax != '\0'))
-         {
-           M4ERROR ((m4_get_warning_status_opt (context), 0,
-                     _("Undefined syntax code %c"), syntax));
-         }
-       break;
+         if ((m4_set_syntax (context->syntax, syntax, string[0]) < 0)
+             && (syntax != '\0'))
+           {
+             M4ERROR ((m4_get_warning_status_opt (context), 0,
+                       _("Undefined syntax code %c"), syntax));
+           }
+         break;
 
-      case 'C':
-      case 'D':
-      case 'Q':
-       operation = character;
-       GET_CHARACTER;
+       case 'C':
+       case 'D':
+       case 'Q':
+         operation = character;
+         GET_CHARACTER;
 
-       /* Get string lengths. */
+         /* Get string lengths. */
 
-       if (operation == 'D' && character == '-')
-         {
-           /* Accept a negative diversion number.  */
-           GET_CHARACTER;
+         if (operation == 'D' && character == '-')
+           {
+             /* Accept a negative diversion number.  */
+             GET_CHARACTER;
+             GET_NUMBER (number[0]);
+             number[0] = -number[0];
+           }
+         else
            GET_NUMBER (number[0]);
-           number[0] = -number[0];
-         }
-       else
-         GET_NUMBER (number[0]);
-       VALIDATE (',');
-       GET_CHARACTER;
-       GET_NUMBER (number[1]);
-       VALIDATE ('\n');
+         VALIDATE (',');
+         GET_CHARACTER;
+         GET_NUMBER (number[1]);
+         VALIDATE ('\n');
 
-       /* Get string contents.  */
-       if (operation != 'D')
-         GET_STRING (file, string[0], allocated[0], number[0]);
-       GET_STRING (file, string[1], allocated[1], number[1]);
-       GET_CHARACTER;
-       VALIDATE ('\n');
+         /* Get string contents.  */
+         if (operation != 'D')
+           GET_STRING (file, string[0], allocated[0], number[0]);
+         GET_STRING (file, string[1], allocated[1], number[1]);
+         GET_CHARACTER;
+         VALIDATE ('\n');
 
-       /* Act according to operation letter.  */
+         /* Act according to operation letter.  */
 
-       switch (operation)
-         {
-         case 'C':
+         switch (operation)
+           {
+           case 'C':
 
-           /* Change comment strings.  */
+             /* Change comment strings.  */
 
-           m4_set_comment (M4SYNTAX, string[0], string[1]);
-           break;
+             m4_set_comment (M4SYNTAX, string[0], string[1]);
+             break;
 
-         case 'D':
+           case 'D':
 
-           /* Select a diversion and add a string to it.  */
+             /* Select a diversion and add a string to it.  */
 
-           m4_make_diversion (number[0]);
-           if (number[1] > 0)
-             m4_shipout_text (context, NULL, string[1], number[1]);
-           break;
+             m4_make_diversion (number[0]);
+             if (number[1] > 0)
+               m4_shipout_text (context, NULL, string[1], number[1]);
+             break;
 
-         case 'Q':
+           case 'Q':
 
-           /* Change quote strings.  */
+             /* Change quote strings.  */
 
-           m4_set_quotes (M4SYNTAX, string[0], string[1]);
-           break;
+             m4_set_quotes (M4SYNTAX, string[0], string[1]);
+             break;
 
-         default:
+           default:
 
-           /* Cannot happen.  */
+             /* Cannot happen.  */
 
-           break;
-         }
-       break;
+             break;
+           }
+         break;
 
-      case 'T':
-       GET_CHARACTER;
+       case 'T':
+         GET_CHARACTER;
 
-       /* Get string lengths. */
+         /* Get string lengths. */
 
-       GET_NUMBER (number[0]);
-       VALIDATE (',');
-       GET_CHARACTER;
-       GET_NUMBER (number[1]);
+         GET_NUMBER (number[0]);
+         VALIDATE (',');
+         GET_CHARACTER;
+         GET_NUMBER (number[1]);
 
-       if ((character == ',') && (version > 1))
-         {
-           /* 'T' operator accepts an optional third argument for
-              format versions 2 or later.  */
-           GET_CHARACTER;
-           GET_NUMBER (number[2]);
-         }
-       else if (version > 1)
-         {
+         if (character == ',')
+           {
+             if (version > 1)
+               {
+                 /* 'T' operator accepts an optional third argument for
+                    format versions 2 or later.  */
+                 GET_CHARACTER;
+                 GET_NUMBER (number[2]);
+               }
+             else
+               {
+                 /* 3 argument 'T' operations are invalid for format
+                    version 1.  */
+                 M4ERROR ((EXIT_FAILURE, 0, _("\
+ill-formed frozen file, version 2 directive encountered")));
+               }
+           }
+         else
            number[2] = 0;
-         }
-       else
-         {
-           /* 3 argument 'T' operations are invalid for format version 1.  */
-           M4ERROR ((EXIT_FAILURE, 0, _("Ill-formed frozen file")));
-         }
 
-       VALIDATE ('\n');
+         VALIDATE ('\n');
 
-       /* Get string contents.  */
-       GET_STRING (file, string[0], allocated[0], number[0]);
-       GET_STRING (file, string[1], allocated[1], number[1]);
-       if ((number[2] > 0)  && (version > 1))
+         /* Get string contents.  */
+         GET_STRING (file, string[0], allocated[0], number[0]);
+         GET_STRING (file, string[1], allocated[1], number[1]);
          GET_STRING (file, string[2], allocated[2], number[2]);
-       VALIDATE ('\n');
-
-       /* Enter a macro having an expansion text as a definition.  */
-       {
-         m4_symbol_value *token = xzalloc (sizeof *token);
-         lt_dlhandle handle = 0;
-
-         if (number[2] > 0)
-           handle = m4__module_find (string[2]);
+         VALIDATE ('\n');
 
-         m4_set_symbol_value_text (token, xstrdup (string[1]));
-         VALUE_HANDLE (token)          = handle;
-         VALUE_MAX_ARGS (token)        = -1;
-
-         m4_symbol_pushdef (M4SYMTAB, string[0], token);
-       }
-       break;
+         /* Enter a macro having an expansion text as a definition.  */
+         {
+           m4_symbol_value *token = xzalloc (sizeof *token);
+           lt_dlhandle handle = 0;
 
-      case 'V':
+           if (number[2] > 0)
+             handle = m4__module_find (string[2]);
 
-       /* Validate and save format version.  Only `1' and `2'
-          are acceptable for now.  */
+           m4_set_symbol_value_text (token, xstrdup (string[1]));
+           VALUE_HANDLE (token)                = handle;
+           VALUE_MAX_ARGS (token)      = -1;
 
-       GET_CHARACTER;
-       version = character - '0';
-       if ((version < 1) || (version > 2))
-           issue_expect_message ('2');
-       GET_CHARACTER;
-       VALIDATE ('\n');
-       break;
+           m4_symbol_pushdef (M4SYMTAB, string[0], token);
+         }
+         break;
 
-      }
+       }
+      GET_DIRECTIVE;
+    }
 
   free (string[0]);
   free (string[1]);
@@ -749,4 +786,5 @@ reload_frozen_state (m4 *context, const 
 #undef GET_NUMBER
 #undef VALIDATE
 #undef CHECK_ALLOCATION
+#undef GET_DIRECTIVE
 }
Index: src/main.c
===================================================================
RCS file: /sources/m4/m4/src/main.c,v
retrieving revision 1.69
diff -u -p -r1.69 main.c
--- src/main.c  22 Jul 2006 22:38:14 -0000      1.69
+++ src/main.c  27 Jul 2006 13:24:15 -0000
@@ -108,7 +108,7 @@ Operation modes:\n\
   -e, --interactive            unbuffer output, ignore interrupts\n\
   -P, --prefix-builtins        force a `m4_' prefix to all builtins\n\
   -Q, --quiet, --silent        suppress some warnings for builtins\n\
-  -r, --regexp-syntax=[SPEC]   change the default regexp syntax\n"),
+  -r, --regexp-syntax=SPEC     change the default regexp syntax\n"),
             stdout);
       fputs (_("\
 \n\
@@ -145,7 +145,7 @@ Frozen state files:\n\
       fputs (_("\
 \n\
 Debugging:\n\
-  -d, --debug=[FLAGS]          set debug level (no FLAGS implies `aeq')\n\
+  -d, --debug[=FLAGS]          set debug level (no FLAGS implies `aeq')\n\
   -l, --arglength=NUM          restrict macro tracing size\n\
   -o, --error-output=FILE      redirect debug and trace output\n\
   -t, --trace=NAME             trace NAME when it will be defined\n"),
@@ -169,6 +169,11 @@ FLAGS is any of:\n\
 \n\
 If no FILE or if FILE is `-', standard input is read.\n"),
             stdout);
+      fputs (_("\
+\n\
+Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
+mismatch, or whatever value was passed to the m4exit macro.\n\
+"), stdout);
 
       fputs (_("\nReport bugs to <address@hidden>.\n"), stdout);
     }
@@ -400,15 +405,7 @@ main (int argc, char *const *argv, char 
   m4_include_env_init (context);
 
   if (frozen_file_to_read)
-    {
-      int ch;
-
-      /* Take care not to mix frozen state with startup state.  */
-      for (ch = 256; --ch > 0;)
-       context->syntax->table[ch] = 0;
-
-      reload_frozen_state (context, frozen_file_to_read);
-    }
+    reload_frozen_state (context, frozen_file_to_read);
   else
     {
       m4_module_load (context, "m4", 0);

reply via email to

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