m4-patches
[Top][All Lists]
Advanced

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

FYI: 1-eggert-posixly-correct.patch [was Re: bad define semantics in GNU


From: Gary V. Vaughan
Subject: FYI: 1-eggert-posixly-correct.patch [was Re: bad define semantics in GNU m4]
Date: Wed, 09 Jul 2003 13:39:02 +0100
User-agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.3) Gecko/20030312

Gary V. Vaughan wrote:
Paul Eggert wrote:
Richard Stallman <address@hidden> writes:

   How about if we modify m4 so that it disables incompatibilities with
   POSIX if the POSIXLY_CORRECT environment variable is set?  This is
   what the GNU coding standards suggest.

That is an ok solution.  I had thought that an option would be more
convenient as an interface, but your argument in favor of using the
envvar seems to make sense.

OK, here is a proposed patch against CVS m4 to implement this.  It
suppresses all the POSIX incompatibilities that I found in m4, if
POSIXLY_CORRECT is set.  Unfortunately I can't easily test this, as
CVS m4 requires a CVS libtool version that I don't have, and the
bootstrap fails with the latest released libtool.

+1

If there are no objections, I'll test and apply this when I've recovered from the gastric flu that has put me out of circulation for the last week or so.

Just applied to HEAD, with a few changes to the ChangeLog entries only.
--
  ())_. Gary V. Vaughan     gary@(oranda.demon.co.uk|gnu.org)
  ( '/  Research Scientist  http://www.oranda.demon.co.uk       ,_())____
  / )=  GNU Hacker          http://www.gnu.org/software/libtool  \'      `&
`(_~)_  Tech' Author        http://sources.redhat.com/autobook   =`---d__/
Index: ChangeLog
from  Paul Eggert  <address@hidden> and
        Gary V. Vaughan  <address@hidden>

        Conform to POSIX if the POSIXLY_CORRECT environment is set.
        --traditional `define' now smashes all the definitions.

        * NEWS: Explain this.
        * doc/m4.texinfo (Defn): `defn' takes any number of arguments.
        (Extensions): Explain that extensions that are incompatible with
        POSIX are disabled if POSIXLY_CORRECT is set.
        (Incompatibilities): Remove.
        (Define, Other Incompat): Explain difference
        between GNU and POSIX behavior of define, pushdef, popdef.
        * m4/m4.c (m4_get_posixly_correct_opt): New undef.
        * m4/m4module.h (m4_context_opt_bit_table): Add POSIXLY_CORRECT entry.
        * m4/m4private.h (M4_OPT_POSIXLY_CORRECT_BIT): New macro.
        (m4_get_posixly_correct_opt): New macro.
        * m4/m4macro.c (m4_process_macro): Disable $10, $abc etc. if
        POSIXLY_CORRECT.
        * modules/m4.c (builtin_functions): defn now takes any number of args.
        (builtin_define): Smash all the definitions if
        POSIXLY_CORRECT.
        (builtin_defn)): Allow any number of arguments.
        (builtin_undivert): Do not allow nonnumeric arguments
        if POSIXLY_CORRECT.
        * src/main.c (main): Set posixly-correct behavior if either
        POSIXLY_CORRECT is set, or if -G is given.
        * tests/builtins.at: New test for smashed definitions.

Index: NEWS
===================================================================
RCS file: /cvsroot/m4/m4/NEWS,v
retrieving revision 1.8
diff -u -p -u -r1.8 NEWS
--- NEWS 4 Oct 2001 08:03:18 -0000 1.8
+++ NEWS 9 Jul 2003 12:28:20 -0000
@@ -1,6 +1,16 @@
 GNU m4 NEWS - History of user-visible changes.         -*- outline -*-
 Copyright 1992, 1993, 1994, 1998, 2000, 2001 Free Software Foundation, Inc.
 
