[Top][All Lists]
[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 ##
## ------ ##