MFC: bwk's 01-May-2007 release
This commit is contained in:
parent
1ea17145e8
commit
518dde115f
@ -25,6 +25,50 @@ THIS SOFTWARE.
|
||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||
was sent to the printers in August, 1987.
|
||||
|
||||
May 1, 2007:
|
||||
fiddle in makefile to fix for BSD make; thanks to igor sobrado.
|
||||
|
||||
Mar 31, 2007:
|
||||
fixed some null pointer refs calling adjbuf.
|
||||
|
||||
Feb 21, 2007:
|
||||
fixed a bug in matching the null RE in sub and gsub. thanks to al aho
|
||||
who actually did the fix (in b.c), and to wolfgang seeberg for finding
|
||||
it and providing a very compact test case.
|
||||
|
||||
fixed quotation in b.c; thanks to Hal Pratt and the Princeton Dante
|
||||
Project.
|
||||
|
||||
removed some no-effect asserts in run.c.
|
||||
|
||||
fiddled maketab.c to not complain about bison-generated values.
|
||||
|
||||
removed the obsolete -V argument; fixed --version to print the
|
||||
version and exit.
|
||||
|
||||
fixed wording and an outright error in the usage message; thanks to igor
|
||||
sobrado and jason mcintyre.
|
||||
|
||||
fixed a bug in -d that caused core dump if no program followed.
|
||||
|
||||
Jan 1, 2007:
|
||||
dropped mac.code from makefile; there are few non-MacOSX
|
||||
mac's these days.
|
||||
|
||||
Jan 17, 2006:
|
||||
system() not flagged as unsafe in the unadvertised -safe option.
|
||||
found it while enhancing tests before shipping the ;login: article.
|
||||
practice what you preach.
|
||||
|
||||
removed the 9-years-obsolete -mr and -mf flags.
|
||||
|
||||
added -version and --version options.
|
||||
|
||||
core dump on linux with BEGIN {nextfile}, now fixed.
|
||||
|
||||
removed some #ifdef's in run.c and lex.c that appear to no
|
||||
longer be necessary.
|
||||
|
||||
Apr 24, 2005:
|
||||
modified lib.c so that values of $0 et al are preserved in the END
|
||||
block, apparently as required by posix. thanks to havard eidnes
|
||||
|
@ -6,7 +6,7 @@ Peter Weinberger (Addison-Wesley, 1988, ISBN 0-201-07981-X).
|
||||
|
||||
Original sources were taken from the Brian Kernighan's home page
|
||||
(http://cm.bell-labs.com/who/bwk/) and include bug fixes up thru
|
||||
April 24, 2005.
|
||||
May 01, 2007.
|
||||
|
||||
The following files were removed for this import:
|
||||
|
||||
@ -21,4 +21,4 @@ The following files were removed for this import:
|
||||
|
||||
The vendor import was done by:
|
||||
|
||||
cvs import src/contrib/one-true-awk BELL_LABS bwk_20050424
|
||||
cvs import src/contrib/one-true-awk BELL_LABS bwk_20070501
|
||||
|
@ -30,7 +30,7 @@ typedef double Awkfloat;
|
||||
|
||||
typedef unsigned char uschar;
|
||||
|
||||
#define xfree(a) { if ((a) != NULL) { free((char *) a); a = NULL; } }
|
||||
#define xfree(a) { if ((a) != NULL) { free((void *) (a)); (a) = NULL; } }
|
||||
|
||||
#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf
|
||||
*/
|
||||
|
@ -50,7 +50,7 @@ Node *arglist = 0; /* list of args for current function */
|
||||
%token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']'
|
||||
%token <i> ARRAY
|
||||
%token <i> MATCH NOTMATCH MATCHOP
|
||||
%token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS
|
||||
%token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS EMPTYRE
|
||||
%token <i> AND BOR APPEND EQ GE GT LE LT NE IN
|
||||
%token <i> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC
|
||||
%token <i> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT NEXTFILE
|
||||
|
@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
/* lasciate ogne speranza, voi ch'entrate. */
|
||||
/* lasciate ogne speranza, voi ch'intrate. */
|
||||
|
||||
#define DEBUG
|
||||
|
||||
@ -44,10 +44,11 @@ THIS SOFTWARE.
|
||||
#define parent(v) (v)->nnext
|
||||
|
||||
#define LEAF case CCL: case NCCL: case CHAR: case DOT: case FINAL: case ALL:
|
||||
#define ELEAF case EMPTYRE: /* empty string in regexp */
|
||||
#define UNARY case STAR: case PLUS: case QUEST:
|
||||
|
||||
/* encoding in tree Nodes:
|
||||
leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL):
|
||||
leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL, EMPTYRE):
|
||||
left is index, right contains value or pointer to value
|
||||
unary (STAR, PLUS, QUEST): left is child, right is null
|
||||
binary (CAT, OR): left and right are children
|
||||
@ -182,6 +183,7 @@ int makeinit(fa *f, int anchor)
|
||||
void penter(Node *p) /* set up parent pointers and leaf indices */
|
||||
{
|
||||
switch (type(p)) {
|
||||
ELEAF
|
||||
LEAF
|
||||
info(p) = poscnt;
|
||||
poscnt++;
|
||||
@ -206,6 +208,7 @@ void penter(Node *p) /* set up parent pointers and leaf indices */
|
||||
void freetr(Node *p) /* free parse tree */
|
||||
{
|
||||
switch (type(p)) {
|
||||
ELEAF
|
||||
LEAF
|
||||
xfree(p);
|
||||
break;
|
||||
@ -324,7 +327,7 @@ char *cclenter(const char *argp) /* add a character class */
|
||||
if ((collate_range_cmp(c, j) > 0) ||
|
||||
collate_range_cmp(j, c2) > 0)
|
||||
continue;
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0))
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
|
||||
FATAL("out of space for character class [%.10s...] 2", p);
|
||||
*bp++ = j;
|
||||
i++;
|
||||
@ -332,7 +335,7 @@ char *cclenter(const char *argp) /* add a character class */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, 0))
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2"))
|
||||
FATAL("out of space for character class [%.10s...] 3", p);
|
||||
*bp++ = c;
|
||||
i++;
|
||||
@ -354,6 +357,7 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo
|
||||
int *p;
|
||||
|
||||
switch (type(v)) {
|
||||
ELEAF
|
||||
LEAF
|
||||
f->re[info(v)].ltype = type(v);
|
||||
f->re[info(v)].lval.np = right(v);
|
||||
@ -390,11 +394,12 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo
|
||||
}
|
||||
|
||||
int first(Node *p) /* collects initially active leaves of p into setvec */
|
||||
/* returns 1 if p matches empty string */
|
||||
/* returns 0 if p matches empty string */
|
||||
{
|
||||
int b, lp;
|
||||
|
||||
switch (type(p)) {
|
||||
ELEAF
|
||||
LEAF
|
||||
lp = info(p); /* look for high-water mark of subscripts */
|
||||
while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */
|
||||
@ -404,6 +409,10 @@ int first(Node *p) /* collects initially active leaves of p into setvec */
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("out of space in first()");
|
||||
}
|
||||
if (type(p) == EMPTYRE) {
|
||||
setvec[lp] = 0;
|
||||
return(0);
|
||||
}
|
||||
if (setvec[lp] != 1) {
|
||||
setvec[lp] = 1;
|
||||
setcnt++;
|
||||
@ -480,7 +489,7 @@ int match(fa *f, const char *p0) /* shortest match ? */
|
||||
if (f->out[s])
|
||||
return(1);
|
||||
do {
|
||||
assert(*p < NCHARS);
|
||||
/* assert(*p < NCHARS); */
|
||||
if ((ns = f->gototab[s][*p]) != 0)
|
||||
s = ns;
|
||||
else
|
||||
@ -511,7 +520,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
do {
|
||||
if (f->out[s]) /* final state */
|
||||
patlen = q-p;
|
||||
assert(*q < NCHARS);
|
||||
/* assert(*q < NCHARS); */
|
||||
if ((ns = f->gototab[s][*q]) != 0)
|
||||
s = ns;
|
||||
else
|
||||
@ -569,7 +578,7 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||
do {
|
||||
if (f->out[s]) /* final state */
|
||||
patlen = q-p;
|
||||
assert(*q < NCHARS);
|
||||
/* assert(*q < NCHARS); */
|
||||
if ((ns = f->gototab[s][*q]) != 0)
|
||||
s = ns;
|
||||
else
|
||||
@ -616,9 +625,10 @@ Node *reparse(const char *p) /* parses regular expression pointed to by p */
|
||||
lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */
|
||||
rtok = relex();
|
||||
/* GNU compatibility: an empty regexp matches anything */
|
||||
if (rtok == '\0')
|
||||
if (rtok == '\0') {
|
||||
/* FATAL("empty regular expression"); previous */
|
||||
return(op2(ALL, NIL, NIL));
|
||||
return(op2(EMPTYRE, NIL, NIL));
|
||||
}
|
||||
np = regexp();
|
||||
if (rtok != '\0')
|
||||
FATAL("syntax error in regular expression %s at %s", lastre, prestr);
|
||||
@ -642,6 +652,9 @@ Node *primary(void)
|
||||
case ALL:
|
||||
rtok = relex();
|
||||
return (unary(op2(ALL, NIL, NIL)));
|
||||
case EMPTYRE:
|
||||
rtok = relex();
|
||||
return (unary(op2(ALL, NIL, NIL)));
|
||||
case DOT:
|
||||
rtok = relex();
|
||||
return (unary(op2(DOT, NIL, NIL)));
|
||||
@ -681,7 +694,7 @@ Node *primary(void)
|
||||
Node *concat(Node *np)
|
||||
{
|
||||
switch (rtok) {
|
||||
case CHAR: case DOT: case ALL: case CCL: case NCCL: case '$': case '(':
|
||||
case CHAR: case DOT: case ALL: case EMPTYRE: case CCL: case NCCL: case '$': case '(':
|
||||
return (concat(op2(CAT, np, primary())));
|
||||
}
|
||||
return (np);
|
||||
@ -802,7 +815,7 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
else
|
||||
cflag = 0;
|
||||
n = 2 * strlen((const char *) prestr)+1;
|
||||
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0))
|
||||
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1"))
|
||||
FATAL("out of space for reg expr %.10s...", lastre);
|
||||
for (; ; ) {
|
||||
if ((c = *prestr++) == '\\') {
|
||||
@ -821,7 +834,7 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
prestr[2 + cc->cc_namelen] == ']') {
|
||||
prestr += cc->cc_namelen + 3;
|
||||
for (i = 0; i < NCHARS; i++) {
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, 0))
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2"))
|
||||
FATAL("out of space for reg expr %.10s...", lastre);
|
||||
if (cc->cc_func(i)) {
|
||||
*bp++ = i;
|
||||
@ -870,6 +883,7 @@ int cgoto(fa *f, int s, int c)
|
||||
if ((k == CHAR && c == ptoi(f->re[p[i]].lval.np))
|
||||
|| (k == DOT && c != 0 && c != HAT)
|
||||
|| (k == ALL && c != 0)
|
||||
|| (k == EMPTYRE && c != 0)
|
||||
|| (k == CCL && member(c, (char *) f->re[p[i]].lval.up))
|
||||
|| (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) {
|
||||
q = f->re[p[i]].lfollow;
|
||||
|
@ -89,12 +89,7 @@ Keyword keywords[] ={ /* keep sorted: binary searched */
|
||||
{ "while", WHILE, WHILE },
|
||||
};
|
||||
|
||||
#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define RET(x) { if(dbg)printf("lex %s\n", tokname(x)); return(x); }
|
||||
#else
|
||||
#define RET(x) return(x)
|
||||
#endif
|
||||
|
||||
int peek(void)
|
||||
{
|
||||
@ -122,7 +117,7 @@ int gettok(char **pbuf, int *psz) /* get next input token */
|
||||
if (isalpha(c) || c == '_') { /* it's a varname */
|
||||
for ( ; (c = input()) != 0; ) {
|
||||
if (bp-buf >= sz)
|
||||
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, 0))
|
||||
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, "gettok"))
|
||||
FATAL( "out of space for name %.10s...", buf );
|
||||
if (isalnum(c) || c == '_')
|
||||
*bp++ = c;
|
||||
@ -139,7 +134,7 @@ int gettok(char **pbuf, int *psz) /* get next input token */
|
||||
/* read input until can't be a number */
|
||||
for ( ; (c = input()) != 0; ) {
|
||||
if (bp-buf >= sz)
|
||||
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, 0))
|
||||
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, "gettok"))
|
||||
FATAL( "out of space for number %.10s...", buf );
|
||||
if (isdigit(c) || c == 'e' || c == 'E'
|
||||
|| c == '.' || c == '+' || c == '-')
|
||||
@ -176,7 +171,7 @@ int yylex(void)
|
||||
{
|
||||
int c;
|
||||
static char *buf = 0;
|
||||
static int bufsize = 500;
|
||||
static int bufsize = 5; /* BUG: setting this small causes core dump! */
|
||||
|
||||
if (buf == 0 && (buf = (char *) malloc(bufsize)) == NULL)
|
||||
FATAL( "out of space in yylex" );
|
||||
@ -188,10 +183,8 @@ int yylex(void)
|
||||
reg = 0;
|
||||
return regexpr();
|
||||
}
|
||||
/* printf("top\n"); */
|
||||
for (;;) {
|
||||
c = gettok(&buf, &bufsize);
|
||||
/* printf("gettok [%s]\n", buf); */
|
||||
if (c == 0)
|
||||
return 0;
|
||||
if (isalpha(c) || c == '_')
|
||||
@ -371,7 +364,7 @@ int string(void)
|
||||
if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL)
|
||||
FATAL("out of space for strings");
|
||||
for (bp = buf; (c = input()) != '"'; ) {
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, 0))
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, "string"))
|
||||
FATAL("out of space for string %.10s...", buf);
|
||||
switch (c) {
|
||||
case '\n':
|
||||
@ -465,12 +458,13 @@ int word(char *w)
|
||||
int c, n;
|
||||
|
||||
n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0]));
|
||||
/* BUG: this ought to be inside the if; in theory could fault (daniel barrett) */
|
||||
kp = keywords + n;
|
||||
if (n != -1) { /* found in table */
|
||||
yylval.i = kp->sub;
|
||||
switch (kp->type) { /* special handling */
|
||||
case FSYSTEM:
|
||||
if (safe)
|
||||
case BLTIN:
|
||||
if (kp->sub == FSYSTEM && safe)
|
||||
SYNTAX( "system is unsafe" );
|
||||
RET(kp->type);
|
||||
case FUNC:
|
||||
@ -518,7 +512,7 @@ int regexpr(void)
|
||||
FATAL("out of space for rex expr");
|
||||
bp = buf;
|
||||
for ( ; (c = input()) != '/' && c != 0; ) {
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, 0))
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
|
||||
FATAL("out of space for reg expr %.10s...", buf);
|
||||
if (c == '\n') {
|
||||
SYNTAX( "newline in regular expression %.10s...", buf );
|
||||
|
@ -42,7 +42,7 @@ int fieldssize = RECSIZE;
|
||||
Cell **fldtab; /* pointers to Cells */
|
||||
char inputFS[100] = " ";
|
||||
|
||||
#define MAXFLD 200
|
||||
#define MAXFLD 2
|
||||
int nfields = MAXFLD; /* last allocated slot for $i */
|
||||
|
||||
int donefld; /* 1 = implies rec broken into fields */
|
||||
@ -173,7 +173,7 @@ int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
|
||||
|
||||
void nextfile(void)
|
||||
{
|
||||
if (infile != stdin)
|
||||
if (infile != NULL && infile != stdin)
|
||||
fclose(infile);
|
||||
infile = NULL;
|
||||
argno++;
|
||||
|
@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
const char *version = "version 20050424 (FreeBSD)";
|
||||
const char *version = "version 20070501 (FreeBSD)";
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
@ -62,14 +62,21 @@ int main(int argc, char *argv[])
|
||||
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
||||
cmdname = argv[0];
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
|
||||
fprintf(stderr,
|
||||
"usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n",
|
||||
cmdname);
|
||||
exit(1);
|
||||
}
|
||||
signal(SIGFPE, fpecatch);
|
||||
yyin = NULL;
|
||||
symtab = makesymtab(NSYMTAB);
|
||||
symtab = makesymtab(NSYMTAB/NSYMTAB);
|
||||
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
|
||||
if (strcmp(argv[1], "--") == 0) { /* explicit end of args */
|
||||
if (strcmp(argv[1],"-version") == 0 || strcmp(argv[1],"--version") == 0) {
|
||||
printf("awk %s\n", version);
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
if (strncmp(argv[1], "--", 2) == 0) { /* explicit end of args */
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
@ -119,20 +126,12 @@ int main(int argc, char *argv[])
|
||||
setclvar(argv[1]);
|
||||
}
|
||||
break;
|
||||
case 'm': /* more memory: -mr=record, -mf=fields */
|
||||
/* no longer supported */
|
||||
WARNING("obsolete option %s ignored", argv[1]);
|
||||
break;
|
||||
case 'd':
|
||||
dbg = atoi(&argv[1][2]);
|
||||
if (dbg == 0)
|
||||
dbg = 1;
|
||||
printf("awk %s\n", version);
|
||||
break;
|
||||
case 'V': /* added for exptools "standard" */
|
||||
printf("awk %s\n", version);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
WARNING("unknown option %s ignored", argv[1]);
|
||||
break;
|
||||
|
@ -27,10 +27,12 @@ CFLAGS = -O2
|
||||
CFLAGS =
|
||||
|
||||
CC = gcc -Wall -g -Wwrite-strings
|
||||
CC = gcc -fprofile-arcs -ftest-coverage
|
||||
# followed by gcov onefile.c; cat onefile.c.gcov
|
||||
CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
|
||||
CC = gcc -Wall -g
|
||||
CC = cc
|
||||
CC = gcc -O4
|
||||
CC = gcc -Wall -g
|
||||
|
||||
|
||||
YACC = bison -y
|
||||
YACC = yacc
|
||||
@ -45,7 +47,7 @@ LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c \
|
||||
lib.c run.c tran.c missing95.c
|
||||
|
||||
SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win \
|
||||
vcvars32.bat buildwin.bat mac.code awk.1
|
||||
vcvars32.bat buildwin.bat awk.1
|
||||
|
||||
a.out: ytab.o $(OFILES)
|
||||
$(CC) $(CFLAGS) ytab.o $(OFILES) $(ALLOC) -lm
|
||||
@ -83,4 +85,4 @@ names:
|
||||
@echo $(LISTING)
|
||||
|
||||
clean:
|
||||
rm -f a.out *.o *.obj maketab maketab.exe *.bb *.bbg *.da *.gcov # proctab.c
|
||||
rm -f a.out *.o *.obj maketab maketab.exe *.bb *.bbg *.da *.gcov *.gcno *.gcda # proctab.c
|
||||
|
@ -135,7 +135,7 @@ int main(int argc, char *argv[])
|
||||
if (c != '#' || (n != 4 && strcmp(def,"define") != 0)) /* not a valid #define */
|
||||
continue;
|
||||
if (tok < FIRSTTOKEN || tok > LASTTOKEN) {
|
||||
fprintf(stderr, "maketab funny token %d %s ignored\n", tok, buf);
|
||||
/* fprintf(stderr, "maketab funny token %d %s ignored\n", tok, buf); */
|
||||
continue;
|
||||
}
|
||||
names[tok-FIRSTTOKEN] = (char *) malloc(strlen(name)+1);
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
|
||||
static char *printname[92] = {
|
||||
static char *printname[93] = {
|
||||
(char *) "FIRSTTOKEN", /* 258 */
|
||||
(char *) "PROGRAM", /* 259 */
|
||||
(char *) "PASTAT", /* 260 */
|
||||
@ -24,81 +24,82 @@ static char *printname[92] = {
|
||||
(char *) "STAR", /* 276 */
|
||||
(char *) "QUEST", /* 277 */
|
||||
(char *) "PLUS", /* 278 */
|
||||
(char *) "AND", /* 279 */
|
||||
(char *) "BOR", /* 280 */
|
||||
(char *) "APPEND", /* 281 */
|
||||
(char *) "EQ", /* 282 */
|
||||
(char *) "GE", /* 283 */
|
||||
(char *) "GT", /* 284 */
|
||||
(char *) "LE", /* 285 */
|
||||
(char *) "LT", /* 286 */
|
||||
(char *) "NE", /* 287 */
|
||||
(char *) "IN", /* 288 */
|
||||
(char *) "ARG", /* 289 */
|
||||
(char *) "BLTIN", /* 290 */
|
||||
(char *) "BREAK", /* 291 */
|
||||
(char *) "CLOSE", /* 292 */
|
||||
(char *) "CONTINUE", /* 293 */
|
||||
(char *) "DELETE", /* 294 */
|
||||
(char *) "DO", /* 295 */
|
||||
(char *) "EXIT", /* 296 */
|
||||
(char *) "FOR", /* 297 */
|
||||
(char *) "FUNC", /* 298 */
|
||||
(char *) "SUB", /* 299 */
|
||||
(char *) "GSUB", /* 300 */
|
||||
(char *) "IF", /* 301 */
|
||||
(char *) "INDEX", /* 302 */
|
||||
(char *) "LSUBSTR", /* 303 */
|
||||
(char *) "MATCHFCN", /* 304 */
|
||||
(char *) "NEXT", /* 305 */
|
||||
(char *) "NEXTFILE", /* 306 */
|
||||
(char *) "ADD", /* 307 */
|
||||
(char *) "MINUS", /* 308 */
|
||||
(char *) "MULT", /* 309 */
|
||||
(char *) "DIVIDE", /* 310 */
|
||||
(char *) "MOD", /* 311 */
|
||||
(char *) "ASSIGN", /* 312 */
|
||||
(char *) "ASGNOP", /* 313 */
|
||||
(char *) "ADDEQ", /* 314 */
|
||||
(char *) "SUBEQ", /* 315 */
|
||||
(char *) "MULTEQ", /* 316 */
|
||||
(char *) "DIVEQ", /* 317 */
|
||||
(char *) "MODEQ", /* 318 */
|
||||
(char *) "POWEQ", /* 319 */
|
||||
(char *) "PRINT", /* 320 */
|
||||
(char *) "PRINTF", /* 321 */
|
||||
(char *) "SPRINTF", /* 322 */
|
||||
(char *) "ELSE", /* 323 */
|
||||
(char *) "INTEST", /* 324 */
|
||||
(char *) "CONDEXPR", /* 325 */
|
||||
(char *) "POSTINCR", /* 326 */
|
||||
(char *) "PREINCR", /* 327 */
|
||||
(char *) "POSTDECR", /* 328 */
|
||||
(char *) "PREDECR", /* 329 */
|
||||
(char *) "VAR", /* 330 */
|
||||
(char *) "IVAR", /* 331 */
|
||||
(char *) "VARNF", /* 332 */
|
||||
(char *) "CALL", /* 333 */
|
||||
(char *) "NUMBER", /* 334 */
|
||||
(char *) "STRING", /* 335 */
|
||||
(char *) "REGEXPR", /* 336 */
|
||||
(char *) "GETLINE", /* 337 */
|
||||
(char *) "SUBSTR", /* 338 */
|
||||
(char *) "SPLIT", /* 339 */
|
||||
(char *) "RETURN", /* 340 */
|
||||
(char *) "WHILE", /* 341 */
|
||||
(char *) "CAT", /* 342 */
|
||||
(char *) "UMINUS", /* 343 */
|
||||
(char *) "NOT", /* 344 */
|
||||
(char *) "POWER", /* 345 */
|
||||
(char *) "INCR", /* 346 */
|
||||
(char *) "DECR", /* 347 */
|
||||
(char *) "INDIRECT", /* 348 */
|
||||
(char *) "LASTTOKEN", /* 349 */
|
||||
(char *) "EMPTYRE", /* 279 */
|
||||
(char *) "AND", /* 280 */
|
||||
(char *) "BOR", /* 281 */
|
||||
(char *) "APPEND", /* 282 */
|
||||
(char *) "EQ", /* 283 */
|
||||
(char *) "GE", /* 284 */
|
||||
(char *) "GT", /* 285 */
|
||||
(char *) "LE", /* 286 */
|
||||
(char *) "LT", /* 287 */
|
||||
(char *) "NE", /* 288 */
|
||||
(char *) "IN", /* 289 */
|
||||
(char *) "ARG", /* 290 */
|
||||
(char *) "BLTIN", /* 291 */
|
||||
(char *) "BREAK", /* 292 */
|
||||
(char *) "CLOSE", /* 293 */
|
||||
(char *) "CONTINUE", /* 294 */
|
||||
(char *) "DELETE", /* 295 */
|
||||
(char *) "DO", /* 296 */
|
||||
(char *) "EXIT", /* 297 */
|
||||
(char *) "FOR", /* 298 */
|
||||
(char *) "FUNC", /* 299 */
|
||||
(char *) "SUB", /* 300 */
|
||||
(char *) "GSUB", /* 301 */
|
||||
(char *) "IF", /* 302 */
|
||||
(char *) "INDEX", /* 303 */
|
||||
(char *) "LSUBSTR", /* 304 */
|
||||
(char *) "MATCHFCN", /* 305 */
|
||||
(char *) "NEXT", /* 306 */
|
||||
(char *) "NEXTFILE", /* 307 */
|
||||
(char *) "ADD", /* 308 */
|
||||
(char *) "MINUS", /* 309 */
|
||||
(char *) "MULT", /* 310 */
|
||||
(char *) "DIVIDE", /* 311 */
|
||||
(char *) "MOD", /* 312 */
|
||||
(char *) "ASSIGN", /* 313 */
|
||||
(char *) "ASGNOP", /* 314 */
|
||||
(char *) "ADDEQ", /* 315 */
|
||||
(char *) "SUBEQ", /* 316 */
|
||||
(char *) "MULTEQ", /* 317 */
|
||||
(char *) "DIVEQ", /* 318 */
|
||||
(char *) "MODEQ", /* 319 */
|
||||
(char *) "POWEQ", /* 320 */
|
||||
(char *) "PRINT", /* 321 */
|
||||
(char *) "PRINTF", /* 322 */
|
||||
(char *) "SPRINTF", /* 323 */
|
||||
(char *) "ELSE", /* 324 */
|
||||
(char *) "INTEST", /* 325 */
|
||||
(char *) "CONDEXPR", /* 326 */
|
||||
(char *) "POSTINCR", /* 327 */
|
||||
(char *) "PREINCR", /* 328 */
|
||||
(char *) "POSTDECR", /* 329 */
|
||||
(char *) "PREDECR", /* 330 */
|
||||
(char *) "VAR", /* 331 */
|
||||
(char *) "IVAR", /* 332 */
|
||||
(char *) "VARNF", /* 333 */
|
||||
(char *) "CALL", /* 334 */
|
||||
(char *) "NUMBER", /* 335 */
|
||||
(char *) "STRING", /* 336 */
|
||||
(char *) "REGEXPR", /* 337 */
|
||||
(char *) "GETLINE", /* 338 */
|
||||
(char *) "SUBSTR", /* 339 */
|
||||
(char *) "SPLIT", /* 340 */
|
||||
(char *) "RETURN", /* 341 */
|
||||
(char *) "WHILE", /* 342 */
|
||||
(char *) "CAT", /* 343 */
|
||||
(char *) "UMINUS", /* 344 */
|
||||
(char *) "NOT", /* 345 */
|
||||
(char *) "POWER", /* 346 */
|
||||
(char *) "INCR", /* 347 */
|
||||
(char *) "DECR", /* 348 */
|
||||
(char *) "INDIRECT", /* 349 */
|
||||
(char *) "LASTTOKEN", /* 350 */
|
||||
};
|
||||
|
||||
|
||||
Cell *(*proctab[92])(Node **, int) = {
|
||||
Cell *(*proctab[93])(Node **, int) = {
|
||||
nullproc, /* FIRSTTOKEN */
|
||||
program, /* PROGRAM */
|
||||
pastat, /* PASTAT */
|
||||
@ -120,6 +121,7 @@ Cell *(*proctab[92])(Node **, int) = {
|
||||
nullproc, /* STAR */
|
||||
nullproc, /* QUEST */
|
||||
nullproc, /* PLUS */
|
||||
nullproc, /* EMPTYRE */
|
||||
boolop, /* AND */
|
||||
boolop, /* BOR */
|
||||
nullproc, /* APPEND */
|
||||
|
@ -49,19 +49,20 @@ void tempfree(Cell *p) {
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef _NFILE
|
||||
#ifndef FOPEN_MAX
|
||||
#define FOPEN_MAX _NFILE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FOPEN_MAX
|
||||
#define FOPEN_MAX 40 /* max number of open files */
|
||||
#endif
|
||||
|
||||
#ifndef RAND_MAX
|
||||
#define RAND_MAX 32767 /* all that ansi guarantees */
|
||||
#endif
|
||||
/* do we really need these? */
|
||||
/* #ifdef _NFILE */
|
||||
/* #ifndef FOPEN_MAX */
|
||||
/* #define FOPEN_MAX _NFILE */
|
||||
/* #endif */
|
||||
/* #endif */
|
||||
/* */
|
||||
/* #ifndef FOPEN_MAX */
|
||||
/* #define FOPEN_MAX 40 */ /* max number of open files */
|
||||
/* #endif */
|
||||
/* */
|
||||
/* #ifndef RAND_MAX */
|
||||
/* #define RAND_MAX 32767 */ /* all that ansi guarantees */
|
||||
/* #endif */
|
||||
|
||||
jmp_buf env;
|
||||
extern int pairstack[];
|
||||
@ -110,6 +111,7 @@ int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
|
||||
if (rminlen)
|
||||
minlen += quantum - rminlen;
|
||||
tbuf = (char *) realloc(*pbuf, minlen);
|
||||
dprintf( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) );
|
||||
if (tbuf == NULL) {
|
||||
if (whatrtn)
|
||||
FATAL("out of memory in %s", whatrtn);
|
||||
@ -463,7 +465,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
|
||||
for (np = a[1]; np; np = np->nnext) {
|
||||
y = execute(np); /* subscript */
|
||||
s = getsval(y);
|
||||
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, 0))
|
||||
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array"))
|
||||
FATAL("out of memory for %s[%s...]", x->nval, buf);
|
||||
strcat(buf, s);
|
||||
if (np->nnext)
|
||||
@ -510,7 +512,7 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
|
||||
for (np = a[1]; np; np = np->nnext) {
|
||||
y = execute(np); /* subscript */
|
||||
s = getsval(y);
|
||||
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, 0))
|
||||
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete"))
|
||||
FATAL("out of memory deleting %s[%s...]", x->nval, buf);
|
||||
strcat(buf, s);
|
||||
if (np->nnext)
|
||||
@ -549,7 +551,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
|
||||
for (p = a[0]; p; p = p->nnext) {
|
||||
x = execute(p); /* expr */
|
||||
s = getsval(x);
|
||||
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, 0))
|
||||
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest"))
|
||||
FATAL("out of memory deleting %s[%s...]", x->nval, buf);
|
||||
strcat(buf, s);
|
||||
tempfree(x);
|
||||
@ -819,7 +821,7 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
if ((fmt = (char *) malloc(fmtsz)) == NULL)
|
||||
FATAL("out of memory in format()");
|
||||
while (*s) {
|
||||
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format");
|
||||
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1");
|
||||
if (*s != '%') {
|
||||
*p++ = *s++;
|
||||
continue;
|
||||
@ -833,9 +835,9 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
fmtwd = atoi(s+1);
|
||||
if (fmtwd < 0)
|
||||
fmtwd = -fmtwd;
|
||||
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
|
||||
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format2");
|
||||
for (t = fmt; (*t++ = *s) != '\0'; s++) {
|
||||
if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, 0))
|
||||
if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, "format3"))
|
||||
FATAL("format item %.30s... ran format() out of memory", os);
|
||||
if (isalpha((uschar)*s) && *s != 'l' && *s != 'h' && *s != 'L')
|
||||
break; /* the ansi panoply */
|
||||
@ -853,7 +855,7 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
*t = '\0';
|
||||
if (fmtwd < 0)
|
||||
fmtwd = -fmtwd;
|
||||
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
|
||||
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format4");
|
||||
|
||||
switch (*s) {
|
||||
case 'f': case 'e': case 'g': case 'E': case 'G':
|
||||
@ -887,14 +889,14 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
n = MAXNUMSIZE;
|
||||
if (fmtwd > n)
|
||||
n = fmtwd;
|
||||
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format");
|
||||
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5");
|
||||
switch (flag) {
|
||||
case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */
|
||||
t = getsval(x);
|
||||
n = strlen(t);
|
||||
if (fmtwd > n)
|
||||
n = fmtwd;
|
||||
adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format");
|
||||
adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6");
|
||||
p += strlen(p);
|
||||
sprintf(p, "%s", t);
|
||||
break;
|
||||
@ -906,7 +908,7 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
n = strlen(t);
|
||||
if (fmtwd > n)
|
||||
n = fmtwd;
|
||||
if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, 0))
|
||||
if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7"))
|
||||
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);
|
||||
sprintf(p, fmt, t);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user