m4: Support long options.

The option names are identical to those of the equivalent options in GNU m4, except of course for --gnu which does not exist in GNU m4.

While here, make the argument to -d / --debug optional, with the same default behavior as in GNU m4, and document it properly.

Sponsored by:	Klara, Inc.
Reviewed by:	kevans, imp
Differential Revision:	https://reviews.freebsd.org/D40694
This commit is contained in:
Dag-Erling Smørgrav 2023-06-21 20:58:40 +00:00
parent 02b885b09d
commit 47b32f8f93
2 changed files with 44 additions and 17 deletions

View file

@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 8, 2021
.Dd June 21, 2023
.Dt M4 1
.Os
.Sh NAME
@ -47,7 +47,7 @@
.Fl D Ar name Op No = Ar value
.Sm on
.Oc
.Op Fl d Ar flags
.Op Fl d Oo Oo +- Oc Ns Ar flags Oc
.Op Fl I Ar dirname
.Op Fl o Ar filename
.Op Fl t Ar macro
@ -98,15 +98,14 @@ recognized as special when not followed by an open parenthesis.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl D Ns Ar name Ns Op = Ns Ar value
.It Fl D Ns Ar name Ns Oo = Ns Ar value Oc , Fl -define Ns = Ns Ar name Ns Oo = Ns Ar value Oc
Define the symbol
.Ar name
to have some value (or
.Dv NULL ) .
.It Fl d Ar "flags"
Set trace flags.
.Ar flags
may hold the following:
.It Fl d Oo Oo +|- Oc Ns Ar flags Oc , Fl -debug Ns = Ns Oo Oo +|- Oc Ns Ar flags Oc
Set or unset trace flags.
The trace flags are as follows:
.Bl -tag -width Ds
.It Ar a
print macro arguments.
@ -128,9 +127,21 @@ number macro expansions.
turn on all options.
.El
.Pp
If
.Qq +
or
.Qq -
is used, the specified flags are added to or removed from the set of
active trace flags, respectively; otherwise, the specified flags
replace the set of active trace flags.
.Pp
Specifying this option without an argument is equivalent to specifying
it with the argument
.Qq aeq .
.Pp
By default, trace is set to
.Qq eq .
.It Fl E
.It Fl E , Fl -fatal-warnings
Set warnings to be fatal.
When a single
.Fl E
@ -145,7 +156,7 @@ first warning and
.Nm
will exit with a non-zero exit status.
This behaviour matches GNU-m4 1.4.9 and later.
.It Fl g
.It Fl g , Fl -gnu
Activate GNU-m4 compatibility mode.
In this mode, translit handles simple character
ranges (e.g., a-z), regular expressions mimic emacs behavior,
@ -155,27 +166,27 @@ empty names for macro definitions are allowed,
and eval understands
.Sq 0rbase:value
numbers.
.It Fl I Ar "dirname"
.It Fl I Ar dirname , Fl -include Ns = Ns Ar dirname
Add directory
.Ar dirname
to the include path.
.It Fl o Ar filename
.It Fl o Ar filename , Fl -error-output Ns = Ns Ar filename
Send trace output to
.Ar filename .
.It Fl P
.It Fl P , Fl -prefix-builtins
Prefix all built-in macros with
.Sq m4_ .
For example, instead of writing
.Ic define ,
use
.Ic m4_define .
.It Fl s
.It Fl s , Fl -synclines
Output line synchronization directives, suitable for
.Xr cpp 1 .
.It Fl t Ar macro
.It Fl t Ar macro , Fl -trace Ns = Ns Ar macro
Turn tracing on for
.Ar macro .
.It Fl "U" Ns Ar "name"
.It Fl U Ns Ar name , Fl -undefine Ns = Ns Ar name
Undefine the symbol
.Ar name .
.El

View file

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <signal.h>
#include <err.h>
#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
@ -60,6 +61,21 @@ __FBSDID("$FreeBSD$");
#include "extern.h"
#include "pathnames.h"
static const char *shortopts = "+D:d::EgI:o:Pst:U:";
static const struct option longopts[] = {
{ "define", required_argument, NULL, 'D' },
{ "debug", optional_argument, NULL, 'd' },
{ "fatal-warnings", no_argument, NULL, 'E' },
{ "gnu", no_argument, NULL, 'g' },
{ "include", required_argument, NULL, 'I' },
{ "error-output", required_argument, NULL, 'o' },
{ "prefix-builtins", no_argument, NULL, 'P' },
{ "synclines", no_argument, NULL, 's' },
{ "trace", required_argument, NULL, 't' },
{ "undefine", required_argument, NULL, 'U' },
{ NULL, 0, NULL, 0 },
};
stae *mstack; /* stack of m4 machine */
char *sstack; /* shadow stack, for string space extension */
static size_t STACKMAX; /* current maximum size of stack */
@ -188,7 +204,7 @@ main(int argc, char *argv[])
outfile = NULL;
resizedivs(MAXOUT);
while ((c = getopt(argc, argv, "gst:d:D:EU:o:I:P")) != -1)
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1)
switch(c) {
case 'D': /* define something..*/
@ -218,7 +234,7 @@ main(int argc, char *argv[])
mimic_gnu = 1;
break;
case 'd':
set_trace_flags(optarg);
set_trace_flags(optarg ? optarg : "aeq");
break;
case 's':
synch_lines = 1;