+Version beta 1.4r - ???, by ???
+
+* If the POSIXLY_CORRECT environment variable is set, m4 now disables
+  GNU extensions that are incompatible with POSIX.
+
+* POSIXLY_CORRECT and `m4 --traditional' now makes the `define' builtin
+  replace all `pushdef'ed values of a macro, as POSIX requires.
+
+* The `defn' builtin now allows any number of arguments, as POSIX requires.
+
 Version beta 1.4q - August 2001, by Gary V. Vaughan
 
 * Support for the experimental `changeword' has been dropped.
Index: doc/m4.texinfo
===================================================================
RCS file: /cvsroot/m4/m4/doc/m4.texinfo,v
retrieving revision 1.17
diff -u -p -u -r1.17 m4.texinfo
--- doc/m4.texinfo 27 Jun 2003 14:00:25 -0000 1.17
+++ doc/m4.texinfo 9 Jul 2003 12:28:33 -0000
@@ -235,7 +235,6 @@ Miscellaneous builtin macros
 Compatibility with other versions of @code{m4}
 
 * Extensions::                  Extensions in GNU m4
-* Incompatibilities::           Facilities in System V m4 not in GNU m4
 * Other Incompat::              Other incompatibilities
 
 @end detailmenu
@@ -1032,6 +1031,14 @@ a part of the macro definition, and it i
 the output.  This can be avoided by use of the macro @code{dnl}.
 @xref{Dnl}, for details.
 
address@hidden GNU extensions
+GNU @code{m4} normally replaces only the @emph{topmost} definition of a
+macro if it has several definitions from @code{pushdef}.
address@hidden, , Temporarily redefining macros}, for an explanation of
address@hidden  Some other UNIX implementations replace all definitions
+of a macro with @code{define}.
address@hidden Incompat, , Other incompatibilities}, for more details.
+
 The first argument to @code{define} does not have to be a simple word.
 It can be any text string.  A macro with a non standard name cannot be
 invoked in the normal way, as the name is not recognised.  It can only
@@ -1245,6 +1252,11 @@ points to the builtin's internal definit
 meaningful as the second argument to @code{define} (and @code{pushdef}),
 and is ignored in any other context.
 
address@hidden can be given any number of arguments; it expands to the
+concatenation of the quoted definitions of each argument.  The
+usefulness of this behavior is unclear, but @acronym{POSIX} requires
+it.
+
 The macro @code{defn} is recognized only with parameters.
 @end deffn
 
@@ -3761,7 +3773,6 @@ is made to summarize these here.
 
 @menu
 * Extensions::                  Extensions in GNU m4
-* Incompatibilities::           Facilities in System V m4 not in GNU m4
 * Other Incompat::              Other incompatibilities
 @end menu
 
@@ -3769,10 +3780,16 @@ is made to summarize these here.
 @section Extensions in GNU @code{m4}
 
 @cindex GNU extensions
address@hidden @acronym{POSIX}
address@hidden @env{POSIXLY_CORRECT}
 This version of @code{m4} contains a few facilities, that do not exist
 in System V @code{m4}.  These extra facilities are all suppressed by
 using the @samp{-G} command line option, unless overridden by other
 command line options.
+Most of these extensions are compatible with
address@hidden://www.unix.org/single_unix_specification/,
address@hidden; the few exceptions are suppressed if the
address@hidden environment variable is set.
 
 @itemize @bullet
 @item
@@ -3780,6 +3797,8 @@ In the @address@hidden notation for macr
 several digits, while the System V @code{m4} only accepts one digit.
 This allows macros in GNU @code{m4} to take any number of arguments, and
 not only nine (@pxref{Arguments}).
address@hidden does not allow this extension, so it is disabled if
address@hidden is set.
 
 @item
 Files included with @code{include} and @code{sinclude} are sought in a
@@ -3790,6 +3809,8 @@ directory.  The search path is specified
 @item
 Arguments to @code{undivert} can be non-numeric, in which case the named
 file will be included uninterpreted in the output (@pxref{Undivert}).
address@hidden does not allow this extension, so it is disabled if
address@hidden is set.
 
 @item
 Formatted output is supported through the @code{format} builtin, which
@@ -3846,18 +3867,6 @@ description of these options.
 Also, the debugging and tracing facilities in GNU @code{m4} are much
 more extensive than in most other versions of @code{m4}.
 
address@hidden Incompatibilities
address@hidden Facilities in System V @code{m4} not in GNU @code{m4}
-
-The version of @code{m4} from System V contains a few facilities that
-have not been implemented in GNU @code{m4} yet.
-
address@hidden @bullet
address@hidden
-System V @code{m4} supports multiple arguments to @code{defn}.  This is
-not implemented in GNU @code{m4}.  Its usefulness is unclear to me.
address@hidden itemize
-
 @node Other Incompat
 @section Other incompatibilities
 
@@ -3908,6 +3917,15 @@ name would be a useless limitation.  Of 
 for the GNU @code{m4} user to hang himself!  Rescanning hangs may be
 avoided through careful programming, a little like for endless loops
 in traditional programming languages.
+
address@hidden
+Some implementations of @code{m4} (Solaris for example) conform to
address@hidden, which requires @code{define(@var{macro})} to behave
+like @code{undefine(@var{macro})pushdef(@var{macro})}.  Other
+implementations, including GNU @code{m4} without the @samp{-G} option
+and without @env{POSIXLY_CORRECT} set, treat
address@hidden(@var{macro})} as
address@hidden(@var{macro})pushdef(@var{macro})}.
 
 @item
 @findex __gnu__
Index: m4/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 m4.c
--- m4/m4.c 26 Jun 2003 14:57:32 -0000 1.4
+++ m4/m4.c 9 Jul 2003 12:28:33 -0000
@@ -62,6 +62,7 @@ m4_delete (m4 *context)
 #undef m4_get_discard_comments_opt
 #undef m4_get_interactive_opt
 #undef m4_get_sync_output_opt
+#undef m4_get_posixly_correct_opt
 
 
 #define M4FIELD(type, base, field)                                     \
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.53
diff -u -p -u -r1.53 m4module.h
--- m4/m4module.h 27 Jun 2003 14:00:25 -0000 1.53
+++ m4/m4module.h 9 Jul 2003 12:28:36 -0000
@@ -105,6 +105,7 @@ extern void         m4_delete       (m4 *);
        M4OPT_BIT(M4_OPT_DISCARD_COMMENTS_BIT,  discard_comments_opt)   \
        M4OPT_BIT(M4_OPT_INTERACTIVE_BIT,       interactive_opt)        \
        M4OPT_BIT(M4_OPT_SYNC_OUTPUT_BIT,       sync_output_opt)        \
+       M4OPT_BIT(M4_OPT_POSIXLY_CORRECT_BIT,   posixly_correct_opt)    \
 
 
 #define M4FIELD(type, base, field)                                     \
Index: m4/m4private.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4private.h,v
retrieving revision 1.26
diff -u -p -u -r1.26 m4private.h
--- m4/m4private.h 26 Jun 2003 14:57:32 -0000 1.26
+++ m4/m4private.h 9 Jul 2003 12:28:36 -0000
@@ -59,6 +59,7 @@ struct m4 {
 #define M4_OPT_DISCARD_COMMENTS_BIT    (1 << 2) /* -c */
 #define M4_OPT_INTERACTIVE_BIT         (1 << 3) /* -e */
 #define M4_OPT_SYNC_OUTPUT_BIT         (1 << 4) /* -s */
+#define M4_OPT_POSIXLY_CORRECT_BIT     (1 << 5) /* POSIXLY_CORRECT */
 
 #ifdef NDEBUG
 #  define m4_get_symbol_table(C)               ((C)->symtab)
@@ -79,6 +80,8 @@ struct m4 {
                (BIT_TEST((C)->opt_flags, M4_OPT_INTERACTIVE_BIT))
 #  define m4_get_sync_output_opt(C)                                    \
                (BIT_TEST((C)->opt_flags, M4_OPT_SYNC_OUTPUT_BIT))
+#  define m4_get_posixly_correct_opt(C)                                        
\
+               (BIT_TEST((C)->opt_flags, M4_OPT_POSIXLY_CORRECT_BIT))
 #endif
 
 
Index: m4/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/macro.c,v
retrieving revision 1.31
diff -u -p -u -r1.31 macro.c
--- m4/macro.c 27 Jun 2003 14:00:25 -0000 1.31
+++ m4/macro.c 9 Jul 2003 12:28:38 -0000
@@ -343,7 +343,7 @@ m4_process_macro (m4 *context, m4_symbol
        {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
-         if (m4_get_no_gnu_extensions_opt (context) || !isdigit(text[1]))
+         if (m4_get_posixly_correct_opt (context) || !isdigit(text[1]))
            {
              i = *text++ - '0';
            }
@@ -369,7 +369,7 @@ m4_process_macro (m4 *context, m4_symbol
          break;
 
        default:
-         if (m4_get_no_gnu_extensions_opt (context)
+         if (m4_get_posixly_correct_opt (context)
              || !SYMBOL_ARG_SIGNATURE (symbol))
            {
              obstack_1grow (obs, ch);
Index: modules/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/m4.c,v
retrieving revision 1.45
diff -u -p -u -r1.45 m4.c
--- modules/m4.c 26 Jun 2003 14:57:32 -0000 1.45
+++ modules/m4.c 9 Jul 2003 12:28:38 -0000
@@ -56,7 +56,7 @@ extern int errno;
        BUILTIN(changequote,    FALSE,  FALSE,  1,      3  )    \
        BUILTIN(decr,           FALSE,  TRUE,   2,      2  )    \
        BUILTIN(define,         TRUE,   TRUE,   2,      3  )    \
-       BUILTIN(defn,           FALSE,  TRUE,   2,      2  )    \
+       BUILTIN(defn,           FALSE,  TRUE,   0,      -1 )    \
        BUILTIN(divert,         FALSE,  FALSE,  1,      2  )    \
        BUILTIN(divnum,         FALSE,  FALSE,  1,      1  )    \
        BUILTIN(dnl,            FALSE,  FALSE,  1,      1  )    \
@@ -161,6 +161,9 @@ M4BUILTIN_HANDLER (define)
       else
        m4_symbol_value_copy (value, argv[2]);
 
+      if (m4_get_posixly_correct_opt (context))
+       m4_symbol_delete (M4SYMTAB, M4ARG (1));
+
       m4_symbol_define (M4SYMTAB, M4ARG (1), value);
     }
 }
@@ -311,22 +314,24 @@ M4BUILTIN_HANDLER (dumpdef)
    macro-definition token on the input stack.  */
 M4BUILTIN_HANDLER (defn)
 {
-  m4_symbol *symbol;
+  int i;
 
-  symbol = m4_symbol_lookup (M4SYMTAB, M4ARG (1));
-  if (symbol == NULL)
+  for (i = 1; i < argc; i++)
     {
-      M4WARN ((m4_get_warning_status_opt (context), 0,
-              _("Warning: %s: undefined name: %s"), M4ARG (0), M4ARG (1)));
-      return;
-    }
+      const char *name = m4_get_symbol_value_text (argv[i]);
+      m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, name);
 
-  if (m4_is_symbol_text (symbol))
-    m4_shipout_string (context, obs, m4_get_symbol_text (symbol), 0, TRUE);
-  else if (m4_is_symbol_func (symbol))
-    m4_push_builtin (m4_get_symbol_value (symbol));
-  else
-    assert (!"Bad token data type in m4_defn");
+      if (!symbol)
+       M4WARN ((m4_get_warning_status_opt (context), 0,
+                _("Warning: %s: undefined name: %s"),
+                m4_get_symbol_value_text (argv[0]), name));
+      else if (m4_is_symbol_text (symbol))
+       m4_shipout_string (context, obs, m4_get_symbol_text (symbol), 0, TRUE);
+      else if (m4_is_symbol_func (symbol))
+       m4_push_builtin (m4_get_symbol_value (symbol));
+      else
+       assert (!"Bad token data type in m4_defn");
+    }
 }
 
 
@@ -402,7 +407,7 @@ M4BUILTIN_HANDLER (undivert)
     {
       if (sscanf (M4ARG (1), "%d", &i) == 1)
        m4_insert_diversion (i);
-      else if (m4_get_no_gnu_extensions_opt (context))
+      else if (m4_get_posixly_correct_opt (context))
        m4_numeric_arg (context, argc, argv, 1, &i);
       else
        {
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.43
diff -u -p -u -r1.43 main.c
--- src/main.c 26 Jun 2003 14:57:32 -0000 1.43
+++ src/main.c 9 Jul 2003 12:28:41 -0000
@@ -240,6 +240,9 @@ main (int argc, char *const *argv, char 
   if (isatty (STDIN_FILENO))
     m4_set_interactive_opt (context, TRUE);
 
+  if (getenv ("POSIXLY_CORRECT"))
+    m4_set_posixly_correct_opt (context, TRUE);
+
   /* First, we decode the arguments, to size up tables and stuff.  */
 
   head = tail = NULL;
@@ -290,6 +293,7 @@ main (int argc, char *const *argv, char 
 
       case 'G':
        m4_set_no_gnu_extensions_opt (context, TRUE);
+       m4_set_posixly_correct_opt (context, TRUE);
        break;
 
       case 'I':
Index: tests/builtins.at
===================================================================
RCS file: /cvsroot/m4/m4/tests/builtins.at,v
retrieving revision 1.7
diff -u -p -u -r1.7 builtins.at
--- tests/builtins.at 13 Oct 2001 08:55:55 -0000 1.7
+++ tests/builtins.at 9 Jul 2003 12:28:41 -0000
@@ -20,6 +20,44 @@ AT_BANNER([Torturing builtins.])
 
 
 ## ------ ##
+## define ##
+## ------ ##
+
+AT_SETUP([[define]])
+
+AT_DATA([[define.m4]],
+[[undefine(`macro')dnl
+pushdef(`macro', `base value')dnl
+pushdef(`macro', `hello, world')dnl
+pushdef(`macro', `top value')dnl
+define(`macro', `new value')dnl
+macro.
+popdef(`macro')dnl
+macro.
+popdef(`macro')dnl
+macro.
+]])
+
+AT_CHECK_M4([define.m4], 0,
+[[new value.
+hello, world.
+base value.
+]], [[m4: define.m4: 1: Warning: undefine: undefined name: macro
+]])
+
+AT_CHECK_M4([--traditional define.m4], 0,
+[[new value.
+macro.
+macro.
+]], [[m4: define.m4: 1: Warning: undefine: undefined name: macro
+m4: define.m4: 9: Warning: popdef: undefined name: macro
+]])
+
+AT_CLEANUP
+
+
+
+## ------ ##
 ## divert ##
 ## ------ ##
 

reply via email to

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