m4-discuss
[Top][All Lists]
Advanced

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

Re: M4 syntax $11 vs. ${11}


From: Eric Blake
Subject: Re: M4 syntax $11 vs. ${11}
Date: Tue, 23 Jan 2007 07:28:13 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.9) Gecko/20061207 Thunderbird/1.5.0.9 Mnenhy/0.7.4.666

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

According to Eric Blake on 1/18/2007 7:50 AM:
> 
> With 1.9b, I would like to implement the resolution of XCU ERN 111.  That
> is, I plan on adding support for ${11}, so that the GNU extension of more
> than 9 parameters is still alive (and in fact, I hope to borrow from shell
> syntax for other extensions such as ${1-default}).  I also plan on making
> $11 obey POSIX semantics if POSIXLY_CORRECT, else obey 1.4.x semantics but
> issue a warning that obsolete syntax was encountered.  Then, after a
> deprecation period, M4 2.1 could remove the POSIXLY_CORRECT check and
> always treat $11 the way POSIX requires.
> 

As a first step, we need syntax categories for { and }, similar to $.
I'm not sure whether $, {, and } should be category masks (for example,
allowing $ to be in both the 'A' and '$' categories at once, to both
participate in macro names during parsing as well trigger parameter
substitution during expansion), but for now I kept the status quo and
the new categories are mutually exclusive with other categories.

Followup patches that still need to be written include: allowing
- --changesyntax from the 1.9a command line, adding --warn-syntax to 1.4.9
and 1.9a, actually coding up ${11} parsing, proposing a patch to
autoconf to call changesyntax(O+{}) alongside changequote([,]).

