diff options
author | jmallett <jmallett@FreeBSD.org> | 2002-04-19 17:26:21 +0000 |
---|---|---|
committer | jmallett <jmallett@FreeBSD.org> | 2002-04-19 17:26:21 +0000 |
commit | b38bbfea3be32adfe5798450f00bbcf0cbed5804 (patch) | |
tree | e50607d075b4fa99ab7d040c1f22f13cfc865fff /usr.bin | |
parent | e0dd7499cbc447a80e58137ec3f5c98184a72d10 (diff) | |
download | FreeBSD-src-b38bbfea3be32adfe5798450f00bbcf0cbed5804.zip FreeBSD-src-b38bbfea3be32adfe5798450f00bbcf0cbed5804.tar.gz |
Bring OpenBSD m4(1) off of the OPENBSD vendor branch, and add the -s option,
$FreeBSD$ identifiers, and fix initialisation to stderr to happen in a function
as stderr is not the same in CURRENT as in OpenBSD.
Reviewed by: obrien
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/m4/Makefile | 9 | ||||
-rw-r--r-- | usr.bin/m4/eval.c | 656 | ||||
-rw-r--r-- | usr.bin/m4/expr.c | 128 | ||||
-rw-r--r-- | usr.bin/m4/extern.h | 157 | ||||
-rw-r--r-- | usr.bin/m4/look.c | 77 | ||||
-rw-r--r-- | usr.bin/m4/m4.1 | 20 | ||||
-rw-r--r-- | usr.bin/m4/main.c | 584 | ||||
-rw-r--r-- | usr.bin/m4/mdef.h | 102 | ||||
-rw-r--r-- | usr.bin/m4/misc.c | 327 | ||||
-rw-r--r-- | usr.bin/m4/pathnames.h | 10 | ||||
-rw-r--r-- | usr.bin/m4/stdd.h | 10 | ||||
-rw-r--r-- | usr.bin/m4/trace.c | 5 |
12 files changed, 1442 insertions, 643 deletions
diff --git a/usr.bin/m4/Makefile b/usr.bin/m4/Makefile index 7a57e83..cc54a0e 100644 --- a/usr.bin/m4/Makefile +++ b/usr.bin/m4/Makefile @@ -1,10 +1,13 @@ -# @(#)Makefile 8.1 (Berkeley) 6/6/93 +# $OpenBSD: Makefile,v 1.8 2001/09/18 14:55:52 espie Exp $ +# $FreeBSD$ -# -DEXTENDED +# -DEXTENDED # if you want the paste & spaste macros. PROG= m4 CFLAGS+=-DEXTENDED -SRCS= eval.c expr.c look.c main.c misc.c + +SRCS= eval.c expr.c look.c main.c misc.c gnum4.c trace.c +MAN= m4.1 .include <bsd.prog.mk> diff --git a/usr.bin/m4/eval.c b/usr.bin/m4/eval.c index 81eeb18..6f6ed0c 100644 --- a/usr.bin/m4/eval.c +++ b/usr.bin/m4/eval.c @@ -1,3 +1,6 @@ +/* $OpenBSD: eval.c,v 1.43 2002/02/16 21:27:48 millert Exp $ */ +/* $NetBSD: eval.c,v 1.7 1996/11/10 21:21:29 pk Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -34,13 +37,10 @@ * SUCH DAMAGE. */ -#ifndef lint -#if 0 -static char sccsid[] = "@(#)eval.c 8.1 (Berkeley) 6/6/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__SCCSID("@(#)eval.c 8.2 (Berkeley) 4/27/95"); +__RCSID_SOURCE("$OpenBSD: eval.c,v 1.43 2002/02/16 21:27:48 millert Exp $"); +__FBSDID("$FreeBSD$"); /* * eval.c @@ -49,18 +49,45 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <err.h> +#include <errno.h> +#include <unistd.h> #include <stdio.h> #include <stdlib.h> +#include <stddef.h> #include <string.h> -#include <unistd.h> +#include <fcntl.h> +#include <err.h> #include "mdef.h" #include "stdd.h" #include "extern.h" #include "pathnames.h" +#define BUILTIN_MARKER "__builtin_" + +static void dodefn(const char *); +static void dopushdef(const char *, const char *); +static void dodump(const char *[], int); +static void dotrace(const char *[], int, int); +static void doifelse(const char *[], int); +static int doincl(const char *); +static int dopaste(const char *); +static void gnu_dochq(const char *[], int); +static void dochq(const char *[], int); +static void gnu_dochc(const char *[], int); +static void dochc(const char *[], int); +static void dodiv(int); +static void doundiv(const char *[], int); +static void dosub(const char *[], int); +static void map(char *, const char *, const char *, const char *); +static const char *handledash(char *, char *, const char *); +static void expand_builtin(const char *[], int, int); +static void expand_macro(const char *[], int); +static void dump_one_def(ndptr); + +unsigned long expansion_id; + /* - * eval - evaluate built-in macros. + * eval - eval all macros and builtins calls * argc - number of elements in argv. * argv - element vector : * argv[0] = definition of a user @@ -71,37 +98,66 @@ static const char rcsid[] = * . macro or built-in. * . * - * Note that the minimum value for argc is 3. A call in the form - * of macro-or-builtin() will result in: + * A call in the form of macro-or-builtin() will result in: * argv[0] = nullstr * argv[1] = macro-or-builtin * argv[2] = nullstr + * + * argc is 3 for macro-or-builtin() and 2 for macro-or-builtin */ - void eval(argv, argc, td) -register char *argv[]; -register int argc; -register int td; + const char *argv[]; + int argc; + int td; +{ + ssize_t mark = -1; + + expansion_id++; + if (td & RECDEF) + errx(1, "%s at line %lu: expanding recursive definition for %s", + CURRENT_NAME, CURRENT_LINE, argv[1]); + if (traced_macros && is_traced(argv[1])) + mark = trace(argv, argc, infile+ilevel); + if (td == MACRTYPE) + expand_macro(argv, argc); + else + expand_builtin(argv, argc, td); + if (mark != -1) + finish_trace(mark); +} + +/* + * expand_builtin - evaluate built-in macros. + */ +void +expand_builtin(argv, argc, td) + const char *argv[]; + int argc; + int td; { - register int c, n; + int c, n; + int ac; static int sysval = 0; - char *p; #ifdef DEBUG printf("argc = %d\n", argc); for (n = 0; n < argc; n++) printf("argv[%d] = %s\n", n, argv[n]); + fflush(stdout); #endif + /* * if argc == 3 and argv[2] is null, then we * have macro-or-builtin() type call. We adjust * argc to avoid further checking.. */ + ac = argc; + if (argc == 3 && !*(argv[2])) argc--; - switch (td & ~STATIC) { + switch (td & TYPEMASK) { case DEFITYPE: if (argc > 2) @@ -117,6 +173,14 @@ register int td; dodump(argv, argc); break; + case TRACEONTYPE: + dotrace(argv, argc, 1); + break; + + case TRACEOFFTYPE: + dotrace(argv, argc, 0); + break; + case EXPRTYPE: /* * doexpr - evaluate arithmetic @@ -175,9 +239,6 @@ register int td; /* * dosys - execute system command */ - /* Make sure m4 output is NOT interrupted */ - fflush(stdout); - fflush(stderr); if (argc > 2) sysval = system(argv[2]); break; @@ -186,15 +247,20 @@ register int td; /* * dosysval - return value of the last * system call. - * + * */ pbnum(sysval); break; + case ESYSCMDTYPE: + if (argc > 2) + doesyscmd(argv[2]); + break; case INCLTYPE: if (argc > 2) if (!doincl(argv[2])) - err(1, "%s", argv[2]); + err(1, "%s at line %lu: include(%s)", + CURRENT_NAME, CURRENT_LINE, argv[2]); break; case SINCTYPE: @@ -205,7 +271,8 @@ register int td; case PASTTYPE: if (argc > 2) if (!dopaste(argv[2])) - err(1, "%s", argv[2]); + err(1, "%s at line %lu: paste(%s)", + CURRENT_NAME, CURRENT_LINE, argv[2]); break; case SPASTYPE: @@ -214,17 +281,23 @@ register int td; break; #endif case CHNQTYPE: - dochq(argv, argc); + if (mimic_gnu) + gnu_dochq(argv, ac); + else + dochq(argv, argc); break; case CHNCTYPE: - dochc(argv, argc); + if (mimic_gnu) + gnu_dochc(argv, ac); + else + dochc(argv, argc); break; case SUBSTYPE: /* * dosub - select substring - * + * */ if (argc > 3) dosub(argv, argc); @@ -238,14 +311,14 @@ register int td; */ if (argc > 3) { for (n = argc - 1; n > 3; n--) { - putback(rquote); + pbstr(rquote); pbstr(argv[n]); - putback(lquote); - putback(','); + pbstr(lquote); + putback(COMMA); } - putback(rquote); + pbstr(rquote); pbstr(argv[3]); - putback(lquote); + pbstr(lquote); } break; @@ -295,8 +368,21 @@ register int td; /* * dotemp - create a temporary file */ - if (argc > 2) - pbstr(mktemp(argv[2])); + if (argc > 2) { + int fd; + char *temp; + + temp = xstrdup(argv[2]); + + fd = mkstemp(temp); + if (fd == -1) + err(1, + "%s at line %lu: couldn't make temp file %s", + CURRENT_NAME, CURRENT_LINE, argv[2]); + close(fd); + pbstr(temp); + free(temp); + } break; case TRNLTYPE: @@ -307,14 +393,16 @@ register int td; * characters in the "to" string. */ if (argc > 3) { - char temp[STRSPMAX+1]; + char *temp; + + temp = xalloc(strlen(argv[2])+1); if (argc > 4) map(temp, argv[2], argv[3], argv[4]); else map(temp, argv[2], argv[3], null); pbstr(temp); - } - else if (argc > 2) + free(temp); + } else if (argc > 2) pbstr(argv[2]); break; @@ -353,9 +441,7 @@ register int td; * dom4wrap - set up for * wrap-up/wind-down activity */ - if ((p = strdup(argv[2])) == NULL) - err(1, "strdup"); - m4wraps = (argc > 2) ? p : null; + m4wraps = (argc > 2) ? xstrdup(argv[2]) : null; break; case EXITTYPE: @@ -372,30 +458,54 @@ register int td; dodefn(argv[n]); break; - case MACRTYPE: - pbstr(""); + case INDIRTYPE: /* Indirect call */ + if (argc > 2) + doindir(argv, argc); + break; + + case BUILTINTYPE: /* Builtins only */ + if (argc > 2) + dobuiltin(argv, argc); break; + case PATSTYPE: + if (argc > 2) + dopatsubst(argv, argc); + break; + case REGEXPTYPE: + if (argc > 2) + doregexp(argv, argc); + break; + case LINETYPE: + doprintlineno(infile+ilevel); + break; + case FILENAMETYPE: + doprintfilename(infile+ilevel); + break; + case SELFTYPE: + pbstr(rquote); + pbstr(argv[1]); + pbstr(lquote); + break; default: - errx(1, "eval: major botch"); + errx(1, "%s at line %lu: eval: major botch.", + CURRENT_NAME, CURRENT_LINE); break; } } -const char dumpfmt[] = "`%s'\t`%s'\n"; /* format string for dumpdef */ - /* - * expand - user-defined macro expansion + * expand_macro - user-defined macro expansion */ void -expand(argv, argc) -register char *argv[]; -register int argc; +expand_macro(argv, argc) + const char *argv[]; + int argc; { - register unsigned char *t; - register unsigned char *p; - register int n; - register int argno; + const char *t; + const char *p; + int n; + int argno; t = argv[0]; /* defn string as a whole */ p = t; @@ -404,7 +514,7 @@ register int argc; p--; /* last character of defn */ while (p > t) { if (*(p - 1) != ARGFLAG) - putback(*p); + PUTBACK(*p); else { switch (*p) { @@ -425,25 +535,30 @@ register int argc; pbstr(argv[argno + 1]); break; case '*': - for (n = argc - 1; n > 2; n--) { - pbstr(argv[n]); - putback(','); - } - pbstr(argv[2]); + if (argc > 2) { + for (n = argc - 1; n > 2; n--) { + pbstr(argv[n]); + putback(COMMA); + } + pbstr(argv[2]); + } break; - case '@': - for( n = argc - 1; n >= 2; n-- ) - { - putback(rquote); - pbstr(argv[n]); - putback(lquote); - if( n > 2 ) - putback(','); + case '@': + if (argc > 2) { + for (n = argc - 1; n > 2; n--) { + pbstr(rquote); + pbstr(argv[n]); + pbstr(lquote); + putback(COMMA); + } + pbstr(rquote); + pbstr(argv[2]); + pbstr(lquote); } - break; + break; default: - putback(*p); - putback('$'); + PUTBACK(*p); + PUTBACK('$'); break; } p--; @@ -451,7 +566,7 @@ register int argc; p--; } if (p == t) /* do last character */ - putback(*p); + PUTBACK(*p); } /* @@ -459,41 +574,58 @@ register int argc; */ void dodefine(name, defn) -register char *name; -register char *defn; + const char *name; + const char *defn; { - register ndptr p; + ndptr p; + int n; if (!*name) - errx(1, "null definition"); - if (STREQ(name, defn)) - errx(1, "%s: recursive definition", name); + errx(1, "%s at line %lu: null definition.", CURRENT_NAME, + CURRENT_LINE); if ((p = lookup(name)) == nil) p = addent(name); else if (p->defn != null) free((char *) p->defn); + if (strncmp(defn, BUILTIN_MARKER, sizeof(BUILTIN_MARKER)-1) == 0) { + n = builtin_type(defn+sizeof(BUILTIN_MARKER)-1); + if (n != -1) { + p->type = n & TYPEMASK; + if ((n & NOARGS) == 0) + p->type |= NEEDARGS; + p->defn = null; + return; + } + } if (!*defn) p->defn = null; else - if ((p->defn = strdup(defn)) == NULL) - err(1, "strdup"); + p->defn = xstrdup(defn); p->type = MACRTYPE; + if (STREQ(name, defn)) + p->type |= RECDEF; } /* * dodefn - push back a quoted definition of * the given name. */ -void +static void dodefn(name) -char *name; + const char *name; { - register ndptr p; - - if ((p = lookup(name)) != nil && p->defn != null) { - putback(rquote); - pbstr(p->defn); - putback(lquote); + ndptr p; + char *real; + + if ((p = lookup(name)) != nil) { + if (p->defn != null) { + pbstr(rquote); + pbstr(p->defn); + pbstr(lquote); + } else if ((real = builtin_realname(p->type)) != NULL) { + pbstr(real); + pbstr(BUILTIN_MARKER); + } } } @@ -504,24 +636,46 @@ char *name; * hash bucket, it hides a previous definition from * lookup. */ -void +static void dopushdef(name, defn) -register char *name; -register char *defn; + const char *name; + const char *defn; { - register ndptr p; + ndptr p; if (!*name) - errx(1, "null definition"); - if (STREQ(name, defn)) - errx(1, "%s: recursive definition", name); + errx(1, "%s at line %lu: null definition", CURRENT_NAME, + CURRENT_LINE); p = addent(name); if (!*defn) p->defn = null; else - if ((p->defn = strdup(defn)) == NULL) - err(1, "strdup"); + p->defn = xstrdup(defn); p->type = MACRTYPE; + if (STREQ(name, defn)) + p->type |= RECDEF; +} + +/* + * dump_one_def - dump the specified definition. + */ +static void +dump_one_def(p) + ndptr p; +{ + char *real; + + if (mimic_gnu) { + if ((p->type & TYPEMASK) == MACRTYPE) + fprintf(traceout, "%s:\t%s\n", p->name, p->defn); + else { + real = builtin_realname(p->type); + if (real == NULL) + real = null; + fprintf(traceout, "%s:\t<%s>\n", p->name, real); + } + } else + fprintf(traceout, "`%s'\t`%s'\n", p->name, p->defn); } /* @@ -529,35 +683,50 @@ register char *defn; * table to stderr. If nothing is specified, the entire * hash table is dumped. */ -void +static void dodump(argv, argc) -register char *argv[]; -register int argc; + const char *argv[]; + int argc; { - register int n; + int n; ndptr p; if (argc > 2) { for (n = 2; n < argc; n++) if ((p = lookup(argv[n])) != nil) - fprintf(stderr, dumpfmt, p->name, - p->defn); - } - else { + dump_one_def(p); + } else { for (n = 0; n < HASHSIZE; n++) for (p = hashtab[n]; p != nil; p = p->nxtptr) - fprintf(stderr, dumpfmt, p->name, - p->defn); + dump_one_def(p); } } /* + * dotrace - mark some macros as traced/untraced depending upon on. + */ +static void +dotrace(argv, argc, on) + const char *argv[]; + int argc; + int on; +{ + int n; + + if (argc > 2) { + for (n = 2; n < argc; n++) + mark_traced(argv[n], on); + } else + mark_traced(NULL, on); +} + +/* * doifelse - select one of two alternatives - loop. */ -void +static void doifelse(argv, argc) -register char *argv[]; -register int argc; + const char *argv[]; + int argc; { cycle { if (STREQ(argv[2], argv[3])) @@ -576,13 +745,14 @@ register int argc; /* * doinclude - include a given file. */ -int +static int doincl(ifile) -char *ifile; + const char *ifile; { if (ilevel + 1 == MAXINP) - errx(1, "too many include files"); - if ((infile[ilevel + 1] = fopen(ifile, "r")) != NULL) { + errx(1, "%s at line %lu: too many include files.", + CURRENT_NAME, CURRENT_LINE); + if (fopen_trypath(infile+ilevel+1, ifile) != NULL) { ilevel++; if ((inname[ilevel] = strdup(ifile)) == NULL) err(1, NULL); @@ -590,8 +760,7 @@ char *ifile; bbase[ilevel] = bufbase = bp; emitline(); return (1); - } - else + } else return (0); } @@ -600,12 +769,12 @@ char *ifile; * dopaste - include a given file without any * macro processing. */ -int +static int dopaste(pfile) -char *pfile; + const char *pfile; { FILE *pf; - register int c; + int c; if ((pf = fopen(pfile, "r")) != NULL) { fprintf(active, "#line 1 \"%s\"\n", pfile); @@ -614,78 +783,128 @@ char *pfile; (void) fclose(pf); emitline(); return (1); - } - else + } else return (0); } #endif +static void +gnu_dochq(argv, ac) + const char *argv[]; + int ac; +{ + /* In gnu-m4 mode, the only way to restore quotes is to have no + * arguments at all. */ + if (ac == 2) { + lquote[0] = LQUOTE, lquote[1] = EOS; + rquote[0] = RQUOTE, rquote[1] = EOS; + } else { + strlcpy(lquote, argv[2], sizeof(lquote)); + if(ac > 3) + strlcpy(rquote, argv[3], sizeof(rquote)); + else + rquote[0] = EOS; + } +} + /* * dochq - change quote characters */ -void +static void dochq(argv, argc) -register char *argv[]; -register int argc; + const char *argv[]; + int argc; { if (argc > 2) { if (*argv[2]) - lquote = *argv[2]; - else - lquote = LQUOTE; + strlcpy(lquote, argv[2], sizeof(lquote)); + else { + lquote[0] = LQUOTE; + lquote[1] = EOS; + } if (argc > 3) { if (*argv[3]) - rquote = *argv[3]; - else - rquote = RQUOTE; - } - else - rquote = lquote; - } - else { - lquote = LQUOTE; - rquote = RQUOTE; + strlcpy(rquote, argv[3], sizeof(rquote)); + } else + strcpy(rquote, lquote); + } else { + lquote[0] = LQUOTE, lquote[1] = EOS; + rquote[0] = RQUOTE, rquote[1] = EOS; } } +static void +gnu_dochc(argv, ac) + const char *argv[]; + int ac; +{ + /* In gnu-m4 mode, no arguments mean no comment + * arguments at all. */ + if (ac == 2) { + scommt[0] = EOS; + ecommt[0] = EOS; + } else { + if (*argv[2]) + strlcpy(scommt, argv[2], sizeof(scommt)); + else + scommt[0] = SCOMMT, scommt[1] = EOS; + if(ac > 3 && *argv[3]) + strlcpy(ecommt, argv[3], sizeof(ecommt)); + else + ecommt[0] = ECOMMT, ecommt[1] = EOS; + } +} /* * dochc - change comment characters */ -void +static void dochc(argv, argc) -register char *argv[]; -register int argc; + const char *argv[]; + int argc; { if (argc > 2) { if (*argv[2]) - scommt = *argv[2]; + strlcpy(scommt, argv[2], sizeof(scommt)); if (argc > 3) { if (*argv[3]) - ecommt = *argv[3]; + strlcpy(ecommt, argv[3], sizeof(ecommt)); } else - ecommt = ECOMMT; + ecommt[0] = ECOMMT, ecommt[1] = EOS; } else { - scommt = SCOMMT; - ecommt = ECOMMT; + scommt[0] = SCOMMT, scommt[1] = EOS; + ecommt[0] = ECOMMT, ecommt[1] = EOS; } } /* * dodivert - divert the output to a temporary file */ -void +static void dodiv(n) -register int n; + int n; { + int fd; + oindex = n; - if (n < 0 || n >= MAXOUT) + if (n >= maxout) { + if (mimic_gnu) + resizedivs(n + 10); + else + n = 0; /* bitbucket */ + } + + if (n < 0) n = 0; /* bitbucket */ if (outfile[n] == NULL) { - m4temp[UNIQUE] = n + '0'; - if ((outfile[n] = fopen(m4temp, "w")) == NULL) - errx(1, "%s: cannot divert", m4temp); + char fname[] = _PATH_DIVNAME; + + if ((fd = mkstemp(fname)) < 0 || + (outfile[n] = fdopen(fd, "w+")) == NULL) + err(1, "%s: cannot divert", fname); + if (unlink(fname) == -1) + err(1, "%s: cannot unlink", fname); } active = outfile[n]; } @@ -694,24 +913,24 @@ register int n; * doundivert - undivert a specified output, or all * other outputs, in numerical order. */ -void +static void doundiv(argv, argc) -register char *argv[]; -register int argc; + const char *argv[]; + int argc; { - register int ind; - register int n; + int ind; + int n; if (argc > 2) { for (ind = 2; ind < argc; ind++) { n = atoi(argv[ind]); - if (n > 0 && n < MAXOUT && outfile[n] != NULL) + if (n > 0 && n < maxout && outfile[n] != NULL) getdiv(n); } } else - for (n = 1; n < MAXOUT; n++) + for (n = 1; n < maxout; n++) if (outfile[n] != NULL) getdiv(n); } @@ -719,13 +938,13 @@ register int argc; /* * dosub - select substring */ -void +static void dosub(argv, argc) -register char *argv[]; -register int argc; + const char *argv[]; + int argc; { - register unsigned char *ap, *fc, *k; - register int nc; + const char *ap, *fc, *k; + int nc; ap = argv[2]; /* target string */ #ifdef EXPR @@ -733,13 +952,12 @@ register int argc; #else fc = ap + atoi(argv[3]); /* first char */ #endif - if (argc < 5) - nc = strlen(fc); - else + nc = strlen(fc); + if (argc >= 5) #ifdef EXPR - nc = expr(argv[4]); + nc = min(nc, expr(argv[4])); #else - nc = atoi(argv[4]); + nc = min(nc, atoi(argv[4])); #endif if (fc >= ap && fc < ap + strlen(ap)) for (k = fc + nc - 1; k >= fc; k--) @@ -771,55 +989,109 @@ register int argc; * about 5 times faster than any algorithm that makes multiple passes over * destination string. */ -void +static void map(dest, src, from, to) -register char *dest; -register char *src; -register char *from; -register char *to; + char *dest; + const char *src; + const char *from; + const char *to; { - register char *tmp; - register char sch, dch; - static char mapvec[128] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127 + const char *tmp; + unsigned char sch, dch; + static char frombis[257]; + static char tobis[257]; + static unsigned char mapvec[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; if (*src) { + if (mimic_gnu) { + /* + * expand character ranges on the fly + */ + from = handledash(frombis, frombis + 256, from); + to = handledash(tobis, tobis + 256, to); + } tmp = from; /* * create a mapping between "from" and * "to" */ while (*from) - mapvec[*from++] = (*to) ? *to++ : (char) 0; + mapvec[(unsigned char)(*from++)] = (*to) ? + (unsigned char)(*to++) : 0; while (*src) { - sch = *src++; + sch = (unsigned char)(*src++); dch = mapvec[sch]; while (dch != sch) { sch = dch; dch = mapvec[sch]; } - if (*dest = dch) + if ((*dest = (char)dch)) dest++; } /* * restore all the changed characters */ while (*tmp) { - mapvec[*tmp] = *tmp; + mapvec[(unsigned char)(*tmp)] = (unsigned char)(*tmp); tmp++; } } - *dest = (char) 0; + *dest = '\0'; +} + + +/* + * handledash: + * use buffer to copy the src string, expanding character ranges + * on the way. + */ +static const char * +handledash(buffer, end, src) + char *buffer; + char *end; + const char *src; +{ + char *p; + + p = buffer; + while(*src) { + if (src[1] == '-' && src[2]) { + unsigned char i; + for (i = (unsigned char)src[0]; + i <= (unsigned char)src[2]; i++) { + *p++ = i; + if (p == end) { + *p = '\0'; + return buffer; + } + } + src += 3; + } else + *p++ = *src++; + if (p == end) + break; + } + *p = '\0'; + return buffer; } + diff --git a/usr.bin/m4/expr.c b/usr.bin/m4/expr.c index f63b4781..249d5d5 100644 --- a/usr.bin/m4/expr.c +++ b/usr.bin/m4/expr.c @@ -1,3 +1,6 @@ +/* $OpenBSD: expr.c,v 1.12 2002/02/16 21:27:48 millert Exp $ */ +/* $NetBSD: expr.c,v 1.7 1995/09/28 05:37:31 tls Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -32,16 +35,20 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ -#ifndef lint -static char sccsid[] = "@(#)expr.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - #include <sys/cdefs.h> +__SCCSID("@(#)expr.c 8.2 (Berkeley) 4/29/95"); +__RCSID_SOURCE("$OpenBSD: expr.c,v 1.12 2002/02/16 21:27:48 millert Exp $"); +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <ctype.h> +#include <err.h> +#include <stddef.h> #include <stdio.h> +#include "mdef.h" +#include "extern.h" /* * expression evaluator: performs a standard recursive @@ -87,9 +94,6 @@ static char sccsid[] = "@(#)expr.c 8.1 (Berkeley) 6/6/93"; * Bob Harper */ -#define TRUE 1 -#define FALSE 0 -#define EOS (char) 0 #define EQL 0 #define NEQ 1 #define LSS 2 @@ -98,8 +102,10 @@ static char sccsid[] = "@(#)expr.c 8.1 (Berkeley) 6/6/93"; #define GEQ 5 #define OCTAL 8 #define DECIMAL 10 +#define HEX 16 -static char *nxtch; /* Parser scan pointer */ +static const char *nxtch; /* Parser scan pointer */ +static const char *where; static int query(void); static int lor(void); @@ -116,7 +122,7 @@ static int constant(void); static int num(void); static int geteqrel(void); static int skipws(void); -static void experr(char *); +static void experr(const char *); /* * For longjmp @@ -134,11 +140,12 @@ static jmp_buf expjump; int expr(expbuf) -char *expbuf; + const char *expbuf; { - register int rval; + int rval; nxtch = expbuf; + where = expbuf; if (setjmp(expjump) != 0) return FALSE; @@ -156,7 +163,7 @@ char *expbuf; static int query() { - register int bool, true_val, false_val; + int bool, true_val, false_val; bool = lor(); if (skipws() != '?') { @@ -178,7 +185,7 @@ query() static int lor() { - register int c, vl, vr; + int c, vl, vr; vl = land(); while ((c = skipws()) == '|') { @@ -198,7 +205,7 @@ lor() static int land() { - register int c, vl, vr; + int c, vl, vr; vl = not(); while ((c = skipws()) == '&') { @@ -218,7 +225,7 @@ land() static int not() { - register int val, c; + int val, c; if ((c = skipws()) == '!' && getch() != '=') { ungetch(); @@ -238,7 +245,7 @@ not() static int eqrel() { - register int vl, vr, eqrel; + int vl, vr, eqrel; vl = shift(); while ((eqrel = geteqrel()) != -1) { @@ -276,7 +283,7 @@ eqrel() static int shift() { - register int vl, vr, c; + int vl, vr, c; vl = primary(); while (((c = skipws()) == '<' || c == '>') && getch() == c) { @@ -300,7 +307,7 @@ shift() static int primary() { - register int c, vl, vr; + int c, vl, vr; vl = term(); while ((c = skipws()) == '+' || c == '-') { @@ -322,7 +329,7 @@ primary() static int term() { - register int c, vl, vr; + int c, vl, vr; vl = exp(); while ((c = skipws()) == '*' || c == '/' || c == '%') { @@ -333,10 +340,16 @@ term() vl *= vr; break; case '/': - vl /= vr; + if (vr == 0) + errx(1, "division by zero in eval."); + else + vl /= vr; break; case '%': - vl %= vr; + if (vr == 0) + errx(1, "modulo zero in eval."); + else + vl %= vr; break; } } @@ -350,7 +363,7 @@ term() static int exp() { - register c, vl, vr, n; + int c, vl, vr, n; vl = unary(); switch (c = skipws()) { @@ -379,7 +392,7 @@ exp() static int unary() { - register int val, c; + int val, c; if ((c = skipws()) == '+' || c == '-' || c == '~') { val = unary(); @@ -404,7 +417,7 @@ unary() static int factor() { - register int val; + int val; if (skipws() == '(') { val = query(); @@ -424,9 +437,9 @@ factor() static int constant() { - register int i; - register int value; - register char c; + int i; + int value; + int c; int v[sizeof(int)]; if (skipws() != '\'') { @@ -485,25 +498,56 @@ constant() static int num() { - register int rval, c, base; + int rval, c, base; int ndig; - base = ((c = skipws()) == '0') ? OCTAL : DECIMAL; rval = 0; ndig = 0; - while (c >= '0' && c <= (base == OCTAL ? '7' : '9')) { - rval *= base; - rval += (c - '0'); + c = skipws(); + if (c == '0') { + c = skipws(); + if (c == 'x' || c == 'X') { + base = HEX; + c = skipws(); + } else { + base = OCTAL; + ndig++; + } + } else + base = DECIMAL; + for(;;) { + switch(c) { + case '8': case '9': + if (base == OCTAL) + goto bad_digit; + /*FALLTHRU*/ + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + rval *= base; + rval += c - '0'; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + c = tolower(c); + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + if (base == HEX) { + rval *= base; + rval += c - 'a' + 10; + break; + } + /*FALLTHRU*/ + default: + goto bad_digit; + } c = getch(); ndig++; } +bad_digit: ungetch(); - + if (ndig == 0) experr("bad constant"); - + return rval; - } /* @@ -512,7 +556,7 @@ num() static int geteqrel() { - register int c1, c2; + int c1, c2; c1 = skipws(); c2 = getch(); @@ -556,7 +600,7 @@ geteqrel() static int skipws() { - register char c; + int c; while ((c = getch()) <= ' ' && c > EOS) ; @@ -564,13 +608,13 @@ skipws() } /* - * resets environment to eval(), prints an error + * resets environment to eval(), prints an error * and forces eval to return FALSE. */ static void experr(msg) -char *msg; + const char *msg; { - printf("m4: %s in expr.\n", msg); + printf("m4: %s in expr %s.\n", msg, where); longjmp(expjump, -1); } diff --git a/usr.bin/m4/extern.h b/usr.bin/m4/extern.h index 5fc0bf3..79c3a29 100644 --- a/usr.bin/m4/extern.h +++ b/usr.bin/m4/extern.h @@ -1,3 +1,6 @@ +/* $OpenBSD: extern.h,v 1.29 2002/02/16 21:27:48 millert Exp $ */ +/* $NetBSD: extern.h,v 1.3 1996/01/13 23:25:24 pk Exp $ */ + /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -37,63 +40,119 @@ * $FreeBSD$ */ -int expr(char *); -ndptr addent(char *); -void chrsave(int); -void cleanup(int); -void dochc(char *[], int); -void dochq(char *[], int); -void dodefine(char *, char *); -void dodefn(char *); -void dodiv(int); -void dodump(char *[], int); -void doifelse(char *[], int); -int doincl(char *); -int dopaste(char *); -void dopushdef(char *, char *); -void dosub(char *[], int); -void doundiv(char *[], int); -void emitline(void); -void eval(char *[], int, int); -void expand(char *[], int); -void getdiv(int); -int hash(char *); -int indx(char *, char *); -void killdiv(void); -ndptr lookup(char *); -void map(char *, char *, char *, char *); -void onintr(int); -void pbnum(int); -void pbstr(unsigned char *); -void putback(int); -void remhash(char *, int); -void usage(void); +/* eval.c */ +extern void eval(const char *[], int, int); +extern void dodefine(const char *, const char *); +extern unsigned long expansion_id; + +/* expr.c */ +extern int expr(const char *); + +/* gnum4.c */ +extern void addtoincludepath(const char *); +extern struct input_file *fopen_trypath(struct input_file *, const char *); +extern void doindir(const char *[], int); +extern void dobuiltin(const char *[], int); +extern void dopatsubst(const char *[], int); +extern void doregexp(const char *[], int); + +extern void doprintlineno(struct input_file *); +extern void doprintfilename(struct input_file *); + +extern void doesyscmd(const char *); + + +/* look.c */ +extern ndptr addent(const char *); +extern unsigned hash(const char *); +extern ndptr lookup(const char *); +extern void remhash(const char *, int); + +/* main.c */ +extern void outputstr(const char *); +extern int builtin_type(const char *); +extern char *builtin_realname(int); +extern void emitline(void); + +/* misc.c */ +extern void chrsave(int); +extern char *compute_prevep(void); +extern void getdiv(int); +extern ptrdiff_t indx(const char *, const char *); +extern void initspaces(void); +extern void killdiv(void); +extern void onintr(int); +extern void pbnum(int); +extern void pbunsigned(unsigned long); +extern void pbstr(const char *); +extern void putback(int); +extern void *xalloc(size_t); +extern char *xstrdup(const char *); +extern void usage(void); +extern void resizedivs(int); +extern size_t buffer_mark(void); +extern void dump_buffer(FILE *, size_t); + +extern int obtain_char(struct input_file *); +extern void set_input(struct input_file *, FILE *, const char *); +extern void release_input(struct input_file *); + +/* speeded-up versions of chrsave/putback */ +#define PUTBACK(c) \ + do { \ + if (bp >= endpbb) \ + enlarge_bufspace(); \ + *bp++ = (c); \ + } while(0) + +#define CHRSAVE(c) \ + do { \ + if (ep >= endest) \ + enlarge_strspace(); \ + *ep++ = (c); \ + } while(0) + +/* and corresponding exposure for local symbols */ +extern void enlarge_bufspace(void); +extern void enlarge_strspace(void); +extern char *endpbb; +extern char *endest; + +/* trace.c */ +extern void mark_traced(const char *, int); +extern int is_traced(const char *); +extern void trace_file(const char *); +extern ssize_t trace(const char **, int, struct input_file *); +extern void finish_trace(size_t); +extern int traced_macros; +extern void set_trace_flags(const char *); +extern FILE *traceout; extern ndptr hashtab[]; /* hash table for macros etc. */ -extern stae mstack[]; /* stack of m4 machine */ +extern stae *mstack; /* stack of m4 machine */ +extern char *sstack; /* shadow stack, for string space extension */ extern FILE *active; /* active output file pointer */ -extern FILE *infile[]; /* input file stack (0=stdin) */ -extern char *inname[]; /* names of these input files */ -extern int inlineno[]; /* current number in each input*/ -extern FILE *outfile[]; /* diversion array(0=bitbucket) */ +extern struct input_file infile[];/* input file stack (0=stdin) */ +extern char *inname[]; /* names of these input files */ +extern int inlineno[]; /* current number in each input file */ +extern FILE **outfile; /* diversion array(0=bitbucket) */ +extern int maxout; /* maximum number of diversions */ extern int fp; /* m4 call frame pointer */ extern int ilevel; /* input file stack pointer */ extern int oindex; /* diversion index. */ extern int sp; /* current m4 stack pointer */ -extern unsigned char *bp; /* first available character */ -extern unsigned char buf[]; /* push-back buffer */ -extern unsigned char *bufbase; /* buffer base for this ilevel */ -extern unsigned char *bbase[]; /* buffer base per ilevel */ -extern char ecommt; /* end character for comment */ -extern char *endest; /* end of string space */ -extern unsigned char *endpbb; /* end of push-back buffer */ +extern char *bp; /* first available character */ +extern char *buf; /* push-back buffer */ +extern char *bufbase; /* buffer base for this ilevel */ +extern char *bbase[]; /* buffer base per ilevel */ +extern char ecommt[MAXCCHARS+1];/* end character for comment */ extern char *ep; /* first free char in strspace */ -extern char lquote; /* left quote character (`) */ -extern char *m4dir; /* directory for temporary files */ -extern char *m4temp; /* filename for diversions */ +extern char lquote[MAXCCHARS+1];/* left quote character (`) */ extern char *m4wraps; /* m4wrap string default. */ extern char *null; /* as it says.. just a null. */ -extern char rquote; /* right quote character (') */ -extern char scommt; /* start character for comment */ +extern char rquote[MAXCCHARS+1];/* right quote character (') */ +extern char scommt[MAXCCHARS+1];/* start character for comment */ extern int synccpp; /* Line synchronisation for C preprocessor */ -extern int chscratch; /* Scratch space for gpbc() macro */ +extern int chscratch; /* Scratch space for gpbc() macro */ + +extern int mimic_gnu; /* behaves like gnu-m4 */ diff --git a/usr.bin/m4/look.c b/usr.bin/m4/look.c index 73f5a22..6333639 100644 --- a/usr.bin/m4/look.c +++ b/usr.bin/m4/look.c @@ -1,3 +1,5 @@ +/* $OpenBSD: look.c,v 1.9 2002/02/16 21:27:48 millert Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -34,11 +36,9 @@ * SUCH DAMAGE. */ -#ifndef lint -static char sccsid[] = "@(#)look.c 8.1 (Berkeley) 6/6/93"; -static char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__SCCSID("@(#)look.c 8.1 (Berkeley) 6/6/93"); +__FBSDID("$FreeBSD$"); /* * look.c @@ -47,35 +47,39 @@ static char rcsid[] = */ #include <sys/types.h> -#include <err.h> #include <stdio.h> #include <stdlib.h> +#include <stddef.h> #include <string.h> #include "mdef.h" #include "stdd.h" #include "extern.h" -int +static void freent(ndptr); + +unsigned hash(name) -register char *name; + const char *name; { - register unsigned long h = 0; + unsigned int h = 0; while (*name) h = (h << 5) + h + *name++; - return (h % HASHSIZE); + return (h); } /* * find name in the hash table */ -ndptr +ndptr lookup(name) -char *name; + const char *name; { - register ndptr p; + ndptr p; + unsigned int h; - for (p = hashtab[hash(name)]; p != nil; p = p->nxtptr) - if (STREQ(name, p->name)) + h = hash(name); + for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr) + if (h == p->hv && STREQ(name, p->name)) break; return (p); } @@ -84,32 +88,29 @@ char *name; * hash and create an entry in the hash table. * The new entry is added in front of a hash bucket. */ -ndptr +ndptr addent(name) -char *name; + const char *name; { - register int h; + unsigned int h; ndptr p; h = hash(name); - if ((p = malloc(sizeof(struct ndblock))) == NULL) - err(1, "malloc"); - p->nxtptr = hashtab[h]; - hashtab[h] = p; - if ((p->name = strdup(name)) == NULL) - err(1, "strdup"); + p = (ndptr) xalloc(sizeof(struct ndblock)); + p->nxtptr = hashtab[h % HASHSIZE]; + hashtab[h % HASHSIZE] = p; + p->name = xstrdup(name); + p->hv = h; return p; } static void freent(p) -ndptr p; + ndptr p; { - if (!(p->type & STATIC)) { - free((char *) p->name); - if (p->defn != null) - free((char *) p->defn); - } + free((char *) p->name); + if (p->defn != null) + free((char *) p->defn); free((char *) p); } @@ -118,21 +119,21 @@ ndptr p; */ void remhash(name, all) -char *name; -int all; + const char *name; + int all; { - register int h; - register ndptr xp, tp, mp; + unsigned int h; + ndptr xp, tp, mp; h = hash(name); - mp = hashtab[h]; + mp = hashtab[h % HASHSIZE]; tp = nil; while (mp != nil) { - if (STREQ(mp->name, name)) { + if (mp->hv == h && STREQ(mp->name, name)) { mp = mp->nxtptr; if (tp == nil) { - freent(hashtab[h]); - hashtab[h] = mp; + freent(hashtab[h % HASHSIZE]); + hashtab[h % HASHSIZE] = mp; } else { xp = tp->nxtptr; diff --git a/usr.bin/m4/m4.1 b/usr.bin/m4/m4.1 index ffe8f2d..0ba26f8 100644 --- a/usr.bin/m4/m4.1 +++ b/usr.bin/m4/m4.1 @@ -1,7 +1,7 @@ .\" @(#) $OpenBSD: m4.1,v 1.24 2002/04/18 18:57:23 espie Exp $ -.\" $FreeBSD$ +.\" $FreeBSD$ .\" -.Dd January 26, 1993 +.Dd April 17, 2002 .Dt M4 1 .Os .Sh NAME @@ -11,7 +11,7 @@ .Nm m4 .Op Fl d Ar flags .Op Fl t Ar name -.Op Fl g +.Op Fl gs .Oo .Fl D Ns Ar name Ns Op Ar =value .Oc @@ -54,6 +54,11 @@ recognized as special when not followed by an open parenthesis. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl s +Emit +.Em #line +directives for +.Xr cpp 1 . .It Fl D Ns Ar name Ns Oo .Ar =value .Oc @@ -332,15 +337,6 @@ Returns the current file's name. follows the Single Unix 2 specification, along with a few extensions taken from .Nm gnu-m4 . -.Pp -The -.Fl s -option -.Po -.Xr cpp 1 's -#line directives -.Pc -is currently not supported. Flags .Fl I , .Fl d , diff --git a/usr.bin/m4/main.c b/usr.bin/m4/main.c index 8201016..34020e9 100644 --- a/usr.bin/m4/main.c +++ b/usr.bin/m4/main.c @@ -1,3 +1,6 @@ +/* $OpenBSD: main.c,v 1.52 2002/02/16 21:27:48 millert Exp $ */ +/* $NetBSD: main.c,v 1.12 1997/02/08 23:54:49 cgd Exp $ */ + /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -34,19 +37,12 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1989, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"); +__SCCSID("@(#)main.c 8.1 (Berkeley) 6/6/93"); +__RCSID_SOURCE("$OpenBSD: main.c,v 1.52 2002/02/16 21:27:48 millert Exp $"); +__FBSDID("$FreeBSD$"); /* * main.c @@ -55,115 +51,149 @@ static const char rcsid[] = */ #include <sys/types.h> -#include <ctype.h> -#include <err.h> +#include <assert.h> #include <signal.h> +#include <errno.h> +#include <unistd.h> #include <stdio.h> -#include <stdlib.h> +#include <ctype.h> #include <string.h> -#include <unistd.h> +#include <stddef.h> +#include <stdlib.h> +#include <err.h> #include "mdef.h" #include "stdd.h" #include "extern.h" #include "pathnames.h" ndptr hashtab[HASHSIZE]; /* hash table for macros etc. */ -unsigned char buf[BUFSIZE]; /* push-back buffer */ -unsigned char *bufbase = buf; /* the base for current ilevel */ -unsigned char *bbase[MAXINP]; /* the base for each ilevel */ -unsigned char *bp = buf; /* first available character */ -unsigned char *endpbb = buf+BUFSIZE; /* end of push-back buffer */ -stae mstack[STACKMAX+1]; /* stack of m4 machine */ -char strspace[STRSPMAX+1]; /* string space for evaluation */ -char *ep = strspace; /* first free char in strspace */ -char *endest= strspace+STRSPMAX;/* end of string space */ +stae *mstack; /* stack of m4 machine */ +char *sstack; /* shadow stack, for string space extension */ +static size_t STACKMAX; /* current maximum size of stack */ int sp; /* current m4 stack pointer */ int fp; /* m4 call frame pointer */ -FILE *infile[MAXINP]; /* input file stack (0=stdin) */ -char *inname[MAXINP]; /* names of these input files */ -int inlineno[MAXINP]; /* current number in each input*/ -FILE *outfile[MAXOUT]; /* diversion array(0=bitbucket)*/ +struct input_file infile[MAXINP];/* input file stack (0=stdin) */ +char *inname[MAXINP]; /* names of these input files */ +int inlineno[MAXINP]; /* current number in each input file */ +FILE **outfile; /* diversion array(0=bitbucket)*/ +int maxout; FILE *active; /* active output file pointer */ -char *m4temp; /* filename for diversions */ -char *m4dir; /* directory for diversions */ int ilevel = 0; /* input file stack pointer */ int oindex = 0; /* diversion index.. */ char *null = ""; /* as it says.. just a null.. */ char *m4wraps = ""; /* m4wrap string default.. */ -char lquote = LQUOTE; /* left quote character (`) */ -char rquote = RQUOTE; /* right quote character (') */ -char scommt = SCOMMT; /* start character for comment */ -char ecommt = ECOMMT; /* end character for comment */ +char lquote[MAXCCHARS+1] = {LQUOTE}; /* left quote character (`) */ +char rquote[MAXCCHARS+1] = {RQUOTE}; /* right quote character (') */ +char scommt[MAXCCHARS+1] = {SCOMMT}; /* start character for comment */ +char ecommt[MAXCCHARS+1] = {ECOMMT}; /* end character for comment */ int synccpp; /* Line synchronisation for C preprocessor */ int chscratch; /* Scratch space for gpbc() macro */ struct keyblk keywrds[] = { /* m4 keywords to be installed */ - "include", INCLTYPE, - "sinclude", SINCTYPE, - "define", DEFITYPE, - "defn", DEFNTYPE, - "divert", DIVRTYPE, - "expr", EXPRTYPE, - "eval", EXPRTYPE, - "substr", SUBSTYPE, - "ifelse", IFELTYPE, - "ifdef", IFDFTYPE, - "len", LENGTYPE, - "incr", INCRTYPE, - "decr", DECRTYPE, - "dnl", DNLNTYPE, - "changequote", CHNQTYPE, - "changecom", CHNCTYPE, - "index", INDXTYPE, + { "include", INCLTYPE }, + { "sinclude", SINCTYPE }, + { "define", DEFITYPE }, + { "defn", DEFNTYPE }, + { "divert", DIVRTYPE | NOARGS }, + { "expr", EXPRTYPE }, + { "eval", EXPRTYPE }, + { "substr", SUBSTYPE }, + { "ifelse", IFELTYPE }, + { "ifdef", IFDFTYPE }, + { "len", LENGTYPE }, + { "incr", INCRTYPE }, + { "decr", DECRTYPE }, + { "dnl", DNLNTYPE | NOARGS }, + { "changequote", CHNQTYPE | NOARGS }, + { "changecom", CHNCTYPE | NOARGS }, + { "index", INDXTYPE }, #ifdef EXTENDED - "paste", PASTTYPE, - "spaste", SPASTYPE, + { "paste", PASTTYPE }, + { "spaste", SPASTYPE }, + /* Newer extensions, needed to handle gnu-m4 scripts */ + { "indir", INDIRTYPE}, + { "builtin", BUILTINTYPE}, + { "patsubst", PATSTYPE}, + { "regexp", REGEXPTYPE}, + { "esyscmd", ESYSCMDTYPE}, + { "__file__", FILENAMETYPE | NOARGS}, + { "__line__", LINETYPE | NOARGS}, #endif - "popdef", POPDTYPE, - "pushdef", PUSDTYPE, - "dumpdef", DUMPTYPE, - "shift", SHIFTYPE, - "translit", TRNLTYPE, - "undefine", UNDFTYPE, - "undivert", UNDVTYPE, - "divnum", DIVNTYPE, - "maketemp", MKTMTYPE, - "errprint", ERRPTYPE, - "m4wrap", M4WRTYPE, - "m4exit", EXITTYPE, - "syscmd", SYSCTYPE, - "sysval", SYSVTYPE, - -#ifdef unix - "unix", MACRTYPE, + { "popdef", POPDTYPE }, + { "pushdef", PUSDTYPE }, + { "dumpdef", DUMPTYPE | NOARGS }, + { "shift", SHIFTYPE | NOARGS }, + { "translit", TRNLTYPE }, + { "undefine", UNDFTYPE }, + { "undivert", UNDVTYPE | NOARGS }, + { "divnum", DIVNTYPE | NOARGS }, + { "maketemp", MKTMTYPE }, + { "errprint", ERRPTYPE | NOARGS }, + { "m4wrap", M4WRTYPE | NOARGS }, + { "m4exit", EXITTYPE | NOARGS }, + { "syscmd", SYSCTYPE }, + { "sysval", SYSVTYPE | NOARGS }, + { "traceon", TRACEONTYPE | NOARGS }, + { "traceoff", TRACEOFFTYPE | NOARGS }, + +#if defined(unix) || defined(__unix__) + { "unix", SELFTYPE | NOARGS }, #else #ifdef vms - "vms", MACRTYPE, + { "vms", SELFTYPE | NOARGS }, #endif #endif }; #define MAXKEYS (sizeof(keywrds)/sizeof(struct keyblk)) -void macro(); -void initkwds(); +extern int optind; +extern char *optarg; + +#define MAXRECORD 50 +static struct position { + char *name; + unsigned long line; +} quotes[MAXRECORD], paren[MAXRECORD]; + +static void record(struct position *, int); +static void dump_stack(struct position *, int); + +static void macro(void); +static void initkwds(void); +static ndptr inspect(int, char *); +static int do_look_ahead(int, const char *); + +static void enlarge_stack(void); + +int main(int, char *[]); int main(argc,argv) int argc; char *argv[]; { - register int c; - register int n; + int c; + int n; char *p; - register FILE *ifp; + + traceout = stderr; if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, onintr); initkwds(); + initspaces(); + STACKMAX = INITSTACKMAX; + + mstack = (stae *)xalloc(sizeof(stae) * STACKMAX); + sstack = (char *)xalloc(STACKMAX); - while ((c = getopt(argc, argv, "D:U:s")) != -1) + maxout = 0; + outfile = NULL; + resizedivs(MAXOUT); + + while ((c = getopt(argc, argv, "gst:d:D:U:o:I:")) != -1) switch(c) { case 'D': /* define something..*/ @@ -174,12 +204,27 @@ main(argc,argv) *p++ = EOS; dodefine(optarg, p); break; + case 'I': + addtoincludepath(optarg); + break; case 'U': /* undefine... */ remhash(optarg, TOP); break; + case 'g': + mimic_gnu = 1; + break; + case 'd': + set_trace_flags(optarg); + break; case 's': synccpp = 1; break; + case 't': + mark_traced(optarg, 1); + break; + case 'o': + trace_file(optarg); + break; case '?': usage(); } @@ -188,19 +233,12 @@ main(argc,argv) argv += optind; active = stdout; /* default active output */ - if ((p = strdup(_PATH_DIVDIRNAME)) == NULL) - err(1, "strdup"); - - /* filename for diversions */ - m4dir = mkdtemp(p); - err_set_exit(cleanup); - (void) asprintf(&m4temp, "%s/%s", m4dir, _PATH_DIVNAME); - bbase[0] = bufbase; if (!argc) { sp = -1; /* stack pointer initialized */ fp = 0; /* frame pointer initialized */ - infile[0] = stdin; /* default input (naturally) */ + set_input(infile+0, stdin, "stdin"); + /* default input (naturally) */ if ((inname[0] = strdup("-")) == NULL) err(1, NULL); inlineno[0] = 1; @@ -209,64 +247,92 @@ main(argc,argv) } else for (; argc--; ++argv) { p = *argv; - if (p[0] == '-' && p[1] == '\0') - ifp = stdin; - else if ((ifp = fopen(p, "r")) == NULL) + if (p[0] == '-' && p[1] == EOS) + set_input(infile, stdin, "stdin"); + else if (fopen_trypath(infile, p) == NULL) err(1, "%s", p); sp = -1; - fp = 0; - infile[0] = ifp; + fp = 0; if ((inname[0] = strdup(p)) == NULL) err(1, NULL); inlineno[0] = 1; emitline(); macro(); - if (ifp != stdin) - (void)fclose(ifp); + release_input(infile); } if (*m4wraps) { /* anything for rundown ?? */ ilevel = 0; /* in case m4wrap includes.. */ bufbase = bp = buf; /* use the entire buffer */ - putback(EOF); /* eof is a must !! */ pbstr(m4wraps); /* user-defined wrapup act */ macro(); /* last will and testament */ } if (active != stdout) active = stdout; /* reset output just in case */ - for (n = 1; n < MAXOUT; n++) /* default wrap-up: undivert */ + for (n = 1; n < maxout; n++) /* default wrap-up: undivert */ if (outfile[n] != NULL) getdiv(n); /* remove bitbucket if used */ - cleanup(0); + if (outfile[0] != NULL) { + (void) fclose(outfile[0]); + } + return 0; } -ndptr inspect(); +/* + * Look ahead for `token'. + * (on input `t == token[0]') + * Used for comment and quoting delimiters. + * Returns 1 if `token' present; copied to output. + * 0 if `token' not found; all characters pushed back + */ +static int +do_look_ahead(t, token) + int t; + const char *token; +{ + int i; + + assert((unsigned char)t == (unsigned char)token[0]); + + for (i = 1; *++token; i++) { + t = gpbc(); + if (t == EOF || (unsigned char)t != (unsigned char)*token) { + putback(t); + while (--i) + putback(*--token); + return 0; + } + } + return 1; +} + +#define LOOK_AHEAD(t, token) (t != EOF && \ + (unsigned char)(t)==(unsigned char)(token)[0] && \ + do_look_ahead(t,token)) /* * macro - the work horse.. */ -void -macro() { - char token[MAXTOK]; - register char *s; - register int t, l; - register ndptr p; - register int nlpar; +static void +macro() +{ + char token[MAXTOK+1]; + int t, l; + ndptr p; + int nlpar; cycle { - if ((t = gpbc()) == '_' || (t != EOF && isalpha(t))) { - putback(t); - if ((p = inspect(s = token)) == nil) { - if (sp < 0) - while (*s) - putc(*s++, active); - else - while (*s) - chrsave(*s++); - } + t = gpbc(); + if (t == '_' || isalpha(t)) { + p = inspect(t, token); + if (p != nil) + putback(l = gpbc()); + if (p == nil || (l != LPAREN && + (p->type & NEEDARGS) != 0)) + outputstr(token); else { /* * real thing.. First build a call frame: @@ -278,58 +344,93 @@ macro() { /* * now push the string arguments: */ - pushs(p->defn); /* defn string */ - pushs(p->name); /* macro name */ - pushs(ep); /* start next..*/ - - putback(l = gpbc()); - if (l != LPAREN) { /* add bracks */ - putback(RPAREN); - putback(LPAREN); + pushs1(p->defn); /* defn string */ + pushs1(p->name); /* macro name */ + pushs(ep); /* start next..*/ + + if (l != LPAREN && PARLEV == 0) { + /* no bracks */ + chrsave(EOS); + + if (sp == STACKMAX) + errx(1, "internal stack overflow"); + eval((const char **) mstack+fp+1, 2, + CALTYP); + + ep = PREVEP; /* flush strspace */ + sp = PREVSP; /* previous sp.. */ + fp = PREVFP; /* rewind stack...*/ } } - } - else if (t == EOF) { - if (sp > -1) - errx(1, "unexpected end of input"); + } else if (t == EOF) { + if (sp > -1) { + warnx( "unexpected end of input, unclosed parenthesis:"); + dump_stack(paren, PARLEV); + exit(1); + } if (ilevel <= 0) break; /* all done thanks.. */ - --ilevel; - (void) fclose(infile[ilevel+1]); + release_input(infile+ilevel--); free(inname[ilevel+1]); bufbase = bbase[ilevel]; emitline(); continue; } /* - * non-alpha single-char token seen.. + * non-alpha token possibly seen.. * [the order of else if .. stmts is important.] */ - else if (t == lquote) { /* strip quotes */ - nlpar = 1; + else if (LOOK_AHEAD(t,lquote)) { /* strip quotes */ + nlpar = 0; + record(quotes, nlpar++); + /* + * Opening quote: scan forward until matching + * closing quote has been found. + */ do { - if ((l = gpbc()) == rquote) - nlpar--; - else if (l == lquote) - nlpar++; - else if (l == EOF) - errx(1, "missing right quote"); - if (nlpar > 0) { - if (sp < 0) - putc(l, active); + + l = gpbc(); + if (LOOK_AHEAD(l,rquote)) { + if (--nlpar > 0) + outputstr(rquote); + } else if (LOOK_AHEAD(l,lquote)) { + record(quotes, nlpar++); + outputstr(lquote); + } else if (l == EOF) { + if (nlpar == 1) + warnx("unclosed quote:"); else - chrsave(l); + warnx("%d unclosed quotes:", nlpar); + dump_stack(quotes, nlpar); + exit(1); + } else { + if (nlpar > 0) { + if (sp < 0) + putc(l, active); + else + CHRSAVE(l); + } } } while (nlpar != 0); } - else if (sp < 0) { /* not in a macro at all */ - if (t == scommt) { /* comment handling here */ + else if (sp < 0 && LOOK_AHEAD(t, scommt)) { + fputs(scommt, active); + + for(;;) { + t = gpbc(); + if (LOOK_AHEAD(t, ecommt)) { + fputs(ecommt, active); + break; + } + if (t == EOF) + break; putc(t, active); - while ((t = gpbc()) != ecommt) - putc(t, active); } + } + + else if (sp < 0) { /* not in a macro at all */ putc(t, active); /* output directly.. */ } @@ -338,10 +439,10 @@ macro() { case LPAREN: if (PARLEV > 0) chrsave(t); - while ((l = gpbc()) != EOF && isspace(l)) + while (isspace(l = gpbc())) ; /* skip blank, tab, nl.. */ putback(l); - PARLEV++; + record(paren, PARLEV++); break; case RPAREN: @@ -353,10 +454,8 @@ macro() { if (sp == STACKMAX) errx(1, "internal stack overflow"); - if (CALTYP == MACRTYPE) - expand((char **) mstack+fp+1, sp-fp); - else - eval((char **) mstack+fp+1, sp-fp, CALTYP); + eval((const char **) mstack+fp+1, sp-fp, + CALTYP); ep = PREVEP; /* flush strspace */ sp = PREVSP; /* previous sp.. */ @@ -367,7 +466,7 @@ macro() { case COMMA: if (PARLEV == 1) { chrsave(EOS); /* new argument */ - while ((l = gpbc()) != EOF && isspace(l)) + while (isspace(l = gpbc())) ; putback(l); pushs(ep); @@ -376,71 +475,184 @@ macro() { break; default: - chrsave(t); /* stack the char */ + if (LOOK_AHEAD(t, scommt)) { + char *p; + for (p = scommt; *p; p++) + chrsave(*p); + for(;;) { + t = gpbc(); + if (LOOK_AHEAD(t, ecommt)) { + for (p = ecommt; *p; p++) + chrsave(*p); + break; + } + if (t == EOF) + break; + CHRSAVE(t); + } + } else + CHRSAVE(t); /* stack the char */ break; } } } +/* + * output string directly, without pushing it for reparses. + */ +void +outputstr(s) + const char *s; +{ + if (sp < 0) + while (*s) + putc(*s++, active); + else + while (*s) + CHRSAVE(*s++); +} + /* * build an input token.. * consider only those starting with _ or A-Za-z. This is a * combo with lookup to speed things up. */ -ndptr -inspect(tp) -register char *tp; +static ndptr +inspect(c, tp) + int c; + char *tp; { - register int c; - register char *name = tp; - register char *etp = tp+MAXTOK; - register ndptr p; - register unsigned long h = 0; - - while ((c = gpbc()) != EOF && (isalnum(c) || c == '_') && tp < etp) + char *name = tp; + char *etp = tp+MAXTOK; + ndptr p; + unsigned int h; + + h = *tp++ = c; + + while ((isalnum(c = gpbc()) || c == '_') && tp < etp) h = (h << 5) + h + (*tp++ = c); - putback(c); - if (tp == etp) - errx(1, "token too long"); - + if (c != EOF) + PUTBACK(c); *tp = EOS; + /* token is too long, it won't match anything, but it can still + * be output. */ + if (tp == ep) { + outputstr(name); + while (isalnum(c = gpbc()) || c == '_') { + if (sp < 0) + putc(c, active); + else + CHRSAVE(c); + } + *name = EOS; + return nil; + } - for (p = hashtab[h%HASHSIZE]; p != nil; p = p->nxtptr) - if (STREQ(name, p->name)) + for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr) + if (h == p->hv && STREQ(name, p->name)) break; return p; } /* - * initkwds - initialise m4 keywords as fast as possible. + * initkwds - initialise m4 keywords as fast as possible. * This very similar to install, but without certain overheads, - * such as calling lookup. Malloc is not used for storing the - * keyword strings, since we simply use the static pointers + * such as calling lookup. Malloc is not used for storing the + * keyword strings, since we simply use the static pointers * within keywrds block. */ -void -initkwds() { - register int i; - register int h; - register ndptr p; +static void +initkwds() +{ + size_t i; + unsigned int h; + ndptr p; for (i = 0; i < MAXKEYS; i++) { h = hash(keywrds[i].knam); - if ((p = malloc(sizeof(struct ndblock))) == NULL) - err(1, "malloc"); - p->nxtptr = hashtab[h]; - hashtab[h] = p; - p->name = keywrds[i].knam; + p = (ndptr) xalloc(sizeof(struct ndblock)); + p->nxtptr = hashtab[h % HASHSIZE]; + hashtab[h % HASHSIZE] = p; + p->name = xstrdup(keywrds[i].knam); p->defn = null; - p->type = keywrds[i].ktyp | STATIC; + p->hv = h; + p->type = keywrds[i].ktyp & TYPEMASK; + if ((keywrds[i].ktyp & NOARGS) == 0) + p->type |= NEEDARGS; + } +} + +/* Look up a builtin type, even if overridden by the user */ +int +builtin_type(key) + const char *key; +{ + int i; + + for (i = 0; i != MAXKEYS; i++) + if (STREQ(keywrds[i].knam, key)) + return keywrds[i].ktyp; + return -1; +} + +char * +builtin_realname(n) + int n; +{ + int i; + + for (i = 0; i != MAXKEYS; i++) + if (((keywrds[i].ktyp ^ n) & TYPEMASK) == 0) + return keywrds[i].knam; + return NULL; +} + +static void +record(t, lev) + struct position *t; + int lev; +{ + if (lev < MAXRECORD) { + t[lev].name = CURRENT_NAME; + t[lev].line = CURRENT_LINE; } } +static void +dump_stack(t, lev) + struct position *t; + int lev; +{ + int i; + + for (i = 0; i < lev; i++) { + if (i == MAXRECORD) { + fprintf(stderr, " ...\n"); + break; + } + fprintf(stderr, " %s at line %lu\n", + t[i].name, t[i].line); + } +} + + +static void +enlarge_stack() +{ + STACKMAX *= 2; + mstack = realloc(mstack, sizeof(stae) * STACKMAX); + sstack = realloc(sstack, STACKMAX); + if (mstack == NULL || sstack == NULL) + errx(1, "Evaluation stack overflow (%lu)", + (unsigned long)STACKMAX); +} + /* Emit preprocessor #line directive if -s option used. */ void emitline(void) { + if (synccpp) fprintf(active, "#line %d \"%s\"\n", inlineno[ilevel], - inname[ilevel]); + inname[ilevel]); } diff --git a/usr.bin/m4/mdef.h b/usr.bin/m4/mdef.h index 604833f..a8864120 100644 --- a/usr.bin/m4/mdef.h +++ b/usr.bin/m4/mdef.h @@ -1,3 +1,6 @@ +/* $OpenBSD: mdef.h,v 1.21 2001/09/27 11:40:33 espie Exp $ */ +/* $NetBSD: mdef.h,v 1.7 1996/01/13 23:25:27 pk Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -70,13 +73,27 @@ #define SYSVTYPE 31 #define EXITTYPE 32 #define DEFNTYPE 33 - -#define STATIC 128 +#define SELFTYPE 34 +#define INDIRTYPE 35 +#define BUILTINTYPE 36 +#define PATSTYPE 37 +#define FILENAMETYPE 38 +#define LINETYPE 39 +#define REGEXPTYPE 40 +#define ESYSCMDTYPE 41 +#define TRACEONTYPE 42 +#define TRACEOFFTYPE 43 + + +#define TYPEMASK 63 /* Keep bits really corresponding to a type. */ +#define RECDEF 256 /* Pure recursive def, don't expand it */ +#define NOARGS 512 /* builtin needs no args */ +#define NEEDARGS 1024 /* mark builtin that need args with this */ /* * m4 special characters */ - + #define ARGFLAG '$' #define LPAREN '(' #define RPAREN ')' @@ -94,19 +111,19 @@ * other important constants */ -#define EOS (char) 0 -#define MAXINP 10 /* maximum include files */ -#define MAXOUT 10 /* maximum # of diversions */ -#define MAXSTR 512 /* maximum size of string */ -#define BUFSIZE 4096 /* size of pushback buffer */ -#define STACKMAX 1024 /* size of call stack */ -#define STRSPMAX 4096 /* size of string space */ -#define MAXTOK MAXSTR /* maximum chars in a tokn */ -#define HASHSIZE 199 /* maximum size of hashtab */ - +#define EOS '\0' +#define MAXINP 10 /* maximum include files */ +#define MAXOUT 10 /* maximum # of diversions */ +#define BUFSIZE 4096 /* starting size of pushback buffer */ +#define INITSTACKMAX 4096 /* starting size of call stack */ +#define STRSPMAX 4096 /* starting size of string space */ +#define MAXTOK 512 /* maximum chars in a tokn */ +#define HASHSIZE 199 /* maximum size of hashtab */ +#define MAXCCHARS 5 /* max size of comment/quote delim */ + #define ALL 1 #define TOP 0 - + #define TRUE 1 #define FALSE 0 #define cycle for(;;) @@ -114,18 +131,19 @@ /* * m4 data structures */ - + typedef struct ndblock *ndptr; - -struct ndblock { /* hastable structure */ - char *name; /* entry name.. */ - char *defn; /* definition.. */ - int type; /* type of the entry.. */ - ndptr nxtptr; /* link to next entry.. */ + +struct ndblock { /* hastable structure */ + char *name; /* entry name.. */ + char *defn; /* definition.. */ + unsigned int type; /* type of the entry.. */ + unsigned int hv; /* hash function value.. */ + ndptr nxtptr; /* link to next entry.. */ }; - + #define nil ((ndptr) 0) - + struct keyblk { char *knam; /* keyword name */ int ktyp; /* keyword type */ @@ -136,6 +154,15 @@ typedef union { /* stack structure */ char *sstr; /* string entry */ } stae; +struct input_file { + FILE *file; + char *name; + unsigned long lineno; + int c; +}; + +#define CURRENT_NAME (infile[ilevel].name) +#define CURRENT_LINE (infile[ilevel].lineno) /* * macros for readibility and/or speed * @@ -144,10 +171,31 @@ typedef union { /* stack structure */ * pushs() - push a string pointer onto stack */ #define gpbc() (bp > bufbase) ? (*--bp ? *bp : EOF) : \ - ((chscratch = getc(infile[ilevel])) == '\n' && ++inlineno[ilevel], \ - chscratch) -#define pushf(x) if (sp < STACKMAX) mstack[++sp].sfra = (x) -#define pushs(x) if (sp < STACKMAX) mstack[++sp].sstr = (x) + ((chscratch = obtain_char(infile+ilevel)) == '\n' && \ + ++inlineno[ilevel], chscratch) +#define pushf(x) \ + do { \ + if (++sp == STACKMAX) \ + enlarge_stack();\ + mstack[sp].sfra = (x); \ + sstack[sp] = 0; \ + } while (0) + +#define pushs(x) \ + do { \ + if (++sp == STACKMAX) \ + enlarge_stack();\ + mstack[sp].sstr = (x); \ + sstack[sp] = 1; \ + } while (0) + +#define pushs1(x) \ + do { \ + if (++sp == STACKMAX) \ + enlarge_stack();\ + mstack[sp].sstr = (x); \ + sstack[sp] = 0; \ + } while (0) /* * . . diff --git a/usr.bin/m4/misc.c b/usr.bin/m4/misc.c index 323de00..d554d29 100644 --- a/usr.bin/m4/misc.c +++ b/usr.bin/m4/misc.c @@ -1,3 +1,6 @@ +/* $OpenBSD: misc.c,v 1.26 2001/11/16 23:50:40 deraadt Exp $ */ +/* $NetBSD: misc.c,v 1.6 1995/09/28 05:37:41 tls Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -34,59 +37,66 @@ * SUCH DAMAGE. */ -#ifndef lint -#if 0 -static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include <sys/cdefs.h> +__SCCSID("@(#)misc.c 8.1 (Berkeley) 6/6/93"); +__RCSID_SOURCE("$OpenBSD: misc.c,v 1.26 2001/11/16 23:50:40 deraadt Exp $"); +__FBSDID("$FreeBSD$"); #include <sys/types.h> -#include <err.h> +#include <errno.h> +#include <unistd.h> #include <stdio.h> #include <stdlib.h> +#include <stddef.h> #include <string.h> -#include <unistd.h> +#include <err.h> #include "mdef.h" #include "stdd.h" #include "extern.h" #include "pathnames.h" + +char *ep; /* first free char in strspace */ +static char *strspace; /* string space for evaluation */ +char *endest; /* end of string space */ +static size_t strsize = STRSPMAX; +static size_t bufsize = BUFSIZE; + +char *buf; /* push-back buffer */ +char *bufbase; /* the base for current ilevel */ +char *bbase[MAXINP]; /* the base for each ilevel */ +char *bp; /* first available character */ +char *endpbb; /* end of push-back buffer */ + + /* * find the index of second str in the first str. */ -int +ptrdiff_t indx(s1, s2) -char *s1; -char *s2; + const char *s1; + const char *s2; { - register char *t; - register char *p; - register char *m; + char *t; - for (p = s1; *p; p++) { - for (t = p, m = s2; *m && *m == *t; m++, t++); - if (!*m) - return (p - s1); - } - return (-1); + t = strstr(s1, s2); + if (t == NULL) + return (-1); + else + return (t - s1); } /* * putback - push character back onto input */ void putback(c) -int c; + int c; { if (c == EOF) - c = 0; - else if (c == 0) return; - if (bp < endpbb) - *bp++ = c; - else - errx(1, "too many characters pushed back"); + if (bp >= endpbb) + enlarge_bufspace(); + *bp++ = c; } /* @@ -96,22 +106,15 @@ int c; */ void pbstr(s) -register unsigned char *s; + const char *s; { - register unsigned char *es; - register unsigned char *zp; - - es = s; - zp = bp; + size_t n; - while (*es) - es++; - es--; - while (es >= s) - if (zp < endpbb) - *zp++ = *es--; - if ((bp = zp) == endpbb) - errx(1, "too many characters pushed back"); + n = strlen(s); + while (endpbb - bp <= n) + enlarge_bufspace(); + while (n > 0) + *bp++ = s[--n]; } /* @@ -119,9 +122,9 @@ register unsigned char *s; */ void pbnum(n) -int n; + int n; { - register int num; + int num; num = (n < 0) ? -n : n; do { @@ -134,16 +137,83 @@ int n; } /* + * pbunsigned - convert unsigned long to string, push back on input. + */ +void +pbunsigned(n) + unsigned long n; +{ + do { + putback(n % 10 + '0'); + } + while ((n /= 10) > 0); +} + +void +initspaces() +{ + int i; + + strspace = xalloc(strsize+1); + ep = strspace; + endest = strspace+strsize; + buf = (char *)xalloc(bufsize); + bufbase = buf; + bp = buf; + endpbb = buf + bufsize; + for (i = 0; i < MAXINP; i++) + bbase[i] = buf; +} + +void +enlarge_strspace() +{ + char *newstrspace; + int i; + + strsize *= 2; + newstrspace = malloc(strsize + 1); + if (!newstrspace) + errx(1, "string space overflow"); + memcpy(newstrspace, strspace, strsize/2); + for (i = 0; i <= sp; i++) + if (sstack[i]) + mstack[i].sstr = (mstack[i].sstr - strspace) + + newstrspace; + ep = (ep-strspace) + newstrspace; + free(strspace); + strspace = newstrspace; + endest = strspace + strsize; +} + +void +enlarge_bufspace() +{ + char *newbuf; + int i; + + bufsize *= 2; + newbuf = realloc(buf, bufsize); + if (!newbuf) + errx(1, "too many characters pushed back"); + for (i = 0; i < MAXINP; i++) + bbase[i] = (bbase[i]-buf)+newbuf; + bp = (bp-buf)+newbuf; + bufbase = (bufbase-buf)+newbuf; + buf = newbuf; + endpbb = buf+bufsize; +} + +/* * chrsave - put single char on string space */ void chrsave(c) -char c; + int c; { - if (ep < endest) - *ep++ = c; - else - errx(1, "string space overflow"); + if (ep >= endest) + enlarge_strspace(); + *ep++ = c; } /* @@ -151,36 +221,26 @@ char c; */ void getdiv(n) -int n; + int n; { - register int c; - register FILE *dfil; + int c; if (active == outfile[n]) errx(1, "undivert: diversion still active"); + rewind(outfile[n]); + while ((c = getc(outfile[n])) != EOF) + putc(c, active); (void) fclose(outfile[n]); outfile[n] = NULL; - m4temp[UNIQUE] = n + '0'; - if ((dfil = fopen(m4temp, "r")) == NULL) - errx(1, "%s: cannot undivert", m4temp); - else - while ((c = getc(dfil)) != EOF) - putc(c, active); - (void) fclose(dfil); - -#ifdef vms - if (remove(m4temp)) -#else - if (unlink(m4temp) == -1) -#endif - errx(1, "%s: cannot unlink", m4temp); } void onintr(signo) int signo; { - errx(1, "interrupted"); +#define intrmessage "m4: interrupted.\n" + write(STDERR_FILENO, intrmessage, sizeof(intrmessage)-1); + _exit(1); } /* @@ -189,37 +249,132 @@ onintr(signo) void killdiv() { - register int n; + int n; - for (n = 0; n < MAXOUT; n++) + for (n = 0; n < maxout; n++) if (outfile[n] != NULL) { (void) fclose(outfile[n]); - m4temp[UNIQUE] = n + '0'; -#ifdef vms - (void) remove(m4temp); -#else - (void) unlink(m4temp); -#endif } } +/* + * resizedivs: allocate more diversion files */ void -cleanup(n) -int n; -{ - if (outfile[0] != NULL) { - (void) fclose(outfile[0]); - outfile[0] = NULL; - m4temp[UNIQUE] = '0'; - (void) remove(m4temp); - } - (void) remove(m4dir); +resizedivs(n) + int n; +{ + int i; + + outfile = (FILE **)realloc(outfile, sizeof(FILE *) * n); + if (outfile == NULL) + errx(1, "too many diverts %d", n); + for (i = maxout; i < n; i++) + outfile[i] = NULL; + maxout = n; +} + +void * +xalloc(n) + size_t n; +{ + char *p = malloc(n); + + if (p == NULL) + err(1, "malloc"); + return p; +} + +char * +xstrdup(s) + const char *s; +{ + char *p = strdup(s); + if (p == NULL) + err(1, "strdup"); + return p; } void usage() { fprintf(stderr, -"usage: m4 [-s] [-D name[=val]]... [-U name]... file...\n"); +"usage: m4 [-d flags] [-t name] [-gs] [-D name[=value]]...\n" +" [-U name]... [-I dirname]... file...\n"); exit(1); } + +int +obtain_char(f) + struct input_file *f; +{ + if (f->c == EOF) + return EOF; + else if (f->c == '\n') + f->lineno++; + + f->c = fgetc(f->file); + return f->c; +} + +void +set_input(f, real, name) + struct input_file *f; + FILE *real; + const char *name; +{ + f->file = real; + f->lineno = 1; + f->c = 0; + f->name = xstrdup(name); +} + +void +release_input(f) + struct input_file *f; +{ + if (f->file != stdin) + fclose(f->file); + f->c = EOF; + /* + * XXX can't free filename, as there might still be + * error information pointing to it. + */ +} + +void +doprintlineno(f) + struct input_file *f; +{ + pbunsigned(f->lineno); +} + +void +doprintfilename(f) + struct input_file *f; +{ + pbstr(rquote); + pbstr(f->name); + pbstr(lquote); +} + +/* + * buffer_mark/dump_buffer: allows one to save a mark in a buffer, + * and later dump everything that was added since then to a file. + */ +size_t +buffer_mark() +{ + return bp - buf; +} + + +void +dump_buffer(f, m) + FILE *f; + size_t m; +{ + char *s; + + for (s = bp; s-buf > m;) + fputc(*--s, f); +} diff --git a/usr.bin/m4/pathnames.h b/usr.bin/m4/pathnames.h index 3983cf6..043190c 100644 --- a/usr.bin/m4/pathnames.h +++ b/usr.bin/m4/pathnames.h @@ -1,3 +1,6 @@ +/* $OpenBSD: pathnames.h,v 1.4 1997/04/04 18:41:29 deraadt Exp $ */ +/* $NetBSD: pathnames.h,v 1.6 1995/09/29 00:27:55 cgd Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -47,10 +50,9 @@ #define UNIQUE 3 /* unique char location */ #endif -#ifdef unix -#define _PATH_DIVDIRNAME "/tmp/m4XXXXXX" /* directory for files */ -#define _PATH_DIVNAME "m4.0" /* unix diversion files */ -#define UNIQUE 17 /* unique char location */ +#if defined(unix) || defined(__NetBSD__) || defined(__OpenBSD__) +#define _PATH_DIVNAME "/tmp/m4.0XXXXXXXXXX" /* unix diversion files */ +#define UNIQUE 8 /* unique char location */ #endif #ifdef vms diff --git a/usr.bin/m4/stdd.h b/usr.bin/m4/stdd.h index 8d4312e..733aa59 100644 --- a/usr.bin/m4/stdd.h +++ b/usr.bin/m4/stdd.h @@ -1,3 +1,6 @@ +/* $OpenBSD: stdd.h,v 1.4 1999/11/09 18:16:18 deraadt Exp $ */ +/* $NetBSD: stdd.h,v 1.2 1995/09/28 05:37:50 tls Exp $ */ + /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -34,6 +37,7 @@ * SUCH DAMAGE. * * @(#)stdd.h 8.1 (Berkeley) 6/6/93 + * $FreeBSD$ */ /* @@ -45,9 +49,9 @@ #define iswhite(c) ((c) == ' ' || (c) == '\t') -/* - * STREQ is an optimised strcmp(a,b)==0 - * STREQN is an optimised strncmp(a,b,n)==0; assumes n > 0 +/* + * STREQ is an optimised strcmp(a,b)==0 + * STREQN is an optimised strncmp(a,b,n)==0; assumes n > 0 */ #define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) #define STREQN(a, b, n) ((a)[0] == (b)[0] && strncmp(a, b, n) == 0) diff --git a/usr.bin/m4/trace.c b/usr.bin/m4/trace.c index 231667e..181e999 100644 --- a/usr.bin/m4/trace.c +++ b/usr.bin/m4/trace.c @@ -24,6 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/types.h> #include <stddef.h> #include <stdio.h> @@ -33,7 +36,7 @@ #include "stdd.h" #include "extern.h" -FILE *traceout = stderr; +FILE *traceout; int traced_macros = 0; |