[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: RFC: m4 2.0 --prepend-include option
From: |
Eric Blake |
Subject: |
Re: RFC: m4 2.0 --prepend-include option |
Date: |
Fri, 25 Aug 2006 13:22:20 -0600 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.5) Gecko/20060719 Thunderbird/1.5.0.5 Mnenhy/0.7.4.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Eric Blake on 8/23/2006 9:24 AM:
> Here is my proposal for adding a --prepend-include option to m4 2.0, so
> that once autom4te requires 2.0, it can search for files outside of the
> current working directory first.
I've cleaned it up some, making -B an unconditional synonym for
- --prepend-include, per Paul's advice, with the caveat that -B1024 will
issue a warning that it is no longer compatible with other command line m4
implementations. Perhaps I should tune it further to not even warn unless
./1024 is a directory? I also added some tests to the testsuite.
I also added warnings for -T and -S, as well as for -N/--diversions (which
has been a no-op in 1.4.x), but I left -H/--hashsize as a silent
compatibility option for now (since it had an effect in 1.4.x, and might
make the transition from 1.4.x to 2.0 smoother). Let me know if I should
change any of these decisions.
There are more things to do in regards to POSIXLY_CORRECT, so this thread
is by no means closed, but I am checking in the following:
2006-08-25 Eric Blake <address@hidden>
* tests/options.at (debug-flags): Update to reflect new message.
(deprecated options, prepend-include, help and version): New
tests.
* tests/testsuite.at (AT_CHECK_M4): Avoid hanging testsuite if
test omits an input file name.
* src/main.c (long_options, main): Add -B/--prepend-include.
(usage): Document it.
(main): `m4 --help --version' now displays help, not version.
* ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
dirname filenamecat.
* m4/m4module.h (m4_add_include_directory): Add parameter.
* m4/m4private.h (m4__include_init): New prototype.
* m4/m4.c (m4_create): Put `.' on path before options are
collected.
* m4/path.c (includes): Assume C89. Use gnulib for file name
management.
(m4__include_init): New function.
(search_path_add): Allow prepending.
(m4_add_include_directory, search_path_env_init): Adjust callers.
(m4_path_search): Relative names now invoke path search, since
`.' might not be first.
* doc/m4.texinfo (Invoking m4, Search Path): Document new option.
- --
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
iD8DBQFE703s84KuGfSFAYARAkQbAJ9qqflEcz2v7olFsZXY52PtLYGBGQCfRIbX
id3GH9fR8LKYNMB6QRIu/1Y=
=XW+Z
-----END PGP SIGNATURE-----
? ltdl/m4/dirname.m4
? ltdl/m4/dos.m4
? ltdl/m4/double-slash-root.m4
? ltdl/m4/filenamecat.m4
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.34
diff -u -p -r1.34 m4.texinfo
--- doc/m4.texinfo 25 Aug 2006 15:34:09 -0000 1.34
+++ doc/m4.texinfo 25 Aug 2006 19:00:14 -0000
@@ -497,8 +497,19 @@ Imports every variable in the environmen
before @option{-D} and @option{-U}, so they can override the
enviroment.
address@hidden FIXME - need to implement -B/--prepend=DIR, to prepend to the
address@hidden search path prior to `.'.
address@hidden -B @var{DIRECTORY}
address@hidden address@hidden
+Make @code{m4} search @var{DIRECTORY} for included files, prior to
+searching the current working directory. @xref{Search Path}, for more
+details. This option may be given more than once. Some other
+implementations of @code{m4} use @code{-B @var{number}} to change their
+hard-coded limits, but that is unnecessary in @acronym{GNU} where the
+only limit is your hardware capability. So although it is unlikely that
+you will want to include a relative directory whose name is purely
+numeric, @acronym{GNU} @code{m4} will warn you about this potential
+compatibility issue; you can avoid the warning by using the long
+spelling, or by using @samp{./@var{number}} if you really meant it.
+
@item -D @address@hidden@address@hidden
@itemx address@hidden@address@hidden@r{]}
This enters @var{NAME} into the symbol table, before any input files are
@@ -586,13 +597,14 @@ problem in general, if not undecidable!
@itemx address@hidden
These options are present only for compatibility with previous
versions of GNU @code{m4}. They do nothing, because the symbol table
-size and number of diversions are not fixed anymore.
+size and number of diversions are not fixed anymore. They will
+eventually disappear in future releases.
address@hidden -B @var{NUM}
@itemx -S @var{NUM}
@itemx -T @var{NUM}
These options are present for compatibility with System V @code{m4}, but
-do nothing in this implementation.
+do nothing in this implementation. They may disappear in future
+releases.
@end table
@acronym{GNU} @code{m4} comes with a feature of freezing internal state
@@ -2184,7 +2196,7 @@ Show the the current input line number i
@item p
Print a message when a named file is found through the path search
-mecanism (@pxref{Search Path}), giving the actual file name used.
+mechanism (@pxref{Search Path}), giving the actual file name used.
@item i
Print a message each time the current input file is changed, giving file
@@ -2941,12 +2953,14 @@ In GNU @code{m4}, an alternative method
GNU @code{m4} allows included files to be found in other directories
than the current working directory.
-If a file is not found in the current working directory, and the file
-name is not absolute, the file will be looked for in a specified search
-path. First, the directories specified with the @samp{-I} option will
-be searched, in the order found on the command line. Second, if the
address@hidden environment variable is set, it is expected to contain a
-colon-separated list of directories, which will be searched in order.
+If the @option{--prepend-include} or @option{-B} option was provided
+(@pxref{Invoking m4}), those directories are searched first, in reverse
+order that those options were listed on the command line. Then
address@hidden looks in the current working directory. Next comes the
+directories specified with the @option{--include} or @option{-I} option
+will be searched, in the order found on the command line. Finally, if
+the @env{M4PATH} environment variable is set, it is expected to contain
+a colon-separated list of directories, which will be searched in order.
If the automatic search for include-files causes trouble, the @samp{p}
debug flag (@pxref{Debug Levels}) can help isolate the problem.
Index: ltdl/m4/gnulib-cache.m4
===================================================================
RCS file: /sources/m4/m4/ltdl/m4/gnulib-cache.m4,v
retrieving revision 1.8
diff -u -p -r1.8 gnulib-cache.m4
--- ltdl/m4/gnulib-cache.m4 22 Aug 2006 22:36:28 -0000 1.8
+++ ltdl/m4/gnulib-cache.m4 25 Aug 2006 19:00:14 -0000
@@ -15,10 +15,10 @@
# Specification in the form of a command-line invocation:
-# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnu
--m4-base=ltdl/m4 --doc-base=doc --aux-dir=ltdl/config --libtool
--macro-prefix=M4 assert binary-io cloexec close-stream error exit fdl
fopen-safer free gendocs getopt gettext gnupload mkstemp obstack progname regex
regexprops-generic stdbool stdlib-safer strtol unlocked-io verror xalloc
xalloc-die xstrndup xvasprintf
+# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnu
--m4-base=ltdl/m4 --doc-base=doc --aux-dir=ltdl/config --libtool
--macro-prefix=M4 assert binary-io cloexec close-stream dirname error exit fdl
filenamecat fopen-safer free gendocs getopt gettext gnupload mkstemp obstack
progname regex regexprops-generic stdbool stdlib-safer strtol unlocked-io
verror xalloc xalloc-die xstrndup xvasprintf
# Specification in the form of a few gnulib-tool.m4 macro invocations:
-gl_MODULES([assert binary-io cloexec close-stream error exit fdl fopen-safer
free gendocs getopt gettext gnupload mkstemp obstack progname regex
regexprops-generic stdbool stdlib-safer strtol unlocked-io verror xalloc
xalloc-die xstrndup xvasprintf])
+gl_MODULES([assert binary-io cloexec close-stream dirname error exit fdl
filenamecat fopen-safer free gendocs getopt gettext gnupload mkstemp obstack
progname regex regexprops-generic stdbool stdlib-safer strtol unlocked-io
verror xalloc xalloc-die xstrndup xvasprintf])
gl_AVOID([])
gl_SOURCE_BASE([gnu])
gl_M4_BASE([ltdl/m4])
Index: m4/m4.c
===================================================================
RCS file: /sources/m4/m4/m4/m4.c,v
retrieving revision 1.16
diff -u -p -r1.16 m4.c
--- m4/m4.c 27 Jul 2006 22:34:55 -0000 1.16
+++ m4/m4.c 25 Aug 2006 19:00:14 -0000
@@ -37,6 +37,7 @@ m4_create (void)
context->nesting_limit = DEFAULT_NESTING_LIMIT;
context->search_path = xzalloc (sizeof context->search_path);
+ m4__include_init (context);
return context;
}
Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.78
diff -u -p -r1.78 m4module.h
--- m4/m4module.h 23 Aug 2006 11:39:26 -0000 1.78
+++ m4/m4module.h 25 Aug 2006 19:00:14 -0000
@@ -386,7 +386,7 @@ extern void m4_undivert_all (m4 *);
/* --- PATH MANAGEMENT --- */
extern void m4_include_env_init (m4 *);
-extern void m4_add_include_directory (m4 *, const char *);
+extern void m4_add_include_directory (m4 *, const char *, bool);
extern FILE * m4_path_search (m4 *, const char *, char **);
Index: m4/m4private.h
===================================================================
RCS file: /sources/m4/m4/m4/m4private.h,v
retrieving revision 1.54
diff -u -p -r1.54 m4private.h
--- m4/m4private.h 22 Aug 2006 22:36:28 -0000 1.54
+++ m4/m4private.h 25 Aug 2006 19:00:14 -0000
@@ -323,6 +323,7 @@ struct m4__search_path_info {
int max_length; /* length of longest directory name */
};
+extern void m4__include_init (m4 *);
/* Debugging the memory allocator. */
Index: m4/path.c
===================================================================
RCS file: /sources/m4/m4/m4/path.c,v
retrieving revision 1.18
diff -u -p -r1.18 path.c
--- m4/path.c 22 Aug 2006 22:36:28 -0000 1.18
+++ m4/path.c 25 Aug 2006 19:00:14 -0000
@@ -26,25 +26,19 @@
# include <config.h>
#endif
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#if HAVE_STRING_H
-# include <string.h>
-#else
-# if HAVE_STRINGS_H
-# include <strings.h>
-# endif
-#endif
+#include <stdlib.h>
+#include <string.h>
#include "m4module.h"
#include "m4private.h"
+#include "dirname.h"
+#include "filenamecat.h"
+
/* Define this to see runtime debug info. Implied by DEBUG. */
/*#define DEBUG_INCL */
-static void search_path_add (m4__search_path_info *, const char *);
+static void search_path_add (m4__search_path_info *, const char *, bool);
static void search_path_env_init (m4__search_path_info *, char *, bool);
@@ -53,25 +47,33 @@ static void search_path_env_init (m4__se
*/
static void
-search_path_add (m4__search_path_info *info, const char *dir)
+search_path_add (m4__search_path_info *info, const char *dir, bool prepend)
{
m4__search_path *path = xmalloc (sizeof *path);
- if (*dir == '\0')
- dir = ".";
-
- path->next = NULL;
path->len = strlen (dir);
path->dir = xstrdup (dir);
if (path->len > info->max_length) /* remember len of longest directory */
info->max_length = path->len;
- if (info->list_end == NULL)
- info->list = path;
+ if (prepend)
+ {
+ path->next = info->list;
+ info->list = path;
+ if (info->list_end == NULL)
+ info->list_end = path;
+ }
else
- info->list_end->next = path;
- info->list_end = path;
+ {
+ path->next = NULL;
+
+ if (info->list_end == NULL)
+ info->list = path;
+ else
+ info->list_end->next = path;
+ info->list_end = path;
+ }
}
static void
@@ -88,7 +90,7 @@ search_path_env_init (m4__search_path_in
if (path_end)
*path_end = '\0';
if (!isabs || *path == '/')
- search_path_add (info, path);
+ search_path_add (info, path, false);
path = path_end + 1;
}
while (path_end);
@@ -108,25 +110,33 @@ m4_include_env_init (m4 *context)
}
void
-m4_add_include_directory (m4 *context, const char *dir)
+m4_add_include_directory (m4 *context, const char *dir, bool prepend)
{
if (m4_get_no_gnu_extensions_opt (context))
return;
- search_path_add (m4__get_search_path (context), dir);
+ search_path_add (m4__get_search_path (context), dir, prepend);
#ifdef DEBUG_INCL
- fprintf (stderr, "add_include_directory (%s);\n", dir);
+ fprintf (stderr, "add_include_directory (%s) %s;\n", dir,
+ prepend ? "prepend" : "append");
#endif
}
+/* Search for FILE according to -B options, `.', -I options, then
+ M4PATH environment. If successful, return the open file, and if
+ RESULT is not NULL, set *RESULT to a malloc'd string that
+ represents the file found with respect to the current working
+ directory. Otherwise, return NULL, and errno reflects the failure
+ from searching `.' (regardless of what else was searched). */
+
FILE *
m4_path_search (m4 *context, const char *file, char **expanded_name)
{
FILE *fp;
m4__search_path *incl;
char *name; /* buffer for constructed name */
- int e;
+ int e = 0;
if (expanded_name != NULL)
*expanded_name = NULL;
@@ -138,32 +148,27 @@ m4_path_search (m4 *context, const char
return NULL;
}
- /* Look in current working directory first. */
- fp = fopen (file, "r");
- if (fp != NULL)
- {
- if (set_cloexec_flag (fileno (fp), true) != 0)
- m4_error (context, 0, errno,
- _("cannot protect input file across forks"));
- if (expanded_name != NULL)
- *expanded_name = xstrdup (file);
- return fp;
- }
-
- /* If file not found, and filename absolute, fail. */
- if (*file == '/' || m4_get_no_gnu_extensions_opt (context))
- return NULL;
- e = errno;
-
- name = (char *) xmalloc (m4__get_search_path (context)->max_length
- + 1 + strlen (file) + 1);
+ /* If file is absolute, or if we are not searching a path, a single
+ lookup will do the trick. */
+ if (IS_ABSOLUTE_FILE_NAME (file) || m4_get_no_gnu_extensions_opt (context))
+ {
+ fp = fopen (file, "r");
+ if (fp != NULL)
+ {
+ if (set_cloexec_flag (fileno (fp), true) != 0)
+ m4_error (context, 0, errno,
+ _("cannot protect input file across forks"));
+ if (expanded_name != NULL)
+ *expanded_name = xstrdup (file);
+ return fp;
+ }
+ return NULL;
+ }
for (incl = m4__get_search_path (context)->list;
incl != NULL; incl = incl->next)
{
- strncpy (name, incl->dir, incl->len);
- name[incl->len] = '/';
- strcpy (name + incl->len + 1, file);
+ name = file_name_concat (incl->dir, file, NULL);
#ifdef DEBUG_INCL
fprintf (stderr, "path_search (%s) -- trying %s\n", file, name);
@@ -183,26 +188,38 @@ m4_path_search (m4 *context, const char
*expanded_name = name;
else
free (name);
- errno = e;
return fp;
}
+ else if (!incl->len)
+ /* Capture errno only when searching `.'. */
+ e = errno;
+ free (name);
}
- free (name);
-
errno = e;
- return fp;
+ return NULL;
+}
+
+void
+m4__include_init (m4 *context)
+{
+ m4__search_path_info *info = m4__get_search_path (context);
+
+ assert (info);
+ search_path_add (info, "", false);
}
+
#ifdef DEBUG_INCL
-static void
+static void M4_GNUC_UNUSED
include_dump (m4 *context)
{
m4__search_path *incl;
fprintf (stderr, "include_dump:\n");
- for (incl = m4__get_search_path (context)->list; incl != NULL; incl =
incl->next)
+ for (incl = m4__get_search_path (context)->list;
+ incl != NULL; incl = incl->next)
fprintf (stderr, "\t%s\n", incl->dir);
}
Index: src/main.c
===================================================================
RCS file: /sources/m4/m4/src/main.c,v
retrieving revision 1.76
diff -u -p -r1.76 main.c
--- src/main.c 23 Aug 2006 11:39:26 -0000 1.76
+++ src/main.c 25 Aug 2006 19:00:14 -0000
@@ -25,6 +25,8 @@
#include "version-etc.h"
#include "gnu/progname.h"
+#include <limits.h>
+
#define AUTHORS _("Rene' Seindal"), "Gary V. Vaughan"
@@ -34,14 +36,8 @@ const char *frozen_file_to_read = NULL;
/* Name of frozen file to produce near completion. */
const char *frozen_file_to_write = NULL;
-/* If nonzero, display usage information and exit. */
-static int show_help = 0;
-
-/* If nonzero, print the version on standard output and exit. */
-static int show_version = 0;
-
/* If nonzero, import the environment as macros. */
-static int import_environment = 0;
+static bool import_environment = false;
typedef struct macro_definition
{
@@ -109,15 +105,16 @@ SPEC is any one of:\n\
printf (_("\
\n\
Dynamic loading features:\n\
- -M, --module-directory=DIRECTORY add DIRECTORY to the module search path\n\
- -m, --load-module=MODULE load dynamic MODULE from %s\n\
+ -M, --module-directory=DIR add DIR to the module search path\n\
+ -m, --load-module=MODULE load dynamic MODULE from %s\n\
"), USER_MODULE_PATH_ENV);
fputs (_("\
\n\
Preprocessor features:\n\
--import-environment import all environment variables as macros\n\
+ -B, --prepend-include=DIR add DIR to include path before `.'\n\
-D, --define=NAME[=VALUE] define NAME has having VALUE, or empty\n\
- -I, --include=DIRECTORY append DIRECTORY to include path\n\
+ -I, --include=DIR add DIR to include path after `.'\n\
-s, --synclines generate `#line NUM \"FILE\"' lines\n\
-U, --undefine=NAME undefine NAME\n\
"), stdout);
@@ -158,6 +155,13 @@ FLAGS is any of:\n\
"), stdout);
fputs (_("\
\n\
+If defined, the environment variable `M4PATH' is a colon-separated list\n\
+of directories included after any specified by `-I', and the variable\n\
+`M4MODPATH' is a colon-separated list of directories searched after any\n\
+specified by `-M'.\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);
@@ -166,14 +170,26 @@ mismatch, or whatever value was passed t
exit (status);
}
+/* For long options that have no equivalent short option, use a
+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */
+enum
+{
+ DIVERSIONS_OPTION = CHAR_MAX + 1, /* not quite -N, because of message */
+ IMPORT_ENVIRONMENT_OPTION, /* no short opt */
+ PREPEND_INCLUDE_OPTION, /* not quite -B, because of message */
+
+ HELP_OPTION, /* no short opt */
+ VERSION_OPTION /* no short opt */
+};
+
/* Decode options and launch execution. */
static const struct option long_options[] =
{
{"arglength", required_argument, NULL, 'l'},
{"batch", no_argument, NULL, 'b'},
{"debug", optional_argument, NULL, 'd'},
+ {"define", required_argument, NULL, 'D'},
{"discard-comments", no_argument, NULL, 'c'},
- {"diversions", required_argument, NULL, 'N'},
{"error-output", required_argument, NULL, 'o'},
{"fatal-warnings", no_argument, NULL, 'E'},
{"freeze-state", required_argument, NULL, 'F'},
@@ -189,20 +205,19 @@ static const struct option long_options[
{"reload-state", required_argument, NULL, 'R'},
{"silent", no_argument, NULL, 'Q'},
{"synclines", no_argument, NULL, 's'},
+ {"trace", required_argument, NULL, 't'},
{"traditional", no_argument, NULL, 'G'},
+ {"undefine", required_argument, NULL, 'U'},
{"word-regexp", required_argument, NULL, 'W'},
- {"import-environment", no_argument, &import_environment, 1},
-
- {"help", no_argument, &show_help, 1},
- {"version", no_argument, &show_version, 1},
+ {"diversions", required_argument, NULL, DIVERSIONS_OPTION},
+ {"import-environment", no_argument, NULL, IMPORT_ENVIRONMENT_OPTION},
+ {"prepend-include", required_argument, NULL, PREPEND_INCLUDE_OPTION},
- /* These are somewhat troublesome. */
- { "define", required_argument, NULL, 'D' },
- { "undefine", required_argument, NULL, 'U' },
- { "trace", required_argument, NULL, 't' },
+ {"help", no_argument, NULL, HELP_OPTION},
+ {"version", no_argument, NULL, VERSION_OPTION},
- { 0, 0, 0, 0 },
+ { NULL, 0, NULL, 0 },
};
#define OPTSTRING "B:D:EF:GH:I:L:M:N:PQR:S:T:U:bcd::el:m:o:r:st:"
@@ -212,7 +227,7 @@ main (int argc, char *const *argv, char
{
macro_definition *head; /* head of deferred argument list */
macro_definition *tail;
- macro_definition *new;
+ macro_definition *defn;
int optchar; /* option character */
macro_definition *defines;
@@ -251,22 +266,33 @@ main (int argc, char *const *argv, char
head = tail = NULL;
- while (optchar = getopt_long (argc, (char **) argv, OPTSTRING,
- long_options, NULL),
- optchar != EOF)
+ while ((optchar = getopt_long (argc, (char **) argv, OPTSTRING,
+ long_options, NULL)) != -1)
switch (optchar)
{
default:
usage (EXIT_FAILURE);
- case 0:
+ case 'H':
+ /* -H was supported in 1.4.x. FIXME - make obsolete after
+ 2.0, and remove after 2.1. For now, keep it silent. */
break;
- case 'B': /* compatibility junk */
- case 'H':
case 'N':
+ case DIVERSIONS_OPTION:
+ /* -N became an obsolete no-op in 1.4.x. FIXME - remove
+ support for -N after 2.0. */
+ error (0, 0, _("Warning: `m4 %s' is deprecated"),
+ optchar == 'N' ? "-N" : "--diversions");
+ break;
+
case 'S':
case 'T':
+ /* Compatibility junk: options that other implementations
+ support, but which we ignore as no-ops and don't list in
+ --help. */
+ error (0, 0, _("Warning: `m4 -%c' may be removed in a future release"),
+ optchar);
break;
case 'D':
@@ -276,19 +302,37 @@ main (int argc, char *const *argv, char
case 'r':
/* Arguments that cannot be handled until later are accumulated. */
- new = xmalloc (sizeof *new);
- new->code = optchar;
- new->macro = optarg;
- new->next = NULL;
+ defn = xmalloc (sizeof *defn);
+ defn->code = optchar;
+ defn->macro = optarg;
+ defn->next = NULL;
if (head == NULL)
- head = new;
+ head = defn;
else
- tail->next = new;
- tail = new;
+ tail->next = defn;
+ tail = defn;
break;
+ case 'B':
+ /* In 1.4.x, -B<num> was a no-op option for compatibility with
+ Solaris m4. Warn if optarg is all numeric. FIXME -
+ silence this warning after 2.0. */
+ if (isdigit ((unsigned char) *optarg))
+ {
+ char *end;
+ errno = 0;
+ strtol (optarg, &end, 10);
+ if (*end == '\0' && errno == 0)
+ error (0, 0, _("Warning: recommend using `m4 -B ./%s' instead"),
+ optarg);
+ }
+ /* fall through */
+ case PREPEND_INCLUDE_OPTION:
+ m4_add_include_directory (context, optarg, true);
+ break;
+
case 'E':
m4_set_fatal_warnings_opt (context, true);
break;
@@ -303,12 +347,13 @@ main (int argc, char *const *argv, char
break;
case 'I':
- m4_add_include_directory (context, optarg);
+ m4_add_include_directory (context, optarg, false);
break;
case 'L':
m4_set_nesting_limit_opt (context, atoi (optarg));
break;
+
case 'M':
if (lt_dlinsertsearchdir (lt_dlgetsearchpath(), optarg) != 0)
{
@@ -375,19 +420,23 @@ main (int argc, char *const *argv, char
case 's':
m4_set_sync_output_opt (context, true);
break;
- }
- if (show_version)
- {
- version_etc (stdout, PACKAGE, PACKAGE_NAME TIMESTAMP,
- VERSION, AUTHORS, NULL);
- exit (EXIT_SUCCESS);
- }
+ case IMPORT_ENVIRONMENT_OPTION:
+ import_environment = true;
+ break;
- if (show_help)
- usage (EXIT_SUCCESS);
+ case VERSION_OPTION:
+ version_etc (stdout, PACKAGE, PACKAGE_NAME TIMESTAMP,
+ VERSION, AUTHORS, NULL);
+ exit (EXIT_SUCCESS);
+ break;
+
+ case HELP_OPTION:
+ usage (EXIT_SUCCESS);
+ break;
+ }
- /* Do the basic initialisations. */
+ /* Do the basic initializations. */
m4_input_init (context);
m4_output_init ();
@@ -405,7 +454,7 @@ main (int argc, char *const *argv, char
}
/* Import environment variables as macros. The definition are
- preprended to the macro definition list, so -U can override
+ prepended to the macro definition list, so -U can override
environment variables. */
if (import_environment)
@@ -414,16 +463,16 @@ main (int argc, char *const *argv, char
for (env = envp; *env != NULL; env++)
{
- new = xmalloc (sizeof *new);
- new->code = 'D';
- new->macro = *env;
- new->next = head;
- head = new;
+ defn = xmalloc (sizeof *defn);
+ defn->code = 'D';
+ defn->macro = *env;
+ defn->next = head;
+ head = defn;
}
}
/* Handle deferred command line macro definitions. Must come after
- initialisation of the symbol table. */
+ initialization of the symbol table. */
{
defines = head;
Index: tests/options.at
===================================================================
RCS file: /sources/m4/m4/tests/options.at,v
retrieving revision 1.4
diff -u -p -r1.4 options.at
--- tests/options.at 23 Aug 2006 11:39:26 -0000 1.4
+++ tests/options.at 25 Aug 2006 19:00:14 -0000
@@ -35,7 +35,7 @@ comment
--> ends.
]])
-AT_CHECK_M4([-c in], 0,
+AT_CHECK_M4([-c in], [0],
[[This is not a comment This should not disappear.
html ends.
@@ -66,8 +66,8 @@ export ZAPPED
OVERRIDE='This is an environment variable which we will change'
export OVERRIDE
-AT_CHECK_M4([--import-environment -UZAPPED -DOVERRIDE='It is changed.' in], 0,
-[[TEST=This is an environment variable
+AT_CHECK_M4([--import-environment -UZAPPED -DOVERRIDE='It is changed.' in],
+[0], [[TEST=This is an environment variable
ZAPPED=ZAPPED
OVERRIDE=It is changed.
]])
@@ -87,15 +87,16 @@ len(`abc')
]])
dnl AT_CHECK_M4 starts life with -d. Make sure it looks like -daeq.
-AT_CHECK_M4([-tlen in], 0, [[0
+AT_CHECK_M4([-tlen in], [0], [[0
3
]], [[m4trace: -1- len(`abc') -> `3'
]])
dnl Test all flags.
-AT_CHECK_M4([-dV in], 0, [[0
+AT_CHECK_M4([-dV in], [0], [[0
3
-]], [[m4debug: input read from in
+]], [[m4debug: path search for `in' found `in'
+m4debug: input read from in
m4trace:in:1: -1- id 1: divnum ...
m4trace:in:1: -1- id 1: divnum -> ???
m4trace:in:1: -1- id 1: divnum -> `0'
@@ -106,10 +107,114 @@ m4debug:in:3: input exhausted
]])
dnl Test addition and subtraction of flags.
-AT_CHECK_M4([-d-e -d+xt in], 0, [[0
+AT_CHECK_M4([-d-e -d+xt in], [0], [[0
3
]], [[m4trace: -1- id 1: divnum
m4trace: -1- id 2: len(`abc')
]])
AT_CLEANUP
+
+
+## ---------------- ##
+## obsolete options ##
+## ---------------- ##
+
+AT_SETUP([deprecated options])
+
+dnl -N/--diversions are no-ops since 1.4.x
+AT_CHECK_M4([-N1 --diversions=1], [0], [],
+[[m4: Warning: `m4 -N' is deprecated
+m4: Warning: `m4 --diversions' is deprecated
+]])
+
+dnl -H/--hashsize are no-ops since 2.0, and still silent for now...
+AT_CHECK_M4([-H1 --hashsize=1])
+
+dnl -S/-T are no-ops for compatibility
+AT_CHECK_M4([-S1 -T1], [0], [],
+[[m4: Warning: `m4 -S' may be removed in a future release
+m4: Warning: `m4 -T' may be removed in a future release
+]])
+
+dnl -Bint can be confused with its no-op meaning in 1.4.x, but all other
+dnl uses of -B or its long option are okay
+AT_CHECK_M4([-B1 -B./1 --prepend-include=1], [0], [],
+[[m4: Warning: recommend using `m4 -B ./1' instead
+]])
+
+AT_CLEANUP
+
+
+## --------------- ##
+## prepend-include ##
+## --------------- ##
+
+AT_SETUP([prepend-include])
+
+dnl Lots of data to set up.
+AT_DATA([[in]],
+[[include(`foo')dnl
+include(`bar')dnl
+include(`bad')dnl
+include(`blah')dnl
+]])
+
+AT_CHECK([mkdir pre post])
+
+AT_DATA([[pre/foo]], [[in pre/foo
+]])
+AT_DATA([[foo]], [[in ./foo
+]])
+AT_DATA([[bar]], [[in ./bar
+]])
+AT_DATA([[post/bar]], [[in post/bar
+]])
+AT_DATA([[post/blah]], [[in post/blah
+]])
+
+dnl Make circular links in the subdirectories, to ensure that the error
+dnl message when bad cannot be opened comes from the search in ., regardless
+dnl of what else was searched.
+AT_CHECK([ln -s bad pre/bad])
+AT_CHECK([ln -s bad post/bad])
+
+dnl Finally, see that it all works.
+AT_CHECK_M4([-I post -B pre in], [1],
+[[in pre/foo
+in ./bar
+in post/blah
+]], [[m4:in:3: include: cannot open `bad': No such file or directory
+]])
+
+AT_CLEANUP
+
+
+## ---------------- ##
+## help and version ##
+## ---------------- ##
+
+AT_SETUP([help and version])
+
+AT_CHECK_M4([--help], [0], [stdout])
+AT_CHECK([[sed -n -e 's|Usage:.*\[OPTION\]... \[FILE\]...|success|p' stdout]],
+[0], [success
+])
+
+AT_CHECK_M4([--version], [0], [stdout])
+AT_CHECK([[sed -n -e 's|There is NO WARRANTY.*|success|p' stdout]],
+[0], [success
+])
+
+dnl make sure option specified first takes precedence
+AT_CHECK_M4([--help --version], [0], [stdout])
+AT_CHECK([[sed -n -e 's|Usage:.*\[OPTION\]... \[FILE\]...|success|p' stdout]],
+[0], [success
+])
+
+AT_CHECK_M4([--version --help], [0], [stdout])
+AT_CHECK([[sed -n -e 's|There is NO WARRANTY.*|success|p' stdout]],
+[0], [success
+])
+
+AT_CLEANUP
Index: tests/testsuite.at
===================================================================
RCS file: /sources/m4/m4/tests/testsuite.at,v
retrieving revision 1.19
diff -u -p -r1.19 testsuite.at
--- tests/testsuite.at 22 Aug 2006 16:16:48 -0000 1.19
+++ tests/testsuite.at 25 Aug 2006 19:00:14 -0000
@@ -23,8 +23,10 @@ m4_version_prereq([2.52e])
# AT_CHECK_M4(ARGS, [EXIT-STATUS = 0], [STDOUT = `'], [STDERR = `'])
# ------------------------------------------------------------------
+# Run m4 with ARGS, and stdin redirected from /dev/null. Expect EXIT-STATUS,
+# with output matching STDOUT and STDERR as in AT_CHECK.
m4_define([AT_CHECK_M4],
-[AT_CHECK([m4 -b -d $1], [$2], [$3], [$4])
+[AT_CHECK([m4 -b -d $1 < /dev/null], [$2], [$3], [$4])
])
# AT_TEST_M4(TITLE, INPUT, [STDOUT = `'], [STDERR = `'])
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: RFC: m4 2.0 --prepend-include option,
Eric Blake <=