2007-01-23  Eric Blake  <address@hidden>

        * m4/m4module.h (M4_SYNTAX_ASSIGN): Delete this unused
        extension to make enough room.
        (M4_SYNTAX_IGNORE): Change value to zero, since the (commented)
        code in input.c special cases this category.
        (M4_SYNTAX_LBRACE, M4_SYNTAX_RBRACE): New values in preparation
        for define(eleventh,${11}) extension.
        * m4/syntax.c: Update comments accordingly.
        (m4_syntax_create, m4_syntax_code): Handle { and }.
        * m4/input.c (m4__next_token): Likewise.
        * src/freeze.c (produce_frozen_state): Support new categories.
        (reload_frozen_state): When loading version 1, disable syntax
        features not present in 1.4.x.
        * tests/freeze.at: Sort and rename existing tests.
        (loading format 1): Ensure we don't break v1 frozen files that
        used raw ${.
        (loading format 2, reloading changecom, reloading changesyntax):
        New tests.
        * doc/m4.texinfo (Changesyntax, Frozen file format 1): Document
        the new syntax categories.
        (Arguments): Update the FIXME comment.
        (M4wrap): Merge examples from branch, before worrying about fixing
        m4wrap to obey POSIX.
        (Using frozen files): Start merging from branch.
        * NEWS: Update.

- --
Don't work too hard, make some time for fun as well!

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

iD8DBQFFtht884KuGfSFAYARAmy7AKDJ4ET0q8mJ8GHH9BJI1+5I0oimNACgtRZF
cC750gJ/9NwMzdZYsIE/+0w=
=jNzN
-----END PGP SIGNATURE-----
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.37
diff -u -p -r1.37 NEWS
--- NEWS        21 Jan 2007 04:09:06 -0000      1.37
+++ NEWS        23 Jan 2007 14:26:22 -0000
@@ -155,7 +155,9 @@ promoted to 2.0.
 
 *** The `changesyntax' builtin has been improved, to make it easier to add
     and remove characters from a syntax class without having to specify the
-    entire set of characters in that class.
+    entire set of characters in that class.  It also supports two new
+    syntax categories, `{' and `}', for extended argument handling in macro
+    definitions.
 
 *** New `m' flag to `-d'/`--debug' command-line option or `debugmode'
     builtin traces actions related to module loading and unloading, and
@@ -192,7 +194,7 @@ promoted to 2.0.
 ** Other changes
 
 *** The syntax of frozen files format V2 has been improved to save
-    additional state.  This includes the 'R' directive for default regular
+    additional state.  This includes the `R' directive for default regular
     expression syntax.  Also, a V2 file can now be represented completely
     in ASCII, thanks to escape sequences.  Unfortunately, files frozen by
     M4 1.4q that contain \ in macros cannot be read by 1.9b, but since 1.4q
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.93
diff -u -p -r1.93 m4.texinfo
--- doc/m4.texinfo      15 Jan 2007 14:04:26 -0000      1.93
+++ doc/m4.texinfo      23 Jan 2007 14:26:24 -0000
@@ -1706,12 +1706,13 @@ consist of one
 or more digits, allowing macros to have any number of arguments.  This
 is not so in UNIX implementations of @code{m4}, which only recognize
 one digit.
address@hidden FIXME - See Austin group XCU ERN 111.  This is controversial,
address@hidden and POSIX is moving to reserve ${ for implementation use.  We
address@hidden should phase out $10 and replace it with ${10}, and consider
address@hidden other extensions like ${1-default}.  There are existing m4
address@hidden scripts that depend on $10 being the first parameter
address@hidden concatenated with 0, not the tenth argument.
address@hidden FIXME - See Austin group XCU ERN 111.  POSIX says that $11 must
address@hidden be the first argument concatenated with 1, and instead reserves
address@hidden ${11} for implementation use.  Once this is implemented, the
address@hidden documentation needs to reflect how these extended arguments
address@hidden are handled, as well as backwards compatibility issues with
address@hidden 1.4.x.  Also, consider adding further extensions such as
address@hidden ${1-default}, which expands to `default' if $1 is empty.
 
 As a special case, the zeroth argument, @code{$0}, is always the name
 of the macro being expanded.
@@ -4154,6 +4155,15 @@ the single character @samp{,}.
 Characters that can introduce an argument reference in the body of a
 macro.  The default is the single character @samp{$}.
 
address@hidden Left brace
+Characters that introduce an extended argument reference in the body of
+a macro immediately after a character in the Dollar category.  The
+default is the single character @address@hidden
+
address@hidden Right brace
+Characters that conclude an extended argument reference in the body of a
+macro.  The default is the single character @address@hidden
+
 @item Left quote
 The set of characters that can start a single-character quoted string.
 The default is the single character @samp{`}.  For multiple-character
@@ -4523,11 +4533,54 @@ This is the first and last normal input 
 The saved input is only reread when the end of normal input is seen, and
 not if @code{m4exit} is used to exit @code{m4}.
 
address@hidden FIXME: this contradicts POSIX, which requires that "If the
address@hidden m4wrap macro is used multiple times, the arguments specified
address@hidden shall be processed in the order in which the m4wrap macros were
address@hidden processed."
 It is safe to call @code{m4wrap} from saved text, but then the order in
 which the saved text is reread is undefined.  If @code{m4wrap} is not used
 recursively, the saved pieces of text are reread in the opposite order
 in which they were saved (LIFO---last in, first out).
 
+Here is an example of implementing a factorial function using
address@hidden:
+
address@hidden
+define(`f', `ifelse(`$1', `0', `Answer: 0!=1
+', eval(`$1>1'), `0', `Answer: $2$1=eval(`$2$1')
+', `m4wrap(`f(decr(`$1'), `$2$1*')')')')
address@hidden
+f(`10')
address@hidden
+^D
address@hidden: 10*9*8*7*6*5*4*3*2*1=3628800
address@hidden example
+
+Invocations of @code{m4wrap} at the same recursion level are
+concatenated and rescanned as usual:
+
address@hidden
+define(`aa', `AA
+')
address@hidden
+m4wrap(`a')m4wrap(`a')
address@hidden
+^D
address@hidden
address@hidden example
+
address@hidden
+however, the transition between recursion levels behaves like an end of
+file condition between two input files.
+
address@hidden status: 1
address@hidden
+m4wrap(`m4wrap(`)')len(abc')
address@hidden
+^D
address@hidden:stdin:1: end of file in argument list
address@hidden example
+
 @node File Inclusion
 @chapter File inclusion
 
@@ -6739,7 +6792,11 @@ Some bigger @code{m4} applications may b
 containing hundreds of definitions and other costly initializations.
 Usually, the common base is kept in one or more declarative files,
 which files are listed on each @code{m4} invocation prior to the
-user's input file, or else, @code{include}'d from this input file.
+user's input file, or else each input file uses @code{include}.
+
+Reading the common base of a big application, over and over again, may
+be time consuming.  @acronym{GNU} @code{m4} offers some machinery to
+speed up the start of an application using lengthy common bases.
 
 @menu
 * Using frozen files::          Using frozen files
@@ -6756,23 +6813,22 @@ user's input file, or else, @code{includ
 @cindex dumping into frozen file
 @cindex reloading a frozen file
 @cindex @acronym{GNU} extensions
-Reading the common base of a big application, over and over again, may
-be time consuming.  GNU @code{m4} offers some machinery to speed up
-the start of an application using lengthy common bases.  Presume the
-user repeatedly uses:
+Suppose a user has a library of @code{m4} initializations in
address@hidden, which is then used with multiple input files:
 
 @comment ignore
 @example
-m4 base.m4 input.m4
+$ @kbd{m4 base.m4 input1.m4}
+$ @kbd{m4 base.m4 input2.m4}
+$ @kbd{m4 base.m4 input3.m4}
 @end example
 
address@hidden
-with a varying contents of @file{input.m4}, but a rather fixed contents
-for @file{base.m4}.  Then, the user might rather execute:
+Rather than spending time parsing the fixed contents of @file{base.m4}
+every time, the user might rather execute:
 
 @comment ignore
 @example
-m4 -F base.m4f base.m4
+$ @kbd{m4 -F base.m4f base.m4}
 @end example
 
 @noindent
@@ -6780,20 +6836,22 @@ once, and further execute, as often as n
 
 @comment ignore
 @example
-m4 -R base.m4f input.m4
+$ @kbd{m4 -R base.m4f input1.m4}
+$ @kbd{m4 -R base.m4f input2.m4}
+$ @kbd{m4 -R base.m4f input3.m4}
 @end example
 
 @noindent
 with the varying input.  The first call, containing the @code{-F}
-option, only reads and executes file @file{base.m4}, so defining
-various application macros and computing other initializations.  Only
-once the input file @file{base.m4} has been completely processed, GNU
address@hidden produces on @file{base.m4f} a @dfn{frozen} file, that is, a
+option, only reads and executes file @file{base.m4}, defining
+various application macros and computing other initializations.
+Once the input file @file{base.m4} has been completely processed, @acronym{GNU}
address@hidden produces in @file{base.m4f} a @dfn{frozen} file, that is, a
 file which contains a kind of snapshot of the @code{m4} internal state.
 
 Later calls, containing the @code{-R} option, are able to reload
-the internal state of @code{m4}'s memory, from @file{base.m4f},
address@hidden to reading any other input files.  By this mean,
+the internal state of @code{m4}, from @file{base.m4f},
address@hidden to reading any other input files.  This means
 instead of starting with a virgin copy of @code{m4}, input will be
 read after having effectively recovered the effect of a prior run.
 In our example, the effect is the same as if file @file{base.m4} has
@@ -6807,7 +6865,7 @@ some care is taken, the command:
 
 @comment ignore
 @example
-m4 file1.m4 file2.m4 file3.m4 file4.m4
+$ @kbd{m4 file1.m4 file2.m4 file3.m4 file4.m4}
 @end example
 
 @noindent
@@ -6816,20 +6874,13 @@ output:
 
 @comment ignore
 @example
-m4 -F file1.m4f file1.m4
-m4 -R file1.m4f -F file2.m4f file2.m4
-m4 -R file2.m4f -F file3.m4f file3.m4
-m4 -R file3.m4f file4.m4
address@hidden example
-
-This could also be done in a simple way, if everything has been prepared
-before:
-
address@hidden ignore
address@hidden
-m4 -F file1.m4f file1.m4 file2.m4 file3.m4 file4.m4
+$ @kbd{m4 -F file1.m4f file1.m4}
+$ @kbd{m4 -R file1.m4f -F file2.m4f file2.m4}
+$ @kbd{m4 -R file2.m4f -F file3.m4f file3.m4}
+$ @kbd{m4 -R file3.m4f file4.m4}
 @end example
 
address@hidden FIXME - merge the rest of this section.
 Some care is necessary because not every effort has been made for
 this to work in all cases.  In particular, the trace attribute of
 macros is not handled.
@@ -6855,6 +6906,13 @@ Wow - thanks for really reading the manu
 this text is not removed before a release.
 FIXME - split out the two formats into separate nodes.
 
+When loading format 1, the syntax categories @address@hidden and 
@address@hidden are
+disabled (reverting braces to be treated like plain characters).  This
+is because frozen files created with M4 1.4.x did not understand
address@hidden@address@hidden@}} extended argument notation, and a frozen macro 
that
+contained this character sequence should not behave differently just
+because a newer version of M4 reloaded the file.
+
 @node Frozen file format 2
 @section Frozen file format 2
 
Index: m4/input.c
===================================================================
RCS file: /sources/m4/m4/m4/input.c,v
retrieving revision 1.59
diff -u -p -r1.59 input.c
--- m4/input.c  23 Dec 2006 00:02:20 -0000      1.59
+++ m4/input.c  23 Jan 2007 14:26:24 -0000
@@ -1,5 +1,5 @@
 /* GNU m4 -- A simple macro processor
-   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006 Free Software
+   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006, 2007 Free Software
    Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -1170,11 +1170,13 @@ m4__next_token (m4 *context, m4_symbol_v
        obstack_1grow (&token_stack, ch);
 
        if (m4_has_syntax (M4SYNTAX, ch,
-                          M4_SYNTAX_OTHER | M4_SYNTAX_NUM | M4_SYNTAX_DOLLAR))
+                          (M4_SYNTAX_OTHER | M4_SYNTAX_NUM | M4_SYNTAX_DOLLAR
+                            | M4_SYNTAX_LBRACE | M4_SYNTAX_RBRACE)))
          {
            consume_syntax (context, &token_stack,
                            (M4_SYNTAX_OTHER | M4_SYNTAX_NUM
-                            | M4_SYNTAX_DOLLAR));
+                             | M4_SYNTAX_DOLLAR | M4_SYNTAX_LBRACE
+                             | M4_SYNTAX_RBRACE));
            type = M4_TOKEN_STRING;
          }
        else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_SPACE))
@@ -1192,7 +1194,8 @@ m4__next_token (m4 *context, m4_symbol_v
        obstack_1grow (&token_stack, ch);
 
        if (m4_has_syntax (M4SYNTAX, ch,
-                          M4_SYNTAX_OTHER | M4_SYNTAX_NUM | M4_SYNTAX_DOLLAR))
+                          (M4_SYNTAX_OTHER | M4_SYNTAX_NUM | M4_SYNTAX_DOLLAR
+                            | M4_SYNTAX_LBRACE | M4_SYNTAX_RBRACE)))
          type = M4_TOKEN_STRING;
        else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_SPACE))
          type = M4_TOKEN_SPACE;
Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.104
diff -u -p -r1.104 m4module.h
--- m4/m4module.h       13 Jan 2007 13:55:37 -0000      1.104
+++ m4/m4module.h       23 Jan 2007 14:26:24 -0000
@@ -355,30 +355,32 @@ extern    bool             m4_is_syntax_single_quotes
 extern bool             m4_is_syntax_single_comments   (m4_syntax_table *);
 extern bool             m4_is_syntax_macro_escaped     (m4_syntax_table *);
 
-/* These are values to be assigned to syntax table entries, although they
-   are bit masks for fast categorisation in m4__next_token(), only one
-   value per syntax table entry is allowed.  */
+/* These are values to be assigned to syntax table entries.  Although
+   they are bit masks for fast categorization in m4__next_token(),
+   only one value per syntax table entry is allowed.  The enumeration
+   is currently sorted in order of parsing precedence.  */
 enum {
-  M4_SYNTAX_OTHER              = (1 << 0),
-  M4_SYNTAX_IGNORE             = (1 << 1),
-  M4_SYNTAX_SPACE              = (1 << 2),
-  M4_SYNTAX_OPEN               = (1 << 3),
-  M4_SYNTAX_CLOSE              = (1 << 4),
-  M4_SYNTAX_COMMA              = (1 << 5),
-  M4_SYNTAX_DOLLAR             = (1 << 6),
-  M4_SYNTAX_ACTIVE             = (1 << 7),
-  M4_SYNTAX_ESCAPE             = (1 << 8),
-  M4_SYNTAX_ASSIGN             = (1 << 9),
-  M4_SYNTAX_ALPHA              = (1 << 10),
-  M4_SYNTAX_NUM                        = (1 << 11),
-  M4_SYNTAX_LQUOTE             = (1 << 12),
-  M4_SYNTAX_BCOMM              = (1 << 13),
+  M4_SYNTAX_IGNORE             = 0,
+  M4_SYNTAX_ESCAPE             = 1 << 0,
+  M4_SYNTAX_ALPHA              = 1 << 1,
+  M4_SYNTAX_LQUOTE             = 1 << 2,
+  M4_SYNTAX_BCOMM              = 1 << 3,
+  M4_SYNTAX_OTHER              = 1 << 4,
+  M4_SYNTAX_NUM                        = 1 << 5,
+  M4_SYNTAX_DOLLAR             = 1 << 6,
+  M4_SYNTAX_LBRACE             = 1 << 7,
+  M4_SYNTAX_RBRACE             = 1 << 8,
+  M4_SYNTAX_SPACE              = 1 << 9,
+  M4_SYNTAX_ACTIVE             = 1 << 10,
+  M4_SYNTAX_OPEN               = 1 << 11,
+  M4_SYNTAX_CLOSE              = 1 << 12,
+  M4_SYNTAX_COMMA              = 1 << 13,
 
   /* These values are bit masks to OR with categories above, a syntax entry
      may have any number of these in addition to a maximum of one of the
      values above.  */
-  M4_SYNTAX_RQUOTE             = (1 << 14),
-  M4_SYNTAX_ECOMM              = (1 << 15),
+  M4_SYNTAX_RQUOTE             = 1 << 14,
+  M4_SYNTAX_ECOMM              = 1 << 15
 };
 
 #define M4_SYNTAX_MASKS                (M4_SYNTAX_RQUOTE | M4_SYNTAX_ECOMM)
Index: m4/syntax.c
===================================================================
RCS file: /sources/m4/m4/m4/syntax.c,v
retrieving revision 1.20
diff -u -p -r1.20 syntax.c
--- m4/syntax.c 12 Jan 2007 23:07:27 -0000      1.20
+++ m4/syntax.c 23 Jan 2007 14:26:24 -0000
@@ -36,9 +36,10 @@
    M4_SYNTAX_CLOSE     Close list of macro arguments
    M4_SYNTAX_COMMA     Separates macro arguments
    M4_SYNTAX_DOLLAR    Indicates macro argument in user macros
+   M4_SYNTAX_LBRACE    Indicates start of extended macro argument
+   M4_SYNTAX_RBRACE    Indicates end of extended macro argument
    M4_SYNTAX_ACTIVE    This character is a macro name by itself
    M4_SYNTAX_ESCAPE    Use this character to prefix all macro names
-   M4_SYNTAX_ASSIGN    *Used to assign defaults in parameter lists
 
    M4_SYNTAX_ALPHA     Alphabetic characters (can start macro names)
    M4_SYNTAX_NUM       Numeric characters (can form macro names)
@@ -75,22 +76,29 @@
    The precedence as implemented by next_token () is:
 
    M4_SYNTAX_IGNORE    *Filtered out below next_token ()
-   M4_SYNTAX_ESCAPE    Reads macro name iff set, else next
-   M4_SYNTAX_ALPHA     Reads macro name
+   M4_SYNTAX_ESCAPE    Reads macro name iff set, else next character
+   M4_SYNTAX_ALPHA     Reads M4_SYNTAX_ALPHA and M4_SYNTAX_NUM as macro name
    M4_SYNTAX_LQUOTE    Reads all until balanced M4_SYNTAX_RQUOTE
    M4_SYNTAX_BCOMM     Reads all until M4_SYNTAX_ECOMM
 
    M4_SYNTAX_OTHER  }  Reads all M4_SYNTAX_OTHER, M4_SYNTAX_NUM
-   M4_SYNTAX_NUM    }  and M4_SYNTAX_DOLLAR
+   M4_SYNTAX_NUM    }  M4_SYNTAX_DOLLAR, M4_SYNTAX_LBRACE, M4_SYNTAX_RBRACE
    M4_SYNTAX_DOLLAR }
