On Sat, May 24, 2025 at 02:20:08PM -0400, David M. Warme wrote:
> Eric,
>
> Sorry about the scrambled patch files. I am re-sending as text only
> (still mime encoded) with both the branch-1.4 and branch-1.6 patch
> files sent as gzipped attachments. This should force the attachments
> to be encoded using base64 and arrive intact.
Focusing on the branch-1.6 patch:
> +++ b/NEWS
> @@ -196,6 +196,8 @@ following beta features that were deemed worth deferring
> until 1.6:
>
> * Noteworthy changes in release 1.4.19 (2021-05-28) [stable]
>
> +** Add new capability to automatically generate make dependency rules.
I'm hoisting this earlier in the file, since it did not make it into
the 1.4.19 release. It's also worth calling out the new command line
options by name (down the road, it's easier to search for when an
option was added if the option's name is present in NEWS).
> +++ b/checks/check-them
> @@ -37,6 +37,7 @@ out=$tmp/m4-out
> err=$tmp/m4-err
> xout=$tmp/m4-xout
> xerr=$tmp/m4-xerr
> +xaux=$tmp/m4-xaux
> failed=
> skipped=
> strip_needed=false
> @@ -104,7 +105,8 @@ do
> continue ;;
> esac
>
> - options=`${SED} -ne '3s/^dnl @ extra options: //p;3q' "$file"`
> + options=`${SED} -ne '3s/^dnl @ extra options: //p;3q' "$file" \
> + | ${SED} -e "s/TMP\//$tmp\//"`
"sed ... | sed ..." can usually be compacted into "sed ...". And use
of \ inside ` is always a pain to get right. I'm simplifying this one
slightly.
> ${SED} -e '/^dnl @/d' -e '/^\^D$/q' "$file" \
> | LC_MESSAGES=C LANG=C M4PATH=$examples "$m4" -d $options - >$out 2>$err
> stat=$?
> @@ -126,8 +128,9 @@ do
>
> xoutfile=`${SED} -n 's/^dnl @ expected output: //p' "$file"`
> if test -z "$xoutfile" ; then
> - ${SED} -e '/^dnl @result{}/!d' -e 's///' -e "s|examples/|$examples/|" \
> - -e "s|@value{VERSION}|$m4version|" "$file" > $xout
> + ${SED} -ne 's/^dnl @result{}//p' "$file" \
> + | ${SED} -e "s|examples/|$examples/|" \
> + -e "s|@value{VERSION}|$m4version|" > $xout
Unless I'm reading it wrong, this hunk adds a process, but otherwise
makes no difference in the resulting output (either with the
pre-existing one sed, or with your rewritten pipeline of seds, the net
result is that only the lines starting with 'dnl @result{}' are
printed with that prefix stripped and "examples" and "@value{VERSION}"
rewritten). Since it is unrelated to your feature, I'm excluding it.
> else
> cp "$examples/$xoutfile" $xout
> fi
> @@ -149,6 +152,8 @@ do
> "$examples/$xerrfile" > $xerr ;;
> esac
>
> + auxfile=`${SED} -n 's/^dnl @ expected auxfile: //p' "$file"`
> +
> # For the benefit of mingw, normalize \r\n line endings
> if $strip_needed ; then
> tr -d '\015' < $out > $out.t
> @@ -179,6 +184,32 @@ do
> diff $diffopts $xerr $err
> fi
>
> + if test -n "$auxfile"; then
> + tauxfile=`echo "$auxfile" | ${SED} -e "s/TMP\//$tmp\//"`
This is unsafe if $tmp contains /. Better is to use an alternative
delimiter, like "s|TMP/|$tmp/|".
> +++ b/checks/get-them
> @@ -116,9 +125,9 @@ BEGIN {
> }
> if ($0 ~ /^\^D$/)
> next;
> - if ($0 ~ /^\$ @kbd/)
> + if ($0 ~ /^\$ @kbd/ || $0 ~ /^@kbd/)
Oh, peeking ahead, I see where you wrote:
> +$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target \}
> +@kbd{ --makedep-gen-missing-all foo none -}
It would also be possible to condense this back into one regex, rather
than two (either skipping any line that contains @kbd anywhere, or
still requiring it to be near the front but making the "\$ " prefix
optional).
> +++ b/doc/m4.texi
> @@ -36,6 +36,14 @@
> @r{[}@var{\varname\} = @samp{\default\}@r{]}
> @end macro
>
> +@c @auxresult{auxfile}
> +@c ------------
> +@c Used in examples to indicate output produced within the
> +@c ``auxilliary output file.''
> +@macro auxresult{auxfile}
> +\auxfile\ @b{@result{}}
> +@end macro
> +
> @comment %**end of header
> @comment ========================================================
>
> @@ -148,6 +156,7 @@
> * Preprocessor features:: Command line options for preprocessor
> features
> * Limits control:: Command line options for limits control
> * Frozen state:: Command line options for frozen state
> +* Make dependency generation:: Generating make dependency rules
I still think this chapter fits better right after 'Preprocessor
features' (ie. swapped with Limits control and Frozen state); it's an
easy shuffle to make.
> * Debugging options:: Command line options for debugging
> * Command line files:: Specifying input files on the command line
>
> @@ -583,6 +592,7 @@
> * Preprocessor features:: Command line options for preprocessor
> features
> * Limits control:: Command line options for limits control
> * Frozen state:: Command line options for frozen state
> +* Make dependency generation:: Generating make dependency rules
> * Debugging options:: Command line options for debugging
> * Command line files:: Specifying input files on the command line
> @end menu
> @@ -904,6 +914,191 @@
> files are read.
> @end table
>
> +@node Make dependency generation
> +@section Command line options for generating Makefile dependency rules
> +
> +Makefile dependency rules can be automatically generated by specifying
> +both the @code{--makedep=}@var{file} and
> +@code{--makedep-target=}@var{target} options.
@option may be nicer than @code in the rendering here, and in several
other places in the patch. However, I'll probably defer a more
detailed proof-reading and editing pass until later; my goal on
today's review is making sure the code compiles and tests run.
...
> +
> +@comment options: --makedep=TMP/depfile --makedep-target=Target foo
> +@comment auxfile: TMP/depfile
> +@example
> +$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target foo}
> +@result{}bar
> +@auxresult{TMP/depfile}# Automatically generated by GNU m4.
I would prefer to see something like '$ @kbd{cat TMP/depfile}' before
introducing @auxresult{} information. On the other hand, once I did
that, the manual looks like this, and I'm thinking the subsequent
TMP/depfile leadins on the later lines are repetitive and the
monospace font leads to long lines (in the pdf view, it's less than 80
columns, but longer than the rest of the margins), so I may tweak it
further still:
| $ m4 -I examples --makedep=TMP/depfile --makedep-target=Target \
| --makedep-gen-missing-all foo none -
| ⇒bar
| error m4: cannot open 'none': No such file or directory
| include(`incl.m4')
| ⇒Include file start
| ⇒foo
| ⇒Include file end
| ⇒
| include(`none2')
| ⇒
| error m4:stdin:2: include: cannot open 'none2': No such file or directory
| sinclude(`none3')
| ⇒
| ^D
| $ cat TMP/depfile
| TMP/depfile ⇒# Automatically generated by GNU m4.
| TMP/depfile ⇒Target: ./../examples/foo none ./../examples/incl.m4 none2 none3
> +++ b/src/builtin.c
> @@ -1494,13 +1494,14 @@ m4_changecom (struct obstack *obs MAYBE_UNUSED, int
> argc,
> argument, if it exists. Complain about inaccessible files iff
> SILENT is false. */
> static void
> -include (int argc, macro_arguments *argv, bool silent)
> +include (int argc, macro_arguments *argv, bool silent, int ref_from)
> {
> const call_info *me = arg_info (argv);
> FILE *fp;
> char *name;
> const char *arg;
> size_t len;
> + int fail;
>
> if (bad_argc (me, argc, 1, 1))
> return;
> @@ -1513,12 +1514,21 @@ include (int argc, macro_arguments *argv, bool silent)
> fp = m4_path_search (arg, false, &name);
> if (fp == NULL)
> {
> + fail = !silent;
> + if ((makedep_gen_missing & ref_from) != 0)
> + {
> + record_dependency (arg, ref_from);
> + fail = 0;
> + }
> if (!silent)
> m4_error (0, errno, me, _("cannot open %s"),
> quotearg_style (locale_quoting_style, arg));
> + if (fail)
> + retcode = EXIT_FAILURE;
> return;
> }
>
> + record_dependency (name, ref_from);
> push_file (fp, name, true);
> free (name);
> }
> @@ -1527,7 +1537,7 @@ include (int argc, macro_arguments *argv, bool silent)
> static void
> m4_include (struct obstack *obs MAYBE_UNUSED, int argc, macro_arguments
> *argv)
> {
> - include (argc, argv, false);
> + include (argc, argv, false, REF_INCLUDE);
> }
>
> /* Include a file, ignoring errors. */
> @@ -1535,7 +1545,7 @@ static void
> m4_sinclude (struct obstack *obs MAYBE_UNUSED, int argc,
> macro_arguments *argv)
> {
> - include (argc, argv, true);
> + include (argc, argv, true, REF_SINCLUDE);
> }
>
> /* More miscellaneous builtins -- "maketemp", "errprint", "__file__",
> diff --git a/src/eval.c b/src/eval.c
> index 69cd5e41..d91fa3cd 100644
> --- a/src/eval.c
> +++ b/src/eval.c
> @@ -431,6 +431,7 @@ parse_expr (int32_t *v1, eval_error er, unsigned min_prec)
> that the implementation-defined overflow when casting
> unsigned to signed is a silent twos-complement
> wrap-around. */
> + u3 = 1;
> if (v2 < 0)
> er = NEGATIVE_EXPONENT;
> else if (*v1 == 0 && v2 == 0)
This appears unrelated. But I can see how it silences a compiler
warning; I'll push that fix separately (actually, I'll probably pull
the assignment '*v1 = u3' into the conditional arm where u3 is already
set).
> diff --git a/src/m4.c b/src/m4.c
> index 89a2ec2f..aa2327a5 100644
> --- a/src/m4.c
> +++ b/src/m4.c
> @@ -333,6 +379,16 @@ enum
> {
> DEBUGFILE_OPTION = CHAR_MAX + 1, /* no short opt */
> WARN_MACRO_SEQUENCE_OPTION, /* no short opt */
> + MAKEDEP_OPTION, /* no short opt */
> + MAKEDEP_TARGET_OPTION, /* no short opt */
> + MAKEDEP_GEN_MISSING_ARGFILES_OPTION, /* no short opt */
> + MAKEDEP_GEN_MISSING_INCLUDE_OPTION, /* no short opt */
> + MAKEDEP_GEN_MISSING_SINCLUDE_OPTION, /* no short opt */
> + MAKEDEP_GEN_MISSING_ALL_OPTION, /* no short opt */
> + MAKEDEP_PHONY_ARGFILES_OPTION, /* no short opt */
> + MAKEDEP_PHONY_INCLUDE_OPTION, /* no short opt */
> + MAKEDEP_PHONY_SINCLUDE_OPTION, /* no short opt */
> + MAKEDEP_PHONY_ALL_OPTION, /* no short opt */
>
> HELP_OPTION, /* no short opt */
> VERSION_OPTION /* no short opt */
Other than HELP and VERSION, it makes sense to try and keep this
section alphabetically sorted.
> @@ -659,6 +778,30 @@ main (int argc, char *const *argv, char *const *envp
> MAYBE_UNUSED)
> m4_error (0, errno, NULL, _("cannot set debug file %s"),
> quotearg_style (locale_quoting_style, debugfile));
>
> + /* Verify mutual consistency of makedep options. */
> + if ((makedep_path == NULL) && (makedep_target == NULL))
I think this looks better as "if (!makedep_path && !makedep_target)"
> + {
> + /* Makedep mode is NOT active. */
> + if (makedep_gen_missing != 0)
> + m4_error (0, 0, NULL,
> + _("--makedep-gen-missing-* requires --makedep and
> --makedep-target"));
> + if (makedep_phony != 0)
> + m4_error (0, 0, NULL,
> + _("--makedep-phony-* requires --makedep and
> --makedep-target"));
> + if ((makedep_gen_missing | makedep_phony) != 0)
> + exit (EXIT_FAILURE);
> + }
> + else if ((makedep_path != NULL) && (makedep_target != NULL))
and "if (makedep_path && makedep_target)"
...
> +++ b/src/path.c
> @@ -36,6 +36,18 @@ typedef struct includes includes;
> static includes *dir_list; /* the list of path directories */
> static includes *dir_list_end; /* the end of same */
> static int dir_max_length; /* length of longest directory name */
> +
> +struct dependency
> +{
> + struct dependency *next; /* next in list of dependencies */
> + int ref_from; /* bit mask: places file referenced from */
> + char *path; /* pathname of this dependency */
> +};
> +
> +typedef struct dependency dependency;
> +
> +static dependency *dependency_list; /* the list of dependencies */
> +static dependency *dependency_list_end; /* the end of same */
>
>
> void
> @@ -194,6 +206,74 @@ m4_path_search (const char *file, bool binary, char
> **result)
> return fp;
> }
>
> +void
> +record_dependency (const char *path, int ref_from)
> +{
> + dependency *dp;
> + for (dp = dependency_list; dp != NULL; dp = dp->next)
> + if (strcmp (path, dp->path) == 0)
There is the STREQ macro for this.
> +
> +void
> +generate_make_dependencies (const char *path, const char *target, int phony)
> +{
> + FILE *fp;
> + size_t col, len, maxcol;
> + dependency *dp;
> +
> + fp = fopen (path, "w");
> + if (fp == NULL)
> + {
> + m4_error (0, errno, NULL, _("unable to open %s"),
> + quotearg_style_mem (locale_quoting_style,
> + path, strlen (path)));
> + return;
> + }
> +
> + fputs (_("# Automatically generated by GNU m4.\n"), fp);
Should this include the M4 version number?
> +
> + /* Generate the main dependency rule. */
> + maxcol = 78;
> + fprintf (fp, "%s:", target);
> + col = strlen (target) + 1;
> + for (dp = dependency_list; dp != NULL; dp = dp->next)
> + {
> + len = 1 + strlen (dp->path);
> + if (col + len + 2 > maxcol) /* +2 is for trailing space/backslash */
> + {
> + fprintf (fp," \\\n ");
fprintf() is overkill when there are no % directives.
All told, here's what I'm squashing in. I've pushed the patch to the
makedep branch for now, and will merge it to branch-1.6 once I've had
another read through it.
From bb0cd0053d1e467d61660d97b38bce9326e9ec98 Mon Sep 17 00:00:00 2001
From: Eric Blake <[email protected]>
Date: Sun, 25 May 2025 21:02:53 -0500
Subject: [PATCH branch-1.6] squash me
Content-type: text/plain
---
NEWS | 10 +-
checks/check-them | 17 +--
doc/m4.texi | 380 +++++++++++++++++++++++-----------------------
src/m4.c | 32 ++--
src/m4.h | 2 +-
src/path.c | 10 +-
6 files changed, 232 insertions(+), 219 deletions(-)
diff --git a/NEWS b/NEWS
index f2861faa..6bbb347e 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,14 @@ GNU M4 NEWS - User visible changes.
* Noteworthy changes in Version 1.6 (????-??-??) [stable]
Released by ????, based on git versions 1.4.10b.x-* and 1.5.*
+** Add new capability to automatically generate make dependency rules.
+ This is enabled by the new command-line option pair '--makedep=FILE'
+ and '--makedep-target=TARGET' and further tuned by
+ '--makedep-gen-missing-argfiles', '--makedep-gen-missing-include',
+ '--makedep-gen-missing-sinclude', '--makedep-gen-missing-all',
+ '--makedep-phony-argfiles', '--makedep-phony-include',
+ '--makedep-phony-sinclude', and '--makedep-phony-all'.
+
** Fix regressions introduced in 1.4.10b:
*** Using `builtin' or `indir' to perform nested `shift' calls triggered
an assertion failure (not present in 1.4.11).
@@ -193,8 +201,6 @@ following beta features that were deemed worth deferring
until 1.6:
* Noteworthy changes in release 1.4.19 (2021-05-28) [stable]
-** Add new capability to automatically generate make dependency rules.
-
** A number of portability improvements inherited from gnulib, including
the ability to perform stack overflow detection on more platforms
without linking to GNU libsigsegv.
diff --git a/checks/check-them b/checks/check-them
index 09c7c14f..0b283134 100755
--- a/checks/check-them
+++ b/checks/check-them
@@ -98,15 +98,15 @@ do
*stackovf.test)
"$file" "$m4"
case $? in
- 77) skipped="$skipped $file";;
- 0) ;;
- *) failed="$failed $file"
+ 77) skipped="$skipped $file";;
+ 0) ;;
+ *) failed="$failed $file"
esac
continue ;;
esac
- options=`${SED} -ne '3s/^dnl @ extra options: //p;3q' "$file" \
- | ${SED} -e "s/TMP\//$tmp\//"`
+ options=`${SED} -ne "3 { s|TMP/|$tmp/|g; s/^dnl @ extra options: //p; q }" \
+ "$file"`
${SED} -e '/^dnl @/d' -e '/^\^D$/q' "$file" \
| LC_MESSAGES=C LANG=C M4PATH=$examples "$m4" -d $options - >$out 2>$err
stat=$?
@@ -128,9 +128,8 @@ do
xoutfile=`${SED} -n 's/^dnl @ expected output: //p' "$file"`
if test -z "$xoutfile" ; then
- ${SED} -ne 's/^dnl @result{}//p' "$file" \
- | ${SED} -e "s|examples/|$examples/|" \
- -e "s|@value{VERSION}|$m4version|" > $xout
+ ${SED} -e '/^dnl @result{}/!d' -e 's///' -e "s|examples/|$examples/|" \
+ -e "s|@value{VERSION}|$m4version|" "$file" > $xout
else
cp "$examples/$xoutfile" $xout
fi
@@ -185,7 +184,7 @@ do
fi
if test -n "$auxfile"; then
- tauxfile=`echo "$auxfile" | ${SED} -e "s/TMP\//$tmp\//"`
+ tauxfile=`echo "$auxfile" | ${SED} -e "s|TMP/|$tmp/|g"`
if test -f "$tauxfile"; then
${SED} -ne 's|^dnl @auxresult{[A-Za-z0-9_/]*}||p' < $file >$xaux
if $strip_needed ; then
diff --git a/doc/m4.texi b/doc/m4.texi
index bcd5ae45..72281ef3 100644
--- a/doc/m4.texi
+++ b/doc/m4.texi
@@ -39,7 +39,7 @@
@c @auxresult{auxfile}
@c ------------
@c Used in examples to indicate output produced within the
-@c ``auxilliary output file.''
+@c ``auxiliary output file.''
@macro auxresult{auxfile}
\auxfile\ @b{@result{}}
@end macro
@@ -154,9 +154,9 @@ Top
* Operation modes:: Command line options for operation modes
* Preprocessor features:: Command line options for preprocessor features
+* Make dependency generation:: Generating make dependency rules
* Limits control:: Command line options for limits control
* Frozen state:: Command line options for frozen state
-* Make dependency generation:: Generating make dependency rules
* Debugging options:: Command line options for debugging
* Command line files:: Specifying input files on the command line
@@ -590,9 +590,9 @@ Invoking m4
@menu
* Operation modes:: Command line options for operation modes
* Preprocessor features:: Command line options for preprocessor features
+* Make dependency generation:: Generating make dependency rules
* Limits control:: Command line options for limits control
* Frozen state:: Command line options for frozen state
-* Make dependency generation:: Generating make dependency rules
* Debugging options:: Command line options for debugging
* Command line files:: Specifying input files on the command line
@end menu
@@ -807,6 +807,195 @@ Preprocessor features
file names.
@end table
+@node Make dependency generation
+@section Command line options for generating Makefile dependency rules
+
+Makefile dependency rules can be automatically generated by specifying
+both the @code{--makedep=}@var{file} and
+@code{--makedep-target=}@var{target} options.
+
+@table @code
+@item --makedep=@var{file}
+Causes @code{m4} to generate a dependency rule into the specified
+@var{file}. Macro expansion output is still written to stdout as
+normal. This option is analogous to the @code{-MF} option of
+@code{gcc}.
+
+@item --makedep-target=@var{target}
+Specifies @var{target} to be the target of the generated dependency
+rule. The string @var{target} is used verbatim, and can contain several
+logical targets separated by spaces. It is the user's responsibility to
+properly express characters that @code{make} handles specially (such as
+'@code{$}', or spaces within file names). Since @code{m4} sends its
+macro expansion output to stdout, it never really knows the name of the
+target file being generated, so the target must always be specified
+explicitly by the user with this option. This option is analogous to
+the @code{-MT} option of @code{gcc} (except that @code{gcc} allows
+@code{-MT} to be specified multiple times).
+@end table
+
+Note that the @code{--makedep=}@var{file} and
+@code{makedep-target=}@var{target} options must either (a) both be
+specified, or (b) neither be specified. They cannot be used
+independently of each other.
+
+@comment options: --makedep=TMP/depfile --makedep-target=Target foo
+@comment auxfile: TMP/depfile
+@example
+$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target foo}
+@result{}bar
+$ @kbd{cat TMP/depfile}
+@auxresult{TMP/depfile}# Automatically generated by GNU m4.
+@auxresult{TMP/depfile}Target: ./../examples/foo
+@end example
+
+@comment Separate these two examples.
+@sp 1
+
+@comment options: --makedep=TMP/depfile --makedep-target=Target foo
+@comment auxfile: TMP/depfile
+@example
+$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target foo -}
+@result{}bar
+include(`incl.m4')
+@result{}Include file start
+@result{}foo
+@result{}Include file end
+@result{}
+^D
+$ @kbd{cat TMP/depfile}
+@auxresult{TMP/depfile}# Automatically generated by GNU m4.
+@auxresult{TMP/depfile}Target: ./../examples/foo ./../examples/incl.m4
+@end example
+
+The following additional options can also be used when dependency rules
+are being generated (these options are only valid when both
+@code{makedep=}@var{file} and @code{makedep-target=}@var{target} have
+also been specified):
+
+@table @code
+@item --makedep-gen-missing-argfiles
+Causes @code{m4} to assume that any file listed on the command line that
+is missing (i.e., does not exist) is an automatically generated file.
+@code{M4} includes such missing files as dependencies in the generated
+rule regardless. In this case the dependency appears exactly as
+specified on the command line and is not modified by any
+@code{-I}@var{searchdir} prefixes. Note that the macro expansion output
+generated to stdout will be incorrect when this happens because the
+missing file is assumed to be an empty file. A warning is produced on
+stderr for each missing command line file handled in this manner.
+
+@item --makedep-gen-missing-include
+Causes @code{m4} to assume that any file included via the
+@code{include()} macro that is missing (i.e., does not exist) is an
+automatically generated file. @code{M4} includes such missing files as
+dependencies in the generated rule regardless. In this case the
+dependency appears exactly as specified in the argument to
+@code{include()} and is not modified by any @code{-I}@var{searchdir}
+prefixes. Note that the macro expansion output generated to stdout will
+be incorrect when this happens because the missing file is assumed to be
+an empty file. This option causes the @code{m4} @code{include()} macro
+to behave like @code{sinclude()}, except that a warning message is
+produced on stderr to indicate that the requested file was missing.
+This option is analogous to the @code{-MG} option of @code{gcc}.
+
+@item --makedep-gen-missing-sinclude
+Causes @code{m4} to assume that any file included via the
+@code{sinclude()} macro that is missing (i.e., does not exist) is an
+automatically generated file. @code{M4} includes such missing files as
+dependencies in the generated rule regardless. In this case the
+dependency appears exactly as specified in the argument to
+@code{sinclude()} and is not modified by any @code{-I}@var{searchdir}
+prefixes. Note that the macro expansion output generated to stdout will
+be incorrect when this happens because the missing file is assumed to be
+an empty file. This option does not alter @code{sinclude()}'s behavior
+of silently ignoring requests to @code{sinclude()} files that do not exist.
+
+@item --makedep-gen-missing-all
+This option is equivalent to specifying all three options
+@code{--makedep-gen-missing-argfiles},
+@code{--makedep-gen-missing-include} and
+@code{--makedep-gen-missing-sinclude}.
+@end table
+
+Note that the above @code{makedep-gen-missing-*} options assume that the
+missing files will ultimately not @code{include()} or @code{sinclude()}
+any additional files -- if they do, then these additional files will be
+missing from the generated dependency rules.
+
+
+@comment status: 1
+@comment options: --makedep=TMP/depfile --makedep-target=Target
--makedep-gen-missing-all foo none
+@comment auxfile: TMP/depfile
+@example
+$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target \}
+@kbd{ --makedep-gen-missing-all foo none -}
+@result{}bar
+@error{}m4: cannot open 'none': No such file or directory
+include(`incl.m4')
+@result{}Include file start
+@result{}foo
+@result{}Include file end
+@result{}
+include(`none2')
+@result{}
+@error{}m4:stdin:2: include: cannot open 'none2': No such file or directory
+sinclude(`none3')
+@result{}
+^D
+$ @kbd{cat TMP/depfile}
+@auxresult{TMP/depfile}# Automatically generated by GNU m4.
+@auxresult{TMP/depfile}Target: ./../examples/foo none ./../examples/incl.m4
none2 none3
+@end example
+
+The following options control the generation of ``phony'' targets for
+certain classes of dependencies. These dummy rules are used to work
+around errors @code{make} gives if you remove files without updating the
+@code{Makefile} to match. Dependencies that match one or more of these
+classes cause a single dummy rule to be generated for them:
+
+@table @code
+@item --makedep-phony-argfiles
+Causes @code{m4} to generate a ``phony'' target for each file that is
+specified on the command line.
+
+@item --makedep-phony-include
+Causes @code{m4} to generate a ``phony'' target for each file that is
+the subject of an @code{include()} macro. This option is analogous to
+the @code{-MP} option of @code{gcc}.
+
+@item --makedep-phony-sinclude
+Causes @code{m4} to generate a ``phony'' target for each file that is
+the subject of an @code{sinclude()} macro.
+
+@item --makedep-phony-all
+is equivalent to specifying all three options:
+@code{--makedep-phony-argfiles}
+@code{--makedep-phony-include}
+@code{--makedep-phony-sinclude}.
+@end table
+
+@comment options: --makedep=TMP/depfile --makedep-target=Target
--makedep-phony-all foo
+@comment auxfile: TMP/depfile
+@example
+$ @kbd{m4 -I examples --makdep=TMP/depfile --makedep-target=Target \}
+@kbd{ --makedep-phony-all foo -}
+@result{}bar
+include(`incl.m4')
+@result{}Include file start
+@result{}foo
+@result{}Include file end
+@result{}
+^D
+$ @kbd{cat TMP/depfile}
+@auxresult{TMP/depfile}# Automatically generated by GNU m4.
+@auxresult{TMP/depfile}Target: ./../examples/foo ./../examples/incl.m4
+@auxresult{TMP/depfile}
+@auxresult{TMP/depfile}./../examples/foo:
+@auxresult{TMP/depfile}
+@auxresult{TMP/depfile}./../examples/incl.m4:
+@end example
+
@node Limits control
@section Command line options for limits control
@@ -914,191 +1103,6 @@ Frozen state
files are read.
@end table
-@node Make dependency generation
-@section Command line options for generating Makefile dependency rules
-
-Makefile dependency rules can be automatically generated by specifying
-both the @code{--makedep=}@var{file} and
-@code{--makedep-target=}@var{target} options.
-
-@table @code
-@item --makedep=@var{file}
-Causes @code{m4} to generate a dependency rule into the specified
-@var{file}. Macro expansion output is still written to stdout as
-normal. This option is analogous to the @code{-MF} option of
-@code{gcc}.
-
-@item --makedep-target=@var{target}
-Specifies @var{target} to be the target of the generated dependency
-rule. The string @var{target} is used verbatim, and can contain several
-logical targets separated by spaces. It is the user's responsibility to
-properly express characters that @code{make} handles specially (such as
-'@code{$}', or spaces within file names). Since @code{m4} sends its
-macro expansion output to stdout, it never really knows the name of the
-target file being generated, so the target must always be specified
-explicitly by the user with this option. This option is analogous to
-the @code{-MT} option of @code{gcc} (except that @code{gcc} allows
-@code{-MT} to be specified multiple times).
-@end table
-
-Note that the @code{--makedep=}@var{file} and
-@code{makedep-target=}@var{target} options must either (a) both be
-specified, or (b) neither be specified. They cannot be used
-independently of each other.
-
-@comment options: --makedep=TMP/depfile --makedep-target=Target foo
-@comment auxfile: TMP/depfile
-@example
-$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target foo}
-@result{}bar
-@auxresult{TMP/depfile}# Automatically generated by GNU m4.
-@auxresult{TMP/depfile}Target: ./../examples/foo
-@end example
-
-@comment Separate these two examples.
-@sp 1
-
-@comment options: --makedep=TMP/depfile --makedep-target=Target foo
-@comment auxfile: TMP/depfile
-@example
-$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target foo -}
-@result{}bar
-include(`incl.m4')
-@result{}Include file start
-@result{}foo
-@result{}Include file end
-@result{}
-^D
-@auxresult{TMP/depfile}# Automatically generated by GNU m4.
-@auxresult{TMP/depfile}Target: ./../examples/foo ./../examples/incl.m4
-@end example
-
-The following additional options can also be used when dependency rules
-are being generated (these options are only valid when both
-@code{makedep=}@var{file} and @code{makedep-target=}@var{target} have
-also been specified):
-
-@table @code
-@item --makedep-gen-missing-argfiles
-Causes @code{m4} to assume that any file listed on the command line that
-is missing (i.e., does not exist) is an automatically generated file.
-@code{M4} includes such missing files as dependencies in the generated
-rule regardless. In this case the dependency appears exactly as
-specified on the command line and is not modified by any
-@code{-I}@var{searchdir} prefixes. Note that the macro expansion output
-generated to stdout will be incorrect when this happens because the
-missing file is assumed to be an empty file. A warning is produced on
-stderr for each missing command line file handled in this manner.
-
-@item --makedep-gen-missing-include
-Causes @code{m4} to assume that any file included via the
-@code{include()} macro that is missing (i.e., does not exist) is an
-automatically generated file. @code{M4} includes such missing files as
-dependencies in the generated rule regardless. In this case the
-dependency appears exactly as specified in the argument to
-@code{include()} and is not modified by any @code{-I}@var{searchdir}
-prefixes. Note that the macro expansion output generated to stdout will
-be incorrect when this happens because the missing file is assumed to be
-an empty file. This option causes the @code{m4} @code{include()} macro
-to behave like @code{sinclude()}, except that a warning message is
-produced on stderr to indicate that the requested file was missing.
-This option is analogous to the @code{-MG} option of @code{gcc}.
-
-@item --makedep-gen-missing-sinclude
-Causes @code{m4} to assume that any file included via the
-@code{sinclude()} macro that is missing (i.e., does not exist) is an
-automatically generated file. @code{M4} includes such missing files as
-dependencies in the generated rule regardless. In this case the
-dependency appears exactly as specified in the argument to
-@code{sinclude()} and is not modified by any @code{-I}@var{searchdir}
-prefixes. Note that the macro expansion output generated to stdout will
-be incorrect when this happens because the missing file is assumed to be
-an empty file. This option does not alter @code{sinclude()}'s behavior
-of silently ignoring requests to @code{sinclude()} files that do not exist.
-
-@item --makedep-gen-missing-all
-This option is equivalent to specifying all three options
-@code{--makedep-gen-missing-argfiles},
-@code{--makedep-gen-missing-include} and
-@code{--makedep-gen-missing-sinclude}.
-@end table
-
-Note that the above @code{makedep-gen-missing-*} options assume that the
-missing files will ultimately not @code{include()} or @code{sinclude()}
-any additional files -- if they do, then these additional files will be
-missing from the generated dependency rules.
-
-
-@comment status: 1
-@comment options: --makedep=TMP/depfile --makedep-target=Target
--makedep-gen-missing-all foo none
-@comment auxfile: TMP/depfile
-@example
-$ @kbd{m4 -I examples --makedep=TMP/depfile --makedep-target=Target \}
-@kbd{ --makedep-gen-missing-all foo none -}
-@result{}bar
-@error{}m4: cannot open 'none': No such file or directory
-include(`incl.m4')
-@result{}Include file start
-@result{}foo
-@result{}Include file end
-@result{}
-include(`none2')
-@result{}
-@error{}m4:stdin:2: include: cannot open 'none2': No such file or directory
-sinclude(`none3')
-@result{}
-^D
-@auxresult{TMP/depfile}# Automatically generated by GNU m4.
-@auxresult{TMP/depfile}Target: ./../examples/foo none ./../examples/incl.m4
none2 none3
-@end example
-
-The following options control the generation of ``phony'' targets for
-certain classes of dependencies. These dummy rules are used to work
-around errors @code{make} gives if you remove files without updating the
-@code{Makefile} to match. Dependencies that match one or more of these
-classes cause a single dummy rule to be generated for them:
-
-@table @code
-@item --makedep-phony-argfiles
-Causes @code{m4} to generate a ``phony'' target for each file that is
-specified on the command line.
-
-@item --makedep-phony-include
-Causes @code{m4} to generate a ``phony'' target for each file that is
-the subject of an @code{include()} macro. This option is analogous to
-the @code{-MP} option of @code{gcc}.
-
-@item --makedep-phony-sinclude
-Causes @code{m4} to generate a ``phony'' target for each file that is
-the subject of an @code{sinclude()} macro.
-
-@item --makedep-phony-all
-is equivalent to specifying all three options:
-@code{--makedep-phony-argfiles}
-@code{--makedep-phony-include}
-@code{--makedep-phony-sinclude}.
-@end table
-
-@comment options: --makedep=TMP/depfile --makedep-target=Target
--makedep-phony-all foo
-@comment auxfile: TMP/depfile
-@example
-$ @kbd{m4 -I examples --makdep=TMP/depfile --makedep-target=Target \}
-@kbd{ --makedep-phony-all foo -}
-@result{}bar
-include(`incl.m4')
-@result{}Include file start
-@result{}foo
-@result{}Include file end
-@result{}
-^D
-@auxresult{TMP/depfile}# Automatically generated by GNU m4.
-@auxresult{TMP/depfile}Target: ./../examples/foo ./../examples/incl.m4
-@auxresult{TMP/depfile}
-@auxresult{TMP/depfile}./../examples/foo:
-@auxresult{TMP/depfile}
-@auxresult{TMP/depfile}./../examples/incl.m4:
-@end example
-
@node Debugging options
@section Command line options for debugging
diff --git a/src/m4.c b/src/m4.c
index aa2327a5..9f6c5f3b 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -378,17 +378,17 @@ mismatch, or whatever value was passed to the m4exit
macro.\n\
enum
{
DEBUGFILE_OPTION = CHAR_MAX + 1, /* no short opt */
- WARN_MACRO_SEQUENCE_OPTION, /* no short opt */
- MAKEDEP_OPTION, /* no short opt */
- MAKEDEP_TARGET_OPTION, /* no short opt */
+ MAKEDEP_OPTION, /* no short opt */
+ MAKEDEP_TARGET_OPTION, /* no short opt */
MAKEDEP_GEN_MISSING_ARGFILES_OPTION, /* no short opt */
MAKEDEP_GEN_MISSING_INCLUDE_OPTION, /* no short opt */
MAKEDEP_GEN_MISSING_SINCLUDE_OPTION, /* no short opt */
MAKEDEP_GEN_MISSING_ALL_OPTION, /* no short opt */
MAKEDEP_PHONY_ARGFILES_OPTION, /* no short opt */
- MAKEDEP_PHONY_INCLUDE_OPTION, /* no short opt */
+ MAKEDEP_PHONY_INCLUDE_OPTION, /* no short opt */
MAKEDEP_PHONY_SINCLUDE_OPTION, /* no short opt */
- MAKEDEP_PHONY_ALL_OPTION, /* no short opt */
+ MAKEDEP_PHONY_ALL_OPTION, /* no short opt */
+ WARN_MACRO_SEQUENCE_OPTION, /* no short opt */
HELP_OPTION, /* no short opt */
VERSION_OPTION /* no short opt */
@@ -424,16 +424,18 @@ static const struct option long_options[] = {
{"makedep", required_argument, NULL, MAKEDEP_OPTION},
{"makedep-target", required_argument, NULL, MAKEDEP_TARGET_OPTION},
{"makedep-gen-missing-argfiles", no_argument, NULL,
- MAKEDEP_GEN_MISSING_ARGFILES_OPTION},
+ MAKEDEP_GEN_MISSING_ARGFILES_OPTION},
{"makedep-gen-missing-include", no_argument, NULL,
- MAKEDEP_GEN_MISSING_INCLUDE_OPTION},
+ MAKEDEP_GEN_MISSING_INCLUDE_OPTION},
{"makedep-gen-missing-sinclude", no_argument, NULL,
- MAKEDEP_GEN_MISSING_SINCLUDE_OPTION},
+ MAKEDEP_GEN_MISSING_SINCLUDE_OPTION},
{"makedep-gen-missing-all", no_argument, NULL,
- MAKEDEP_GEN_MISSING_ALL_OPTION},
- {"makedep-phony-argfiles", no_argument, NULL, MAKEDEP_PHONY_ARGFILES_OPTION},
+ MAKEDEP_GEN_MISSING_ALL_OPTION},
+ {"makedep-phony-argfiles", no_argument, NULL,
+ MAKEDEP_PHONY_ARGFILES_OPTION},
{"makedep-phony-include", no_argument, NULL, MAKEDEP_PHONY_INCLUDE_OPTION},
- {"makedep-phony-sinclude", no_argument, NULL, MAKEDEP_PHONY_SINCLUDE_OPTION},
+ {"makedep-phony-sinclude", no_argument, NULL,
+ MAKEDEP_PHONY_SINCLUDE_OPTION},
{"makedep-phony-all", no_argument, NULL, MAKEDEP_PHONY_ALL_OPTION},
{"help", no_argument, NULL, HELP_OPTION},
@@ -716,7 +718,7 @@ main (int argc, char *const *argv, char *const *envp
MAYBE_UNUSED)
(which disables these warnings). */
macro_sequence = optarg;
break;
-
+
case MAKEDEP_OPTION:
if (makedep_path != NULL)
usage (EXIT_FAILURE);
@@ -784,10 +786,12 @@ main (int argc, char *const *argv, char *const *envp
MAYBE_UNUSED)
/* Makedep mode is NOT active. */
if (makedep_gen_missing != 0)
m4_error (0, 0, NULL,
- _("--makedep-gen-missing-* requires --makedep and
--makedep-target"));
+ _("--makedep-gen-missing-* requires --makedep and "
+ "--makedep-target"));
if (makedep_phony != 0)
m4_error (0, 0, NULL,
- _("--makedep-phony-* requires --makedep and
--makedep-target"));
+ _("--makedep-phony-* requires --makedep and "
+ "--makedep-target"));
if ((makedep_gen_missing | makedep_phony) != 0)
exit (EXIT_FAILURE);
}
diff --git a/src/m4.h b/src/m4.h
index d2d5c3f6..5eb02962 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -94,7 +94,7 @@
# undef bindtextdomain
# define bindtextdomain(Domainname, Dirname) /* empty */
#endif
-extern int makedep_gen_missing; /* --makedep-gen-missing-* */
+extern int makedep_gen_missing; /* --makedep-gen-missing-* */
/* Bit masks indicating places a file is referenced from. */
#define REF_CMD_LINE 0x01 /* File referenced from command line */
diff --git a/src/path.c b/src/path.c
index 93bd08d2..4dab4bd1 100644
--- a/src/path.c
+++ b/src/path.c
@@ -36,7 +36,7 @@ typedef struct includes includes;
static includes *dir_list; /* the list of path directories */
static includes *dir_list_end; /* the end of same */
static int dir_max_length; /* length of longest directory name */
-
+
struct dependency
{
struct dependency *next; /* next in list of dependencies */
@@ -211,7 +211,7 @@ record_dependency (const char *path, int ref_from)
{
dependency *dp;
for (dp = dependency_list; dp != NULL; dp = dp->next)
- if (strcmp (path, dp->path) == 0)
+ if (STREQ (path, dp->path))
{
/* Remember all the places this file has been referenced from. */
dp->ref_from |= ref_from;
@@ -255,15 +255,15 @@ generate_make_dependencies (const char *path, const char
*target, int phony)
for (dp = dependency_list; dp != NULL; dp = dp->next)
{
len = 1 + strlen (dp->path);
- if (col + len + 2 > maxcol) /* +2 is for trailing space/backslash */
+ if (col + len + 2 > maxcol) /* +2 for trailing space/backslash */
{
- fprintf (fp," \\\n ");
+ fputs (" \\\n ", fp);
col = 1;
}
fprintf (fp, " %s", dp->path);
col += len;
}
- fprintf (fp, "\n");
+ fputc ('\n', fp);
/* Generate phony targets for user-specified subset of dependencies. */
if (phony != 0)
--
2.49.0
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization: qemu.org | libguestfs.org
_______________________________________________
M4-patches mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/m4-patches