From d2d86e25c80bcf0b9408e1247f2418fab9082129 Mon Sep 17 00:00:00 2001 From: bcallah Date: Thu, 15 Jun 2017 13:48:42 +0000 Subject: [PATCH] Add -E flag (make warnings fatal), following the behavior of GNU m4 1.4.9+ Help and direction millert@ espie@ anton@ deraadt@ ok espie@ --- regress/usr.bin/m4/Makefile | 10 ++++++++-- regress/usr.bin/m4/fatalwarnings.m4 | 3 +++ regress/usr.bin/m4/fatalwarnings.out | 1 + usr.bin/m4/eval.c | 6 +++++- usr.bin/m4/extern.h | 6 +++++- usr.bin/m4/gnum4.c | 29 +++++++++++++++++++++++----- usr.bin/m4/m4.1 | 25 +++++++++++++++++++----- usr.bin/m4/main.c | 12 ++++++++++-- usr.bin/m4/misc.c | 6 +++--- usr.bin/m4/tokenizer.l | 13 ++++++------- 10 files changed, 85 insertions(+), 26 deletions(-) create mode 100644 regress/usr.bin/m4/fatalwarnings.m4 create mode 100644 regress/usr.bin/m4/fatalwarnings.out diff --git a/regress/usr.bin/m4/Makefile b/regress/usr.bin/m4/Makefile index 04845d90411..08143728057 100644 --- a/regress/usr.bin/m4/Makefile +++ b/regress/usr.bin/m4/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.32 2016/11/01 00:35:34 tb Exp $ +# $OpenBSD: Makefile,v 1.33 2017/06/15 13:48:42 bcallah Exp $ FIBOMAX=25 M4=m4 @@ -13,7 +13,7 @@ REGRESS_TARGETS= test-ff_after_dnl test-m4wrap test-m4wrap2 \ test-gnupatterns2 test-comments test-synch1 test-synch1bis \ test-gnuformat test-includes test-dumpdef test-gnuprefix \ test-translit test-translit2 test-gnutranslit2 \ - test-gnueval test-gnusofterror + test-gnueval test-gnusofterror test-fatalwarnings test-fatalwarnings2 test-ff_after_dnl: ff_after_dnl.m4 ${M4} ff_after_dnl.m4 | diff - ${.CURDIR}/ff_after_dnl.out @@ -120,6 +120,12 @@ test-gnusofterror: ${M4} -g ${.CURDIR}/gnusofterror.m4 2>/dev/null| diff -u - ${.CURDIR}/gnusofterror.out ! ${M4} -g ${.CURDIR}/gnusofterror.m4 2>/dev/null >/dev/null +test-fatalwarnings: + if ${M4} -E -g ${.CURDIR}/fatalwarnings.m4 >/dev/null 2>&1 || test $$? -ne 1; then false; fi + +test-fatalwarnings2: + ${M4} -E -E -g ${.CURDIR}/fatalwarnings.m4 2>&1 | diff -u - ${.CURDIR}/fatalwarnings.out + .PHONY: ${REGRESS_TARGETS} .include diff --git a/regress/usr.bin/m4/fatalwarnings.m4 b/regress/usr.bin/m4/fatalwarnings.m4 new file mode 100644 index 00000000000..66e007d9cec --- /dev/null +++ b/regress/usr.bin/m4/fatalwarnings.m4 @@ -0,0 +1,3 @@ +patsubst(`a') +patsubst(`b') +patsubst(`c') diff --git a/regress/usr.bin/m4/fatalwarnings.out b/regress/usr.bin/m4/fatalwarnings.out new file mode 100644 index 00000000000..a039270f21d --- /dev/null +++ b/regress/usr.bin/m4/fatalwarnings.out @@ -0,0 +1 @@ +m4: Too few arguments to patsubst diff --git a/usr.bin/m4/eval.c b/usr.bin/m4/eval.c index 18f2241a5db..0ce407b94e7 100644 --- a/usr.bin/m4/eval.c +++ b/usr.bin/m4/eval.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eval.c,v 1.74 2015/02/05 12:59:57 millert Exp $ */ +/* $OpenBSD: eval.c,v 1.75 2017/06/15 13:48:42 bcallah Exp $ */ /* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */ /* @@ -269,6 +269,10 @@ expand_builtin(const char *argv[], int argc, int td) warn("%s at line %lu: include(%s)", CURRENT_NAME, CURRENT_LINE, argv[2]); exit_code = 1; + if (fatal_warns) { + killdiv(); + exit(exit_code); + } } else err(1, "%s at line %lu: include(%s)", CURRENT_NAME, CURRENT_LINE, argv[2]); diff --git a/usr.bin/m4/extern.h b/usr.bin/m4/extern.h index d9cd64ba9f5..ea8406b8540 100644 --- a/usr.bin/m4/extern.h +++ b/usr.bin/m4/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.54 2014/05/12 19:11:19 espie Exp $ */ +/* $OpenBSD: extern.h,v 1.55 2017/06/15 13:48:42 bcallah Exp $ */ /* $NetBSD: extern.h,v 1.3 1996/01/13 23:25:24 pk Exp $ */ /*- @@ -58,6 +58,8 @@ extern void doesyscmd(const char *); extern void getdivfile(const char *); extern void doformat(const char *[], int); +extern void m4_warnx(const char *, ...); + /* look.c */ #define FLAG_UNTRACED 0 @@ -175,4 +177,6 @@ extern int synch_lines; /* line synchronisation directives */ extern int mimic_gnu; /* behaves like gnu-m4 */ extern int prefix_builtins; /* prefix builtin macros with m4_ */ +extern int error_warns; /* make warnings cause exit_code = 1 */ +extern int fatal_warns; /* make warnings fatal */ diff --git a/usr.bin/m4/gnum4.c b/usr.bin/m4/gnum4.c index 94d23496eac..4280cb97339 100644 --- a/usr.bin/m4/gnum4.c +++ b/usr.bin/m4/gnum4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gnum4.c,v 1.50 2015/04/29 00:13:26 millert Exp $ */ +/* $OpenBSD: gnum4.c,v 1.51 2017/06/15 13:48:42 bcallah Exp $ */ /* * Copyright (c) 1999 Marc Espie @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -234,7 +235,7 @@ addchar(int c) } static char * -getstring() +getstring(void) { addchar('\0'); current = 0; @@ -255,11 +256,29 @@ exit_regerror(int er, regex_t *re, const char *source) m4errx(1, "regular expression error in %s: %s.", source, errbuf); } +/* warnx() plus check to see if we need to change exit code or exit. + * -E flag functionality. + */ +void +m4_warnx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); + + if (fatal_warns) + exit(1); + if (error_warns) + exit_code = 1; +} + static void add_sub(int n, const char *string, regex_t *re, regmatch_t *pm) { if (n > re->re_nsub) - warnx("No subexpression %d", n); + m4_warnx("No subexpression %d", n); /* Subexpressions that did not match are * not an error. */ else if (pm[n].rm_so != -1 && @@ -442,7 +461,7 @@ void dopatsubst(const char *argv[], int argc) { if (argc <= 3) { - warnx("Too few arguments to patsubst"); + m4_warnx("Too few arguments to patsubst"); return; } /* special case: empty regexp */ @@ -494,7 +513,7 @@ doregexp(const char *argv[], int argc) const char *source; if (argc <= 3) { - warnx("Too few arguments to regexp"); + m4_warnx("Too few arguments to regexp"); return; } /* special gnu case */ diff --git a/usr.bin/m4/m4.1 b/usr.bin/m4/m4.1 index dcd9a38bacc..d389c158cc4 100644 --- a/usr.bin/m4/m4.1 +++ b/usr.bin/m4/m4.1 @@ -1,4 +1,4 @@ -.\" @(#) $OpenBSD: m4.1,v 1.63 2015/09/14 20:06:58 schwarze Exp $ +.\" @(#) $OpenBSD: m4.1,v 1.64 2017/06/15 13:48:42 bcallah Exp $ .\" .\" Copyright (c) 1989, 1993 .\" The Regents of the University of California. All rights reserved. @@ -30,7 +30,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: September 14 2015 $ +.Dd $Mdocdate: June 15 2017 $ .Dt M4 1 .Os .Sh NAME @@ -38,7 +38,7 @@ .Nd macro language processor .Sh SYNOPSIS .Nm -.Op Fl gPs +.Op Fl EgPs .Oo .Sm off .Fl D Ar name Op No = Ar value @@ -127,6 +127,19 @@ turn on all options. .Pp By default, trace is set to .Qq eq . +.It Fl E +Set warnings to be fatal. +When a single +.Fl E +flag is specified, if warnings are issued, execution continues but +.Nm +will exit with a non-zero exit status. +When multiple +.Fl E +flags are specified, execution will halt upon issuing the 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 Activate GNU-m4 compatibility mode. In this mode, translit handles simple character @@ -434,7 +447,9 @@ Returns the current file's name. .Pp But note that the .Ic m4exit -macro can modify the exit status. +macro can modify the exit status, as can the +.Fl E +flag. .Sh STANDARDS The .Nm @@ -443,7 +458,7 @@ utility is compliant with the specification. .Pp The flags -.Op Fl dgIPot +.Op Fl dEgIPot and the macros .Ic builtin , .Ic esyscmd , diff --git a/usr.bin/m4/main.c b/usr.bin/m4/main.c index 58e21676fa4..f1b8fa5a55b 100644 --- a/usr.bin/m4/main.c +++ b/usr.bin/m4/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.86 2015/11/03 16:21:47 deraadt Exp $ */ +/* $OpenBSD: main.c,v 1.87 2017/06/15 13:48:42 bcallah Exp $ */ /* $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $ */ /*- @@ -77,6 +77,8 @@ char scommt[MAXCCHARS+1] = {SCOMMT}; /* start character for comment */ char ecommt[MAXCCHARS+1] = {ECOMMT}; /* end character for comment */ int synch_lines = 0; /* line synchronisation for C preprocessor */ int prefix_builtins = 0; /* -P option to prefix builtin keywords */ +int error_warns = 0; /* -E option to make warnings exit_code = 1 */ +int fatal_warns = 0; /* -E -E option to make warnings fatal */ struct keyblk { char *knam; /* keyword name */ @@ -185,7 +187,7 @@ main(int argc, char *argv[]) outfile = NULL; resizedivs(MAXOUT); - while ((c = getopt(argc, argv, "gst:d:D:U:o:I:P")) != -1) + while ((c = getopt(argc, argv, "gst:d:D:EU:o:I:P")) != -1) switch(c) { case 'D': /* define something..*/ @@ -196,6 +198,12 @@ main(int argc, char *argv[]) *p++ = EOS; dodefine(optarg, p); break; + case 'E': /* like GNU m4 1.4.9+ */ + if (error_warns == 0) + error_warns = 1; + else + fatal_warns = 1; + break; case 'I': addtoincludepath(optarg); break; diff --git a/usr.bin/m4/misc.c b/usr.bin/m4/misc.c index e0fbb2f4036..0b4f80b30e6 100644 --- a/usr.bin/m4/misc.c +++ b/usr.bin/m4/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.46 2015/12/07 14:12:46 espie Exp $ */ +/* $OpenBSD: misc.c,v 1.47 2017/06/15 13:48:42 bcallah Exp $ */ /* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */ /* @@ -379,9 +379,9 @@ xstrdup(const char *s) } void -usage() +usage(void) { - fprintf(stderr, "usage: m4 [-gPs] [-Dname[=value]] [-d flags] " + fprintf(stderr, "usage: m4 [-EgPs] [-Dname[=value]] [-d flags] " "[-I dirname] [-o filename]\n" "\t[-t macro] [-Uname] [file ...]\n"); exit(1); diff --git a/usr.bin/m4/tokenizer.l b/usr.bin/m4/tokenizer.l index 4adabd7e98f..3ffadd4fa29 100644 --- a/usr.bin/m4/tokenizer.l +++ b/usr.bin/m4/tokenizer.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: tokenizer.l,v 1.8 2012/04/12 17:00:11 espie Exp $ */ +/* $OpenBSD: tokenizer.l,v 1.9 2017/06/15 13:48:42 bcallah Exp $ */ /* * Copyright (c) 2004 Marc Espie * @@ -22,6 +22,7 @@ #include #include +extern void m4_warnx(const char *, ...); extern int mimic_gnu; extern int32_t yylval; @@ -65,9 +66,8 @@ number() errno = 0; l = strtol(yytext, NULL, 0); if (((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) || - l > INT32_MAX || l < INT32_MIN) { - fprintf(stderr, "m4: numeric overflow in expr: %s\n", yytext); - } + l > INT32_MAX || l < INT32_MIN) + m4_warnx("numeric overflow in expr: %s", yytext); return l; } @@ -82,7 +82,7 @@ parse_radix() l = 0; base = strtol(yytext+2, &next, 0); if (base > 36 || next == NULL) { - fprintf(stderr, "m4: error in number %s\n", yytext); + m4_warnx("error in number %s", yytext); } else { next++; while (*next != 0) { @@ -95,8 +95,7 @@ parse_radix() d = *next - 'A' + 10; } if (d >= base) { - fprintf(stderr, - "m4: error in number %s\n", yytext); + m4_warnx("error in number %s", yytext); return 0; } l = base * l + d; -- 2.20.1