+   M4_SYNTAX_LBRACE }
+   M4_SYNTAX_RBRACE }
 
-   M4_SYNTAX_SPACE     Reads all M4_SYNTAX_SPACE
-   M4_SYNTAX_ACTIVE    Returns a single char as a word
-   the rest            Returned as a single char
-
-   The $ is not really a part of m4's input syntax in the sense that a
-   string is parsed equally whether there is a $ or not.  The character
-   $ is used by convention in user macros.  */
+   M4_SYNTAX_SPACE     Reads all M4_SYNTAX_SPACE, depending on buffering
+   M4_SYNTAX_ACTIVE    Returns a single char as a macro name
+
+   M4_SYNTAX_OPEN   }  Returned as a single char
+   M4_SYNTAX_CLOSE  }
+   M4_SYNTAX_COMMA  }
+
+   The $, {, and } are not really a part of m4's input syntax, because a
+   a string is parsed equally whether there is a $ or not.  These characters
+   are instead used during user macro expansion.
+
+   M4_SYNTAX_RQUOTE and M4_SYNTAX_ECOMM do not start tokens.  */
 
 static bool    check_is_single_quotes          (m4_syntax_table *);
 static bool    check_is_single_comments        (m4_syntax_table *);
@@ -120,16 +128,18 @@ m4_syntax_create (void)
       case '$':
        syntax->orig[ch] = M4_SYNTAX_DOLLAR;
        break;
