Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/m4 - don't eat the rest of the string when no match ...
details: https://anonhg.NetBSD.org/src/rev/a77b380ed42c
branches: trunk
changeset: 342962:a77b380ed42c
user: christos <christos%NetBSD.org@localhost>
date: Sat Jan 16 16:59:18 2016 +0000
description:
- don't eat the rest of the string when no match in patsubst
- include the pattern in the error printing of regex
- handle 3 argument and empty patterns the gnu way
- add support for freezing and thawing state (not working yet)
diffstat:
usr.bin/m4/gnum4.c | 230 +++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 189 insertions(+), 41 deletions(-)
diffs (truncated from 354 to 300 lines):
diff -r 09f6bd828bcf -r a77b380ed42c usr.bin/m4/gnum4.c
--- a/usr.bin/m4/gnum4.c Sat Jan 16 16:57:29 2016 +0000
+++ b/usr.bin/m4/gnum4.c Sat Jan 16 16:59:18 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gnum4.c,v 1.9 2012/03/20 20:34:58 matt Exp $ */
+/* $NetBSD: gnum4.c,v 1.10 2016/01/16 16:59:18 christos Exp $ */
/* $OpenBSD: gnum4.c,v 1.39 2008/08/21 21:01:04 espie Exp $ */
/*
@@ -33,7 +33,7 @@
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: gnum4.c,v 1.9 2012/03/20 20:34:58 matt Exp $");
+__RCSID("$NetBSD: gnum4.c,v 1.10 2016/01/16 16:59:18 christos Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -203,10 +203,11 @@
static void addchar(int);
static char *twiddle(const char *);
static char *getstring(void);
-static void exit_regerror(int, regex_t *) __dead;
-static void do_subst(const char *, regex_t *, const char *, regmatch_t *);
-static void do_regexpindex(const char *, regex_t *, regmatch_t *);
-static void do_regexp(const char *, regex_t *, const char *, regmatch_t *);
+static void exit_regerror(int, const char *, regex_t *) __dead;
+static void do_subst(const char *, const char *, regex_t *, const char *,
+ regmatch_t *);
+static void do_regexpindex(const char *, const char *, regex_t *, regmatch_t *);
+static void do_regexp(const char *, const char *, regex_t *, const char *, regmatch_t *);
static void add_sub(size_t, const char *, regex_t *, regmatch_t *);
static void add_replace(const char *, regex_t *, const char *, regmatch_t *);
#define addconstantstring(s) addchars((s), sizeof(s)-1)
@@ -250,7 +251,7 @@
static void
-exit_regerror(int er, regex_t *re)
+exit_regerror(int er, const char *pat, regex_t *re)
{
size_t errlen;
char *errbuf;
@@ -259,14 +260,18 @@
errbuf = xalloc(errlen,
"malloc in regerror: %lu", (unsigned long)errlen);
regerror(er, re, errbuf, errlen);
- m4errx(1, "regular expression error: %s.", errbuf);
+ m4errx(1, "regular expression error: %s for: `%s'", errbuf, pat);
}
static void
add_sub(size_t n, const char *string, regex_t *re, regmatch_t *pm)
{
- if (n > re->re_nsub)
- warnx("No subexpression %zu", n);
+ if (n > re->re_nsub) {
+ if (!quiet)
+ warnx("No subexpression %zu", n);
+ if (fatal_warnings)
+ exit(EXIT_FAILURE);
+ }
/* Subexpressions that did not match are
* not an error. */
else if (pm[n].rm_so != -1 &&
@@ -313,7 +318,8 @@
}
static void
-do_subst(const char *string, regex_t *re, const char *replace, regmatch_t *pm)
+do_subst(const char *pat, const char *string, regex_t *re, const char *replace,
+ regmatch_t *pm)
{
int error;
int flags = 0;
@@ -346,14 +352,18 @@
addchars(string, pm[0].rm_so);
add_replace(string, re, replace, pm);
string += pm[0].rm_eo;
+ buffer[current] = '\0';
}
+ while (*string)
+ addchar(*string++);
if (error != REG_NOMATCH)
- exit_regerror(error, re);
+ exit_regerror(error, pat, re);
pbstr(string);
}
static void
-do_regexp(const char *string, regex_t *re, const char *replace, regmatch_t *pm)
+do_regexp(const char *pat, const char *string, regex_t *re, const char *replace,
+ regmatch_t *pm)
{
int error;
@@ -365,12 +375,12 @@
case REG_NOMATCH:
break;
default:
- exit_regerror(error, re);
+ exit_regerror(error, pat, re);
}
}
static void
-do_regexpindex(const char *string, regex_t *re, regmatch_t *pm)
+do_regexpindex(const char *pat, const char *string, regex_t *re, regmatch_t *pm)
{
int error;
@@ -382,7 +392,7 @@
pbnum(-1);
break;
default:
- exit_regerror(error, re);
+ exit_regerror(error, pat, re);
}
}
@@ -437,6 +447,33 @@
return getstring();
}
+static int
+checkempty(const char *argv[], int argc)
+{
+ const char *s;
+ size_t len;
+
+ if (argc != 3 && argv[3][0] != '\0')
+ return 0;
+
+ if (argc == 3) {
+ if (!quiet)
+ warnx("Too few arguments to patsubst");
+ if (fatal_warnings)
+ exit(EXIT_FAILURE);
+ }
+
+ if (argv[4] && argc > 4)
+ len = strlen(argv[4]);
+ else
+ len = 0;
+ for (s = argv[2]; *s != '\0'; s++) {
+ addchars(argv[4], len);
+ addchar(*s);
+ }
+ return 1;
+}
+
/* patsubst(string, regexp, opt replacement) */
/* argv[2]: string
* argv[3]: regexp
@@ -445,23 +482,17 @@
void
dopatsubst(const char *argv[], int argc)
{
- if (argc <= 3) {
- warnx("Too few arguments to patsubst");
+ if (argc < 3) {
+ if (!quiet)
+ warnx("Too few arguments to patsubst");
+ if (fatal_warnings)
+ exit(EXIT_FAILURE);
return;
}
/* special case: empty regexp */
- if (argv[3][0] == '\0') {
- const char *s;
- size_t len;
- if (argv[4] && argc > 4)
- len = strlen(argv[4]);
- else
- len = 0;
- for (s = argv[2]; *s != '\0'; s++) {
- addchars(argv[4], len);
- addchar(*s);
- }
- } else {
+ if (!checkempty(argv, argc)) {
+
+ const char *pat;
int error;
regex_t re;
regmatch_t *pmatch;
@@ -473,13 +504,13 @@
(l > 0 && argv[3][l-1] == '$'))
mode |= REG_NEWLINE;
- error = regcomp(&re, mimic_gnu ? twiddle(argv[3]) : argv[3],
- mode);
+ pat = mimic_gnu ? twiddle(argv[3]) : argv[3];
+ error = regcomp(&re, pat, mode);
if (error != 0)
- exit_regerror(error, &re);
+ exit_regerror(error, pat, &re);
pmatch = xalloc(sizeof(regmatch_t) * (re.re_nsub+1), NULL);
- do_subst(argv[2], &re,
+ do_subst(pat, argv[2], &re,
argc > 4 && argv[4] != NULL ? argv[4] : "", pmatch);
free(pmatch);
regfree(&re);
@@ -493,21 +524,29 @@
int error;
regex_t re;
regmatch_t *pmatch;
+ const char *pat;
- if (argc <= 3) {
- warnx("Too few arguments to regexp");
+ if (argc < 3) {
+ if (!quiet)
+ warnx("Too few arguments to regexp");
+ if (fatal_warnings)
+ exit(EXIT_FAILURE);
return;
}
- error = regcomp(&re, mimic_gnu ? twiddle(argv[3]) : argv[3],
- REG_EXTENDED);
+ if (checkempty(argv, argc)) {
+ return;
+ }
+
+ pat = mimic_gnu ? twiddle(argv[3]) : argv[3];
+ error = regcomp(&re, pat, REG_EXTENDED);
if (error != 0)
- exit_regerror(error, &re);
+ exit_regerror(error, pat, &re);
pmatch = xalloc(sizeof(regmatch_t) * (re.re_nsub+1), NULL);
if (argv[4] == NULL || argc == 4)
- do_regexpindex(argv[2], &re, pmatch);
+ do_regexpindex(pat, argv[2], &re, pmatch);
else
- do_regexp(argv[2], &re, argv[4], pmatch);
+ do_regexp(pat, argv[2], &re, argv[4], pmatch);
free(pmatch);
regfree(&re);
}
@@ -667,3 +706,112 @@
putc(c, active);
(void) fclose(f);
}
+
+#ifdef REAL_FREEZE
+void
+freeze_state(const char *fname)
+{
+ FILE *f;
+
+ if ((f = fopen(fname, "wb")) == NULL)
+ m4errx(EXIT_FAILURE, "Can't open output freeze file `%s' (%s)",
+ fname, strerror(errno));
+ fprintf(f, "# This is a frozen state file generated by %s\nV1\n",
+ getprogname());
+ fprintf(f, "Q%zu,%zu\n%s%s\n", strlen(lquote), strlen(rquote),
+ lquote, rquote);
+ fprintf(f, "C%zu,%zu\n%s%s\n", strlen(scommt), strlen(ecommt),
+ scommt, ecommt);
+ dump_state(f);
+ /* XXX: diversions? */
+ fprintf(f, "D-1,0\n");
+ fprintf(f, "# End of frozen state file\n");
+ fclose(f);
+}
+
+void
+thaw_state(const char *fname)
+{
+ char *name = NULL;
+ size_t nl, namelen = 0;
+ char *defn = NULL;
+ size_t dl, defnlen = 0;
+ size_t lineno = 0;
+ char line[1024], *ptr, type;
+ FILE *f;
+
+ if ((f = fopen(fname, "rb")) == NULL)
+ m4errx(EXIT_FAILURE, "Can't open frozen file `%s' (%s)",
+ fname, strerror(errno));
+
+#define GET() if (fgets(line, (int)sizeof(line), f) == NULL) goto out
+#define GETSTR(s, l) if (fread(s, 1, l, f) != l) goto out; else s[l] = '\0'
+
+ GET(); /* comment */
+ GET(); /* version */
+ if ((ptr = strrchr(line, '\n')) != NULL)
+ *ptr = '\0';
+ if (strcmp(line, "V1") != 0)
+ m4errx(EXIT_FAILURE, "Bad frozen version `%s'", line);
+
+ for (;;) {
+ GET();
+ lineno++;
+ switch (*line) {
+ case '\n':
+ continue;
+ case '#':
Home |
Main Index |
Thread Index |
Old Index