-----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 <[EMAIL PROTECTED]> * 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 [EMAIL PROTECTED] -----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. [EMAIL PROTECTED] FIXME - need to implement -B/--prepend=DIR, to prepend to the [EMAIL PROTECTED] search path prior to `.'. [EMAIL PROTECTED] -B @var{DIRECTORY} [EMAIL PROTECTED] [EMAIL PROTECTED] +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 @[EMAIL PROTECTED]@[EMAIL PROTECTED] @itemx [EMAIL PROTECTED]@[EMAIL PROTECTED]@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 [EMAIL PROTECTED] 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. [EMAIL PROTECTED] -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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 = `'])
_______________________________________________ M4-discuss mailing list M4-discuss@gnu.org http://lists.gnu.org/mailman/listinfo/m4-discuss