+      case '{':
+       syntax->orig[ch] = M4_SYNTAX_LBRACE;
+       break;
+      case '}':
+       syntax->orig[ch] = M4_SYNTAX_RBRACE;
+       break;
       case '`':
        syntax->orig[ch] = M4_SYNTAX_LQUOTE;
        break;
       case '#':
        syntax->orig[ch] = M4_SYNTAX_BCOMM;
        break;
-      case '=':
-       /* FIXME -revisit the assign syntax attribute.  */
-       /* syntax->orig[ch] = M4_SYNTAX_ASSIGN; */
-       /* break; */
       case '\0':
        /* FIXME - revisit the ignore syntax attribute.  */
        /* syntax->orig[ch] = M4_SYNTAX_IGNORE; */
@@ -169,26 +179,26 @@ m4_syntax_code (char ch)
 
   switch (ch)
     {
-    /* FIXME - revisit the ignore syntax attribute.  */
-    case 'I': case 'i': code = M4_SYNTAX_IGNORE; break;
-    case 'O': case 'o': code = M4_SYNTAX_OTHER;  break;
-    case 'S': case 's': code = M4_SYNTAX_SPACE;  break;
-    case 'W': case 'w': code = M4_SYNTAX_ALPHA;  break;
-    case 'D': case 'd': code = M4_SYNTAX_NUM;    break;
-
-    case '(': code = M4_SYNTAX_OPEN;   break;
-    case ')': code = M4_SYNTAX_CLOSE;  break;
-    case ',': code = M4_SYNTAX_COMMA;  break;
-    /* FIXME - revisit the assign syntax attribute.  */
-    case '=': code = M4_SYNTAX_ASSIGN; break;
-    case '@': code = M4_SYNTAX_ESCAPE; break;
-    case '$': code = M4_SYNTAX_DOLLAR; break;
-
-    case 'L': case 'l': code = M4_SYNTAX_LQUOTE; break;
-    case 'R': case 'r': code = M4_SYNTAX_RQUOTE; break;
-    case 'B': case 'b': code = M4_SYNTAX_BCOMM;  break;
-    case 'E': case 'e': code = M4_SYNTAX_ECOMM;  break;
-    case 'A': case 'a': code = M4_SYNTAX_ACTIVE;  break;
+       /* Sorted according to the order of M4_SYNTAX_* in m4module.h.  */
+       /* FIXME - revisit the ignore syntax attribute.  */
+    case 'I': case 'i':        code = M4_SYNTAX_IGNORE; break;
+    case '@':          code = M4_SYNTAX_ESCAPE; break;
+    case 'W': case 'w':        code = M4_SYNTAX_ALPHA;  break;
+    case 'L': case 'l':        code = M4_SYNTAX_LQUOTE; break;
+    case 'B': case 'b':        code = M4_SYNTAX_BCOMM;  break;
+    case 'O': case 'o':        code = M4_SYNTAX_OTHER;  break;
+    case 'D': case 'd':        code = M4_SYNTAX_NUM;    break;
+    case '$':          code = M4_SYNTAX_DOLLAR; break;
+    case '{':          code = M4_SYNTAX_LBRACE; break;
+    case '}':          code = M4_SYNTAX_RBRACE; break;
+    case 'S': case 's':        code = M4_SYNTAX_SPACE;  break;
+    case 'A': case 'a':        code = M4_SYNTAX_ACTIVE; break;
+    case '(':          code = M4_SYNTAX_OPEN;   break;
+    case ')':          code = M4_SYNTAX_CLOSE;  break;
+    case ',':          code = M4_SYNTAX_COMMA;  break;
+
+    case 'R': case 'r':        code = M4_SYNTAX_RQUOTE; break;
+    case 'E': case 'e':        code = M4_SYNTAX_ECOMM;  break;
 
     default: code = -1;  break;
     }
