Vendor import of bwk's 01-May-2007 release.

Approved by:	delphij (mentor)
Nodded by:	ru
Tested by:	make universe
This commit is contained in:
Rong-En Fan 2007-06-05 15:33:51 +00:00
parent c263f9bff0
commit addad6af5a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/one-true-awk/dist/; revision=170331
11 changed files with 202 additions and 145 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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;
@ -309,7 +312,7 @@ char *cclenter(const char *argp) /* add a character class */
continue;
}
while (c < c2) {
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++ = ++c;
i++;
@ -317,7 +320,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++;
@ -339,6 +342,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);
@ -375,11 +379,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! */
@ -389,6 +394,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++;
@ -465,7 +474,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
@ -496,7 +505,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
@ -554,7 +563,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
@ -601,9 +610,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);
@ -627,6 +637,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)));
@ -666,7 +679,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);
@ -787,7 +800,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++) == '\\') {
@ -806,7 +819,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;
@ -855,6 +868,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;

View File

@ -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 );

View File

@ -40,9 +40,9 @@ char *fields;
int fieldssize = RECSIZE;
Cell **fldtab; /* pointers to Cells */
char inputFS[100] = " ";
char inputFS[10] = " ";
#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++;

View File

@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
const char *version = "version 20050424";
const char *version = "version 20070501";
#define DEBUG
#include <stdio.h>
@ -61,14 +61,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;
@ -107,20 +114,12 @@ int main(int argc, char *argv[])
if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
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;

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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;