Index: src/freeze.c
===================================================================
RCS file: /sources/m4/m4/src/freeze.c,v
retrieving revision 1.59
diff -u -p -r1.59 freeze.c
--- src/freeze.c        21 Jan 2007 04:09:06 -0000      1.59
+++ src/freeze.c        23 Jan 2007 14:26:24 -0000
@@ -267,9 +267,9 @@ produce_frozen_state (m4 *context, const
 
   produce_resyntax_dump (context, file);
 
-  /* Dump syntax table. */
+  /* Dump syntax table.  */
 
-  str = "IS(),address@hidden";
+  str = "address@hidden(),RE";
   while (*str)
     produce_syntax_dump (file, M4SYNTAX, *str++);
 
@@ -492,6 +492,9 @@ reload_frozen_state (m4 *context, const 
        m4__module_open (context, "traditional", NULL);
       else
        m4__module_open (context, "gnu", NULL);
+      /* Disable { and } categories, since ${11} was not supported in
+         1.4.x.  */
+      m4_set_syntax (context->syntax, 'O', '+', "{}");
       break;
     default:
       if (version > 2)
Index: tests/freeze.at
===================================================================
RCS file: /sources/m4/m4/tests/freeze.at,v
retrieving revision 1.8
diff -u -p -r1.8 freeze.at
--- tests/freeze.at     31 Aug 2006 03:21:35 -0000      1.8
+++ tests/freeze.at     23 Jan 2007 14:26:24 -0000
@@ -1,5 +1,5 @@
 # Hand crafted tests for GNU M4.                               -*- Autotest -*-
-# Copyright (C) 2006 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2007 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
@@ -39,7 +39,7 @@ GNU M4 1.4.5
 $ cat frozen.m4
 divert(`-1')
 define(`foo', `\FOO')
-pushdef(`foo', `bar')
+pushdef(`foo', `bar${1}')
 define(`my_define', defn(`define'))
 define(`my_changeword', defn(`changeword'))
 pushdef(`my_define', `define')
@@ -72,12 +72,12 @@ F9,6
 my_definedefine
 T3,4
 foo\FOO
-T3,3
-foobar
+T3,7
+foobar${1}
 F3,3
 dnldnl
-D1,4
-bar
+D1,8
+bar${1}
 
 D0,0
 
@@ -85,7 +85,7 @@ D0,0
 ]])
 
 AT_DATA([input.m4],
-[[foo /* foo */ popdef([foo])foo
+[[foo([2]) /* foo */ popdef([foo])foo
 my_define([bar], [1])[]popdef([my_define]) bar
 my_define([bar], [2])[]popdef([my_define]) bar
 my_define([bar], [3])[]popdef([my_define]) bar
@@ -93,12 +93,12 @@ my_define([bar], [4])[]popdef([my_define
 ]])
 
 AT_CHECK_M4([-R frozen.m4f input.m4], [0],
-[[bar /* foo */ \FOO
+[[bar${1} /* foo */ \FOO
  1
 define 1
  3
 my_define(bar, 4) 3
-bar
+bar${1}
 ]],
 [[m4:input.m4:5: Warning: popdef: undefined macro `my_define'
 ]])
@@ -106,9 +106,162 @@ bar
 AT_CLEANUP
 
 
-## -------------------------- ##
-## Reloading unknown builtins ##
-## -------------------------- ##
+## ---------------- ##
+## loading format 2 ##
+## ---------------- ##
+
+AT_SETUP([loading format 2])
+AT_KEYWORDS([frozen])
+
+AT_DATA([frozen.m4f],
+[[# Handcrafted file, obeying the version 2 spec
+V2
+# missing close quote should be supplied
+Q1,0
+>
+# missing close comment should be supplied
+C1,0
+<
+M2
+m4
+M3
+gnu
+F7,7,3
+builtinbuiltingnu
+# Testing escape sequences
+T4,5
+blah\t\477\040\X5C
+]])
+
+AT_DATA([input.m4],
+[[< comment: builtin()
+builtin(>define', foo, bar)
+foo
+blah
+]])
+
+AT_CHECK_M4([-R frozen.m4f input.m4], [0],
+[[< comment: builtin()
+
+bar
+       '7 \
+]])
+
+AT_CLEANUP
+
+
+## --------- ##
+## changecom ##
+## --------- ##
+
+AT_SETUP([reloading changecom])
+AT_KEYWORDS([frozen])
+
+# Check that changesyntax is maintained across freeze boundaries.
+
+AT_DATA([[frozen.m4]],
+[[changecom`'changequote(<,>)dnl
+]])
+
+AT_DATA([[unfrozen.m4]],
+[[define(<foo>, <bar>)
+foo # foo
+]])
+
+# First generate the `expout' output by running over the sources before
+# freezing.
+AT_CHECK_M4([frozen.m4 unfrozen.m4], [0],
+           [stdout], [stderr])
+
+mv stdout expout
+mv stderr experr
+
+# Now freeze the first source file.
+AT_CHECK_M4([-F frozen.m4f frozen.m4], [0])
+
+# Now rerun the original sequence, but using the frozen file.
+AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0],
+           [expout], [experr])
+
+AT_CLEANUP
+
+
+## ------------ ##
+## changesyntax ##
+## ------------ ##
+
+AT_SETUP([reloading changesyntax])
+AT_KEYWORDS([frozen])
+
+# Check that changesyntax is maintained across freeze boundaries.
+
+AT_DATA([[frozen.m4]],
+[[changesyntax(`W+.', `({', `)}')dnl
+define{`a.b', `hello $1'}dnl
+]])
+
+AT_DATA([[unfrozen.m4]],
+[[a.b{world}
+]])
+
+# First generate the `expout' output by running over the sources before
+# freezing.
+AT_CHECK_M4([frozen.m4 unfrozen.m4], [0],
+           [stdout], [stderr])
+
+mv stdout expout
+mv stderr experr
+
+# Now freeze the first source file.
+AT_CHECK_M4([-F frozen.m4f frozen.m4], [0])
+
+# Now rerun the original sequence, but using the frozen file.
+AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0],
+           [expout], [experr])
+
+AT_CLEANUP
+
+
+## ------------- ##
+## regexp syntax ##
+## ------------- ##
+
+AT_SETUP([reloading regexp syntax])
+AT_KEYWORDS([frozen])
+
+# Check that regular expression syntax is maintained across freeze boundaries.
+
+AT_DATA([[frozen.m4]],
+[[changeresyntax(`POSIX_EXTENDED')dnl
+]])
+
+AT_DATA([[unfrozen.m4]],
+[[regexp(`GNUs not Unix', `\w(\w*)$')
+regexp(`GNUs not Unix', `\w\(\w*\)$', `GNU_M4')
+]])
+
+# First generate the `expout' output by running over the sources before
+# freezing.
+AT_CHECK_M4([frozen.m4 unfrozen.m4], [0],
+           [stdout], [stderr])
+
+mv stdout expout
+mv stderr experr
+
+# Now freeze the first source file.
+AT_CHECK_M4([-F frozen.m4f frozen.m4], [0],
+           [ignore], [ignore])
+
+# Now rerun the original sequence, but using the frozen file.
+AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0],
+           [expout], [experr])
+
+AT_CLEANUP
+
+
+## ---------------- ##
+## unknown builtins ##
+## ---------------- ##
 
 AT_SETUP([reloading unknown builtin])
 AT_KEYWORDS([frozen])
@@ -158,39 +311,3 @@ c: `'
 ]])
 
 AT_CLEANUP
-
-## ---------------------- ##
-## Freezing regexp syntax ##
-## ---------------------- ##
-
-AT_SETUP([regexp syntax])
-AT_KEYWORDS([frozen])
-
-# Check that regular expression syntax is maintained across freeze baundaries.
-
-AT_DATA([[frozen.m4]],
-[[changeresyntax(`POSIX_EXTENDED')dnl
-]])
-
-AT_DATA([[unfrozen.m4]],
-[[regexp(`GNUs not Unix', `\w(\w*)$')
-regexp(`GNUs not Unix', `\w\(\w*\)$', `GNU_M4')
-]])
-
-# First generate the `expout' output by running over the sources before
-# freezing.
-AT_CHECK_M4([frozen.m4 unfrozen.m4], 0,
-           [stdout], [stderr])
-
-mv stdout expout
-mv stderr experr
-
-# Now freeze the first source file.
-AT_CHECK_M4([-F frozen.m4f frozen.m4], 0,
-           [ignore], [ignore])
-
-# Now rerun the original sequence, but using the frozen file.
-AT_CHECK_M4([-R frozen.m4f unfrozen.m4], 0,
-           [expout], [experr])
-
-AT_CLEANUP([frozen.m4f])

reply via email to

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