Apply all our changes including newer fixes to WARNS?=4
This commit is contained in:
parent
35f471cb95
commit
5642d0040b
18
external/historical/nawk/dist/awk.h
vendored
18
external/historical/nawk/dist/awk.h
vendored
@ -48,6 +48,7 @@ extern int safe; /* 0 => unsafe, 1 => safe */
|
||||
#define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */
|
||||
extern int recsize; /* size of current record, orig RECSIZE */
|
||||
|
||||
extern char EMPTY[];
|
||||
extern char **FS;
|
||||
extern char **RS;
|
||||
extern char **ORS;
|
||||
@ -61,16 +62,15 @@ extern char **SUBSEP;
|
||||
extern Awkfloat *RSTART;
|
||||
extern Awkfloat *RLENGTH;
|
||||
|
||||
extern char *record; /* points to $0 */
|
||||
extern uschar *record; /* points to $0 */
|
||||
extern int lineno; /* line number in awk program */
|
||||
extern int errorflag; /* 1 if error has occurred */
|
||||
extern int donefld; /* 1 if record broken into fields */
|
||||
extern int donerec; /* 1 if record is valid (no fld has changed */
|
||||
extern char inputFS[]; /* FS at time of input, for field splitting */
|
||||
|
||||
extern int dbg;
|
||||
|
||||
extern char *patbeg; /* beginning of pattern matched */
|
||||
extern uschar *patbeg; /* beginning of pattern matched */
|
||||
extern int patlen; /* length of pattern matched. set in b.c */
|
||||
|
||||
/* Cell: all information about a variable or constant */
|
||||
@ -126,6 +126,8 @@ extern Cell *rlengthloc; /* RLENGTH */
|
||||
#define FTOUPPER 12
|
||||
#define FTOLOWER 13
|
||||
#define FFLUSH 14
|
||||
#define FSYSTIME 15
|
||||
#define FSTRFTIME 16
|
||||
|
||||
/* Node: parse tree is made of nodes, with Cell's at bottom */
|
||||
|
||||
@ -203,8 +205,6 @@ extern int pairstack[], paircnt;
|
||||
|
||||
#define NCHARS (256+3) /* 256 handles 8-bit chars; 128 does 7-bit */
|
||||
/* watch out in match(), etc. */
|
||||
#define NSTATES 32
|
||||
|
||||
typedef struct rrow {
|
||||
long ltype; /* long avoids pointer warnings on 64-bit */
|
||||
union {
|
||||
@ -216,16 +216,16 @@ typedef struct rrow {
|
||||
} rrow;
|
||||
|
||||
typedef struct fa {
|
||||
uschar gototab[NSTATES][NCHARS];
|
||||
uschar out[NSTATES];
|
||||
unsigned int **gototab;
|
||||
uschar *out;
|
||||
uschar *restr;
|
||||
int *posns[NSTATES];
|
||||
int **posns;
|
||||
int state_count;
|
||||
int anchor;
|
||||
int use;
|
||||
int initstat;
|
||||
int curstat;
|
||||
int accept;
|
||||
int reset;
|
||||
struct rrow re[1]; /* variable: actual size set by calling malloc */
|
||||
} fa;
|
||||
|
||||
|
22
external/historical/nawk/dist/awkgram.y
vendored
22
external/historical/nawk/dist/awkgram.y
vendored
@ -23,6 +23,10 @@ THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
%{
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "awk.h"
|
||||
@ -80,7 +84,7 @@ Node *arglist = 0; /* list of args for current function */
|
||||
%left GETLINE
|
||||
%nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|'
|
||||
%left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FUNC
|
||||
%left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER
|
||||
%left GENSUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER
|
||||
%left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR
|
||||
%left REGEXPR VAR VARNF IVAR WHILE '('
|
||||
%left CAT
|
||||
@ -369,6 +373,22 @@ term:
|
||||
| INCR var { $$ = op1(PREINCR, $2); }
|
||||
| var DECR { $$ = op1(POSTDECR, $1); }
|
||||
| var INCR { $$ = op1(POSTINCR, $1); }
|
||||
| GENSUB '(' reg_expr comma pattern comma pattern ')'
|
||||
{ $$ = op5(GENSUB, NIL, (Node*)makedfa($3, 1), $5, $7, rectonode()); }
|
||||
| GENSUB '(' pattern comma pattern comma pattern ')'
|
||||
{ if (constnode($3))
|
||||
$$ = op5(GENSUB, NIL, (Node *)makedfa(strnode($3), 1), $5, $7, rectonode());
|
||||
else
|
||||
$$ = op5(GENSUB, (Node *)1, $3, $5, $7, rectonode());
|
||||
}
|
||||
| GENSUB '(' reg_expr comma pattern comma pattern comma pattern ')'
|
||||
{ $$ = op5(GENSUB, NIL, (Node*)makedfa($3, 1), $5, $7, $9); }
|
||||
| GENSUB '(' pattern comma pattern comma pattern comma pattern ')'
|
||||
{ if (constnode($3))
|
||||
$$ = op5(GENSUB, NIL, (Node *)makedfa(strnode($3),1), $5,$7,$9);
|
||||
else
|
||||
$$ = op5(GENSUB, (Node *)1, $3, $5, $7, $9);
|
||||
}
|
||||
| GETLINE var LT term { $$ = op3(GETLINE, $2, itonp($3), $4); }
|
||||
| GETLINE LT term { $$ = op3(GETLINE, NIL, itonp($2), $3); }
|
||||
| GETLINE var { $$ = op3(GETLINE, $2, NIL, NIL); }
|
||||
|
293
external/historical/nawk/dist/b.c
vendored
293
external/historical/nawk/dist/b.c
vendored
@ -24,14 +24,19 @@ THIS SOFTWARE.
|
||||
|
||||
/* lasciate ogne speranza, voi ch'intrate. */
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
#define HAT (NCHARS+2) /* matches ^ in regular expr */
|
||||
/* NCHARS is 2**n */
|
||||
@ -62,33 +67,80 @@ int maxsetvec = 0;
|
||||
|
||||
int rtok; /* next token in current re */
|
||||
int rlxval;
|
||||
static uschar *rlxstr;
|
||||
static uschar *prestr; /* current position in current re */
|
||||
static uschar *lastre; /* origin of last re */
|
||||
static const uschar *rlxstr;
|
||||
static const uschar *prestr; /* current position in current re */
|
||||
static const uschar *lastre; /* origin of last re */
|
||||
|
||||
static int setcnt;
|
||||
static int poscnt;
|
||||
|
||||
char *patbeg;
|
||||
uschar *patbeg;
|
||||
int patlen;
|
||||
|
||||
#define NFA 20 /* cache this many dynamic fa's */
|
||||
#define NFA 128 /* cache this many dynamic fa's */
|
||||
fa *fatab[NFA];
|
||||
int nfatab = 0; /* entries in fatab */
|
||||
|
||||
static void
|
||||
resizesetvec(const char *msg)
|
||||
{
|
||||
if (maxsetvec == 0)
|
||||
maxsetvec = MAXLIN;
|
||||
else
|
||||
maxsetvec *= 4;
|
||||
setvec = realloc(setvec, maxsetvec * sizeof(*setvec));
|
||||
tmpset = realloc(tmpset, maxsetvec * sizeof(*tmpset));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
resize_state(fa *f, int state)
|
||||
{
|
||||
void *p;
|
||||
int i, new_count;
|
||||
|
||||
if (++state < f->state_count)
|
||||
return;
|
||||
|
||||
new_count = state + 10; /* needs to be tuned */
|
||||
|
||||
p = realloc(f->gototab, new_count * sizeof(f->gototab[0]));
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
f->gototab = p;
|
||||
|
||||
p = realloc(f->out, new_count * sizeof(f->out[0]));
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
f->out = p;
|
||||
|
||||
p = realloc(f->posns, new_count * sizeof(f->posns[0]));
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
f->posns = p;
|
||||
|
||||
for (i = f->state_count; i < new_count; ++i) {
|
||||
f->gototab[i] = calloc(1, NCHARS * sizeof (**f->gototab));
|
||||
if (f->gototab[i] == NULL)
|
||||
goto out;
|
||||
f->out[i] = 0;
|
||||
f->posns[i] = NULL;
|
||||
}
|
||||
f->state_count = new_count;
|
||||
return;
|
||||
out:
|
||||
overflo("out of memory in resize_state");
|
||||
}
|
||||
|
||||
fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
|
||||
{
|
||||
int i, use, nuse;
|
||||
fa *pfa;
|
||||
static int now = 1;
|
||||
|
||||
if (setvec == 0) { /* first time through any RE */
|
||||
maxsetvec = MAXLIN;
|
||||
setvec = (int *) malloc(maxsetvec * sizeof(int));
|
||||
tmpset = (int *) malloc(maxsetvec * sizeof(int));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("out of space initializing makedfa");
|
||||
}
|
||||
if (setvec == 0) /* first time through any RE */
|
||||
resizesetvec("out of space initializing makedfa");
|
||||
|
||||
if (compile_time) /* a constant for sure */
|
||||
return mkdfa(s, anchor);
|
||||
@ -132,14 +184,15 @@ fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */
|
||||
|
||||
poscnt = 0;
|
||||
penter(p1); /* enter parent pointers and leaf indices */
|
||||
if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL)
|
||||
if ((f = calloc(1, sizeof(*f) + poscnt*sizeof(rrow))) == NULL)
|
||||
overflo("out of space for fa");
|
||||
f->accept = poscnt-1; /* penter has computed number of positions in re */
|
||||
cfoll(f, p1); /* set up follow sets */
|
||||
freetr(p1);
|
||||
if ((f->posns[0] = (int *) calloc(1, *(f->re[0].lfollow)*sizeof(int))) == NULL)
|
||||
resize_state(f, 1);
|
||||
if ((f->posns[0] = calloc(1, *(f->re[0].lfollow)*sizeof(int))) == NULL)
|
||||
overflo("out of space in makedfa");
|
||||
if ((f->posns[1] = (int *) calloc(1, sizeof(int))) == NULL)
|
||||
if ((f->posns[1] = calloc(1, sizeof(int))) == NULL)
|
||||
overflo("out of space in makedfa");
|
||||
*f->posns[1] = 0;
|
||||
f->initstat = makeinit(f, anchor);
|
||||
@ -152,12 +205,12 @@ int makeinit(fa *f, int anchor)
|
||||
{
|
||||
int i, k;
|
||||
|
||||
resize_state(f, 2);
|
||||
f->curstat = 2;
|
||||
f->out[2] = 0;
|
||||
f->reset = 0;
|
||||
k = *(f->re[0].lfollow);
|
||||
xfree(f->posns[2]);
|
||||
if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL)
|
||||
if ((f->posns[2] = calloc(1, (k+1)*sizeof(int))) == NULL)
|
||||
overflo("out of space in makeinit");
|
||||
for (i=0; i <= k; i++) {
|
||||
(f->posns[2])[i] = (f->re[0].lfollow)[i];
|
||||
@ -174,8 +227,10 @@ int makeinit(fa *f, int anchor)
|
||||
}
|
||||
|
||||
f->out[0] = f->out[2];
|
||||
if (f->curstat != 2)
|
||||
if (f->curstat != 2) {
|
||||
resize_state(f, f->curstat);
|
||||
--(*f->posns[f->curstat]);
|
||||
}
|
||||
}
|
||||
return f->curstat;
|
||||
}
|
||||
@ -231,13 +286,13 @@ void freetr(Node *p) /* free parse tree */
|
||||
/* in the parsing of regular expressions, metacharacters like . have */
|
||||
/* to be seen literally; \056 is not a metacharacter. */
|
||||
|
||||
int hexstr(char **pp) /* find and eval hex string at pp, return new p */
|
||||
int hexstr(const uschar **pp) /* find and eval hex string at pp, return new p */
|
||||
{ /* only pick up one 8-bit byte (2 chars) */
|
||||
uschar *p;
|
||||
const uschar *p;
|
||||
int n = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0, p = (uschar *) *pp; i < 2 && isxdigit(*p); i++, p++) {
|
||||
for (i = 0, p = *pp; i < 2 && isxdigit(*p); i++, p++) {
|
||||
if (isdigit(*p))
|
||||
n = 16 * n + *p - '0';
|
||||
else if (*p >= 'a' && *p <= 'f')
|
||||
@ -245,16 +300,16 @@ int hexstr(char **pp) /* find and eval hex string at pp, return new p */
|
||||
else if (*p >= 'A' && *p <= 'F')
|
||||
n = 16 * n + *p - 'A' + 10;
|
||||
}
|
||||
*pp = (char *) p;
|
||||
*pp = p;
|
||||
return n;
|
||||
}
|
||||
|
||||
#define isoctdigit(c) ((c) >= '0' && (c) <= '7') /* multiple use of arg */
|
||||
|
||||
int quoted(char **pp) /* pick up next thing after a \\ */
|
||||
int quoted(const uschar **pp) /* pick up next thing after a \\ */
|
||||
/* and increment *pp */
|
||||
{
|
||||
char *p = *pp;
|
||||
const uschar *p = *pp;
|
||||
int c;
|
||||
|
||||
if ((c = *p++) == 't')
|
||||
@ -288,31 +343,32 @@ int quoted(char **pp) /* pick up next thing after a \\ */
|
||||
char *cclenter(const char *argp) /* add a character class */
|
||||
{
|
||||
int i, c, c2;
|
||||
uschar *p = (uschar *) argp;
|
||||
uschar *op, *bp;
|
||||
const uschar *p = (const uschar *) argp;
|
||||
const uschar *op;
|
||||
uschar *bp;
|
||||
static uschar *buf = 0;
|
||||
static int bufsz = 100;
|
||||
|
||||
op = p;
|
||||
if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)
|
||||
if (buf == 0 && (buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of space for character class [%.10s...] 1", p);
|
||||
bp = buf;
|
||||
for (i = 0; (c = *p++) != 0; ) {
|
||||
if (c == '\\') {
|
||||
c = quoted((char **) &p);
|
||||
c = quoted(&p);
|
||||
} else if (c == '-' && i > 0 && bp[-1] != 0) {
|
||||
if (*p != 0) {
|
||||
c = bp[-1];
|
||||
c2 = *p++;
|
||||
if (c2 == '\\')
|
||||
c2 = quoted((char **) &p);
|
||||
c2 = quoted(&p);
|
||||
if (c > c2) { /* empty; ignore */
|
||||
bp--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
while (c < c2) {
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+2, 100, &bp, "cclenter1"))
|
||||
FATAL("out of space for character class [%.10s...] 2", p);
|
||||
*bp++ = ++c;
|
||||
i++;
|
||||
@ -320,14 +376,14 @@ char *cclenter(const char *argp) /* add a character class */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2"))
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+2, 100, &bp, "cclenter2"))
|
||||
FATAL("out of space for character class [%.10s...] 3", p);
|
||||
*bp++ = c;
|
||||
i++;
|
||||
}
|
||||
*bp = 0;
|
||||
dprintf( ("cclenter: in = |%s|, out = |%s|\n", op, buf) );
|
||||
xfree(op);
|
||||
free(__UNCONST(op));
|
||||
return (char *) tostring((char *) buf);
|
||||
}
|
||||
|
||||
@ -346,18 +402,13 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo
|
||||
LEAF
|
||||
f->re[info(v)].ltype = type(v);
|
||||
f->re[info(v)].lval.np = right(v);
|
||||
while (f->accept >= maxsetvec) { /* guessing here! */
|
||||
maxsetvec *= 4;
|
||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("out of space in cfoll()");
|
||||
}
|
||||
while (f->accept >= maxsetvec) /* guessing here! */
|
||||
resizesetvec("out of space in cfoll()");
|
||||
for (i = 0; i <= f->accept; i++)
|
||||
setvec[i] = 0;
|
||||
setcnt = 0;
|
||||
follow(v); /* computes setvec and setcnt */
|
||||
if ((p = (int *) calloc(1, (setcnt+1)*sizeof(int))) == NULL)
|
||||
if ((p = calloc(1, (setcnt+1)*sizeof(int))) == NULL)
|
||||
overflo("out of space building follow set");
|
||||
f->re[info(v)].lfollow = p;
|
||||
*p = setcnt;
|
||||
@ -387,13 +438,8 @@ int first(Node *p) /* collects initially active leaves of p into setvec */
|
||||
ELEAF
|
||||
LEAF
|
||||
lp = info(p); /* look for high-water mark of subscripts */
|
||||
while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */
|
||||
maxsetvec *= 4;
|
||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("out of space in first()");
|
||||
}
|
||||
while (setcnt >= maxsetvec || lp >= maxsetvec) /* guessing here! */
|
||||
resizesetvec("out of space in first()");
|
||||
if (type(p) == EMPTYRE) {
|
||||
setvec[lp] = 0;
|
||||
return(0);
|
||||
@ -457,7 +503,7 @@ void follow(Node *v) /* collects leaves that can follow v into setvec */
|
||||
|
||||
int member(int c, const char *sarg) /* is c in s? */
|
||||
{
|
||||
uschar *s = (uschar *) sarg;
|
||||
const uschar *s = (const uschar *) sarg;
|
||||
|
||||
while (*s)
|
||||
if (c == *s++)
|
||||
@ -468,9 +514,11 @@ int member(int c, const char *sarg) /* is c in s? */
|
||||
int match(fa *f, const char *p0) /* shortest match ? */
|
||||
{
|
||||
int s, ns;
|
||||
uschar *p = (uschar *) p0;
|
||||
const uschar *p = (const uschar *) p0;
|
||||
|
||||
s = f->initstat;
|
||||
assert (s < f->state_count);
|
||||
|
||||
s = f->reset ? makeinit(f,0) : f->initstat;
|
||||
if (f->out[s])
|
||||
return(1);
|
||||
do {
|
||||
@ -479,6 +527,9 @@ int match(fa *f, const char *p0) /* shortest match ? */
|
||||
s = ns;
|
||||
else
|
||||
s = cgoto(f, s, *p);
|
||||
|
||||
assert (s < f->state_count);
|
||||
|
||||
if (f->out[s])
|
||||
return(1);
|
||||
} while (*p++ != 0);
|
||||
@ -488,17 +539,12 @@ int match(fa *f, const char *p0) /* shortest match ? */
|
||||
int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
{
|
||||
int s, ns;
|
||||
uschar *p = (uschar *) p0;
|
||||
uschar *p = __UNCONST(p0);
|
||||
uschar *q;
|
||||
int i, k;
|
||||
|
||||
/* s = f->reset ? makeinit(f,1) : f->initstat; */
|
||||
if (f->reset) {
|
||||
f->initstat = s = makeinit(f,1);
|
||||
} else {
|
||||
s = f->initstat;
|
||||
}
|
||||
patbeg = (char *) p;
|
||||
s = f->initstat;
|
||||
assert(s < f->state_count);
|
||||
patbeg = p;
|
||||
patlen = -1;
|
||||
do {
|
||||
q = p;
|
||||
@ -510,9 +556,12 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
s = ns;
|
||||
else
|
||||
s = cgoto(f, s, *q);
|
||||
|
||||
assert(s < f->state_count);
|
||||
|
||||
if (s == 1) { /* no transition */
|
||||
if (patlen >= 0) {
|
||||
patbeg = (char *) p;
|
||||
patbeg = p;
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
@ -522,24 +571,11 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
if (f->out[s])
|
||||
patlen = q-p-1; /* don't count $ */
|
||||
if (patlen >= 0) {
|
||||
patbeg = (char *) p;
|
||||
patbeg = p;
|
||||
return(1);
|
||||
}
|
||||
nextin:
|
||||
s = 2;
|
||||
if (f->reset) {
|
||||
for (i = 2; i <= f->curstat; i++)
|
||||
xfree(f->posns[i]);
|
||||
k = *f->posns[0];
|
||||
if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL)
|
||||
overflo("out of space in pmatch");
|
||||
for (i = 0; i <= k; i++)
|
||||
(f->posns[2])[i] = (f->posns[0])[i];
|
||||
f->initstat = f->curstat = 2;
|
||||
f->out[2] = f->out[0];
|
||||
for (i = 0; i < NCHARS; i++)
|
||||
f->gototab[2][i] = 0;
|
||||
}
|
||||
} while (*p++ != 0);
|
||||
return (0);
|
||||
}
|
||||
@ -547,16 +583,12 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||
{
|
||||
int s, ns;
|
||||
uschar *p = (uschar *) p0;
|
||||
uschar *p = __UNCONST(p0);
|
||||
uschar *q;
|
||||
int i, k;
|
||||
|
||||
/* s = f->reset ? makeinit(f,1) : f->initstat; */
|
||||
if (f->reset) {
|
||||
f->initstat = s = makeinit(f,1);
|
||||
} else {
|
||||
s = f->initstat;
|
||||
}
|
||||
s = f->initstat;
|
||||
assert(s < f->state_count);
|
||||
|
||||
patlen = -1;
|
||||
while (*p) {
|
||||
q = p;
|
||||
@ -568,9 +600,12 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||
s = ns;
|
||||
else
|
||||
s = cgoto(f, s, *q);
|
||||
|
||||
assert(s < f->state_count);
|
||||
|
||||
if (s == 1) { /* no transition */
|
||||
if (patlen > 0) {
|
||||
patbeg = (char *) p;
|
||||
patbeg = p;
|
||||
return(1);
|
||||
} else
|
||||
goto nnextin; /* no nonempty match */
|
||||
@ -579,24 +614,11 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||
if (f->out[s])
|
||||
patlen = q-p-1; /* don't count $ */
|
||||
if (patlen > 0 ) {
|
||||
patbeg = (char *) p;
|
||||
patbeg = p;
|
||||
return(1);
|
||||
}
|
||||
nnextin:
|
||||
s = 2;
|
||||
if (f->reset) {
|
||||
for (i = 2; i <= f->curstat; i++)
|
||||
xfree(f->posns[i]);
|
||||
k = *f->posns[0];
|
||||
if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL)
|
||||
overflo("out of state space");
|
||||
for (i = 0; i <= k; i++)
|
||||
(f->posns[2])[i] = (f->posns[0])[i];
|
||||
f->initstat = f->curstat = 2;
|
||||
f->out[2] = f->out[0];
|
||||
for (i = 0; i < NCHARS; i++)
|
||||
f->gototab[2][i] = 0;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return (0);
|
||||
@ -607,7 +629,7 @@ Node *reparse(const char *p) /* parses regular expression pointed to by p */
|
||||
Node *np;
|
||||
|
||||
dprintf( ("reparse <%s>\n", p) );
|
||||
lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */
|
||||
lastre = prestr = (const uschar *) p; /* prestr points to string to be parsed */
|
||||
rtok = relex();
|
||||
/* GNU compatibility: an empty regexp matches anything */
|
||||
if (rtok == '\0') {
|
||||
@ -644,11 +666,11 @@ Node *primary(void)
|
||||
rtok = relex();
|
||||
return (unary(op2(DOT, NIL, NIL)));
|
||||
case CCL:
|
||||
np = op2(CCL, NIL, (Node*) cclenter((char *) rlxstr));
|
||||
np = op2(CCL, NIL, (Node*) cclenter((const char *) rlxstr));
|
||||
rtok = relex();
|
||||
return (unary(np));
|
||||
case NCCL:
|
||||
np = op2(NCCL, NIL, (Node *) cclenter((char *) rlxstr));
|
||||
np = op2(NCCL, NIL, (Node *) cclenter((const char *) rlxstr));
|
||||
rtok = relex();
|
||||
return (unary(np));
|
||||
case '^':
|
||||
@ -732,23 +754,15 @@ Node *unary(Node *np)
|
||||
*/
|
||||
|
||||
/* #define HAS_ISBLANK */
|
||||
#ifndef HAS_ISBLANK
|
||||
|
||||
int (xisblank)(int c)
|
||||
{
|
||||
return c==' ' || c=='\t';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct charclass {
|
||||
static const struct charclass {
|
||||
const char *cc_name;
|
||||
int cc_namelen;
|
||||
int (*cc_func)(int);
|
||||
} charclasses[] = {
|
||||
{ "alnum", 5, isalnum },
|
||||
{ "alpha", 5, isalpha },
|
||||
{ "blank", 5, isspace }, /* was isblank */
|
||||
{ "blank", 5, isblank },
|
||||
{ "cntrl", 5, iscntrl },
|
||||
{ "digit", 5, isdigit },
|
||||
{ "graph", 5, isgraph },
|
||||
@ -769,7 +783,7 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
static uschar *buf = 0;
|
||||
static int bufsz = 100;
|
||||
uschar *bp;
|
||||
struct charclass *cc;
|
||||
const struct charclass *cc;
|
||||
int i;
|
||||
|
||||
switch (c = *prestr++) {
|
||||
@ -785,13 +799,13 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
case ')':
|
||||
return c;
|
||||
case '\\':
|
||||
rlxval = quoted((char **) &prestr);
|
||||
rlxval = quoted(&prestr);
|
||||
return CHAR;
|
||||
default:
|
||||
rlxval = c;
|
||||
return CHAR;
|
||||
case '[':
|
||||
if (buf == 0 && (buf = (uschar *) malloc(bufsz)) == NULL)
|
||||
if (buf == 0 && (buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of space in reg expr %.10s..", lastre);
|
||||
bp = buf;
|
||||
if (*prestr == '^') {
|
||||
@ -801,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, "relex1"))
|
||||
if (!adjbuf(&buf, &bufsz, n, n, &bp, "relex1"))
|
||||
FATAL("out of space for reg expr %.10s...", lastre);
|
||||
for (; ; ) {
|
||||
if ((c = *prestr++) == '\\') {
|
||||
@ -819,8 +833,8 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
|
||||
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, "relex2"))
|
||||
for (i = 1; i < NCHARS; i++) {
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+1, 100, &bp, "relex2"))
|
||||
FATAL("out of space for reg expr %.10s...", lastre);
|
||||
if (cc->cc_func(i)) {
|
||||
*bp++ = i;
|
||||
@ -852,16 +866,12 @@ int cgoto(fa *f, int s, int c)
|
||||
int *p, *q;
|
||||
|
||||
assert(c == HAT || c < NCHARS);
|
||||
while (f->accept >= maxsetvec) { /* guessing here! */
|
||||
maxsetvec *= 4;
|
||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("out of space in cgoto()");
|
||||
}
|
||||
while (f->accept >= maxsetvec) /* guessing here! */
|
||||
resizesetvec("out of space in cgoto()");
|
||||
for (i = 0; i <= f->accept; i++)
|
||||
setvec[i] = 0;
|
||||
setcnt = 0;
|
||||
resize_state(f, s);
|
||||
/* compute positions of gototab[s,c] into setvec */
|
||||
p = f->posns[s];
|
||||
for (i = 1; i <= *p; i++) {
|
||||
@ -874,13 +884,8 @@ int cgoto(fa *f, int s, int c)
|
||||
|| (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) {
|
||||
q = f->re[p[i]].lfollow;
|
||||
for (j = 1; j <= *q; j++) {
|
||||
if (q[j] >= maxsetvec) {
|
||||
maxsetvec *= 4;
|
||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
||||
if (setvec == 0 || tmpset == 0)
|
||||
overflo("cgoto overflow");
|
||||
}
|
||||
if (q[j] >= maxsetvec)
|
||||
resizesetvec("cgoto overflow");
|
||||
if (setvec[q[j]] == 0) {
|
||||
setcnt++;
|
||||
setvec[q[j]] = 1;
|
||||
@ -896,6 +901,8 @@ int cgoto(fa *f, int s, int c)
|
||||
if (setvec[i]) {
|
||||
tmpset[j++] = i;
|
||||
}
|
||||
|
||||
resize_state(f, f->curstat > s ? f->curstat : s);
|
||||
/* tmpset == previous state? */
|
||||
for (i = 1; i <= f->curstat; i++) {
|
||||
p = f->posns[i];
|
||||
@ -905,27 +912,24 @@ int cgoto(fa *f, int s, int c)
|
||||
if (tmpset[j] != p[j])
|
||||
goto different;
|
||||
/* setvec is state i */
|
||||
f->gototab[s][c] = i;
|
||||
if (c != HAT)
|
||||
f->gototab[s][c] = i;
|
||||
return i;
|
||||
different:;
|
||||
}
|
||||
|
||||
/* add tmpset to current set of states */
|
||||
if (f->curstat >= NSTATES-1) {
|
||||
f->curstat = 2;
|
||||
f->reset = 1;
|
||||
for (i = 2; i < NSTATES; i++)
|
||||
xfree(f->posns[i]);
|
||||
} else
|
||||
++(f->curstat);
|
||||
++(f->curstat);
|
||||
resize_state(f, f->curstat);
|
||||
for (i = 0; i < NCHARS; i++)
|
||||
f->gototab[f->curstat][i] = 0;
|
||||
xfree(f->posns[f->curstat]);
|
||||
if ((p = (int *) calloc(1, (setcnt+1)*sizeof(int))) == NULL)
|
||||
if ((p = calloc(1, (setcnt+1)*sizeof(int))) == NULL)
|
||||
overflo("out of space in cgoto");
|
||||
|
||||
f->posns[f->curstat] = p;
|
||||
f->gototab[s][c] = f->curstat;
|
||||
if (c != HAT)
|
||||
f->gototab[s][c] = f->curstat;
|
||||
for (i = 0; i <= setcnt; i++)
|
||||
p[i] = tmpset[i];
|
||||
if (setvec[f->accept])
|
||||
@ -942,13 +946,18 @@ void freefa(fa *f) /* free a finite automaton */
|
||||
|
||||
if (f == NULL)
|
||||
return;
|
||||
for (i = 0; i <= f->curstat; i++)
|
||||
for (i = 0; i < f->state_count; i++) {
|
||||
xfree(f->gototab[i])
|
||||
xfree(f->posns[i]);
|
||||
}
|
||||
for (i = 0; i <= f->accept; i++) {
|
||||
xfree(f->re[i].lfollow);
|
||||
if (f->re[i].ltype == CCL || f->re[i].ltype == NCCL)
|
||||
xfree((f->re[i].lval.np));
|
||||
}
|
||||
xfree(f->restr);
|
||||
xfree(f->out);
|
||||
xfree(f->posns);
|
||||
xfree(f->gototab);
|
||||
xfree(f);
|
||||
}
|
||||
|
44
external/historical/nawk/dist/lex.c
vendored
44
external/historical/nawk/dist/lex.c
vendored
@ -22,12 +22,16 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
extern int infunc;
|
||||
@ -43,7 +47,11 @@ typedef struct Keyword {
|
||||
int type;
|
||||
} Keyword;
|
||||
|
||||
Keyword keywords[] ={ /* keep sorted: binary searched */
|
||||
int peek(void);
|
||||
int gettok(char **, int *);
|
||||
int binsearch(const char *, const Keyword *, int);
|
||||
|
||||
const Keyword keywords[] ={ /* keep sorted: binary searched */
|
||||
{ "BEGIN", XBEGIN, XBEGIN },
|
||||
{ "END", XEND, XEND },
|
||||
{ "NF", VARNF, VARNF },
|
||||
@ -61,6 +69,7 @@ Keyword keywords[] ={ /* keep sorted: binary searched */
|
||||
{ "for", FOR, FOR },
|
||||
{ "func", FUNC, FUNC },
|
||||
{ "function", FUNC, FUNC },
|
||||
{ "gensub", GENSUB, GENSUB },
|
||||
{ "getline", GETLINE, GETLINE },
|
||||
{ "gsub", GSUB, GSUB },
|
||||
{ "if", IF, IF },
|
||||
@ -81,9 +90,11 @@ Keyword keywords[] ={ /* keep sorted: binary searched */
|
||||
{ "sprintf", SPRINTF, SPRINTF },
|
||||
{ "sqrt", FSQRT, BLTIN },
|
||||
{ "srand", FSRAND, BLTIN },
|
||||
{ "strftime", FSTRFTIME, BLTIN },
|
||||
{ "sub", SUB, SUB },
|
||||
{ "substr", SUBSTR, SUBSTR },
|
||||
{ "system", FSYSTEM, BLTIN },
|
||||
{ "systime", FSYSTIME, BLTIN },
|
||||
{ "tolower", FTOLOWER, BLTIN },
|
||||
{ "toupper", FTOUPPER, BLTIN },
|
||||
{ "while", WHILE, WHILE },
|
||||
@ -101,9 +112,9 @@ int peek(void)
|
||||
int gettok(char **pbuf, int *psz) /* get next input token */
|
||||
{
|
||||
int c, retc;
|
||||
char *buf = *pbuf;
|
||||
uschar *buf = (uschar *) *pbuf;
|
||||
int sz = *psz;
|
||||
char *bp = buf;
|
||||
uschar *bp = buf;
|
||||
|
||||
c = input();
|
||||
if (c == 0)
|
||||
@ -146,7 +157,7 @@ int gettok(char **pbuf, int *psz) /* get next input token */
|
||||
}
|
||||
*bp = 0;
|
||||
strtod(buf, &rem); /* parse the number */
|
||||
if (rem == buf) { /* it wasn't a valid number at all */
|
||||
if (rem == (char *)buf) { /* it wasn't a valid number at all */
|
||||
buf[1] = 0; /* return one character as token */
|
||||
retc = buf[0]; /* character is its own type */
|
||||
unputstr(rem+1); /* put rest back for later */
|
||||
@ -173,7 +184,7 @@ int yylex(void)
|
||||
static char *buf = 0;
|
||||
static int bufsize = 5; /* BUG: setting this small causes core dump! */
|
||||
|
||||
if (buf == 0 && (buf = (char *) malloc(bufsize)) == NULL)
|
||||
if (buf == 0 && (buf = malloc(bufsize)) == NULL)
|
||||
FATAL( "out of space in yylex" );
|
||||
if (sc) {
|
||||
sc = 0;
|
||||
@ -357,11 +368,11 @@ int yylex(void)
|
||||
int string(void)
|
||||
{
|
||||
int c, n;
|
||||
char *s, *bp;
|
||||
static char *buf = 0;
|
||||
uschar *s, *bp;
|
||||
static uschar *buf = 0;
|
||||
static int bufsz = 500;
|
||||
|
||||
if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL)
|
||||
if (buf == 0 && (buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of space for strings");
|
||||
for (bp = buf; (c = input()) != '"'; ) {
|
||||
if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, "string"))
|
||||
@ -378,6 +389,7 @@ int string(void)
|
||||
case '\\':
|
||||
c = input();
|
||||
switch (c) {
|
||||
case '\n': break;
|
||||
case '"': *bp++ = '"'; break;
|
||||
case 'n': *bp++ = '\n'; break;
|
||||
case 't': *bp++ = '\t'; break;
|
||||
@ -416,7 +428,9 @@ int string(void)
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
default:
|
||||
WARNING("warning: escape sequence `\\%c' "
|
||||
"treated as plain `%c'", c, c);
|
||||
*bp++ = c;
|
||||
break;
|
||||
}
|
||||
@ -434,7 +448,7 @@ int string(void)
|
||||
}
|
||||
|
||||
|
||||
int binsearch(char *w, Keyword *kp, int n)
|
||||
int binsearch(const char *w, const Keyword *kp, int n)
|
||||
{
|
||||
int cond, low, mid, high;
|
||||
|
||||
@ -454,7 +468,7 @@ int binsearch(char *w, Keyword *kp, int n)
|
||||
|
||||
int word(char *w)
|
||||
{
|
||||
Keyword *kp;
|
||||
const Keyword *kp;
|
||||
int c, n;
|
||||
|
||||
n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0]));
|
||||
@ -504,11 +518,11 @@ void startreg(void) /* next call to yylex will return a regular expression */
|
||||
int regexpr(void)
|
||||
{
|
||||
int c;
|
||||
static char *buf = 0;
|
||||
static uschar *buf = 0;
|
||||
static int bufsz = 500;
|
||||
char *bp;
|
||||
uschar *bp;
|
||||
|
||||
if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL)
|
||||
if (buf == 0 && (buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of space for rex expr");
|
||||
bp = buf;
|
||||
for ( ; (c = input()) != '/' && c != 0; ) {
|
||||
|
168
external/historical/nawk/dist/lib.c
vendored
168
external/historical/nawk/dist/lib.c
vendored
@ -22,6 +22,10 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -30,17 +34,20 @@ THIS SOFTWARE.
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
char EMPTY[] = { '\0' };
|
||||
FILE *infile = NULL;
|
||||
char *file = "";
|
||||
char *record;
|
||||
char *file = EMPTY;
|
||||
uschar *record;
|
||||
int recsize = RECSIZE;
|
||||
char *fields;
|
||||
int fieldssize = RECSIZE;
|
||||
|
||||
Cell **fldtab; /* pointers to Cells */
|
||||
char inputFS[100] = " ";
|
||||
|
||||
static size_t len_inputFS = 0;
|
||||
static char *inputFS = NULL;
|
||||
|
||||
#define MAXFLD 2
|
||||
int nfields = MAXFLD; /* last allocated slot for $i */
|
||||
@ -52,15 +59,15 @@ int lastfld = 0; /* last used field */
|
||||
int argno = 1; /* current input argument number */
|
||||
extern Awkfloat *ARGC;
|
||||
|
||||
static Cell dollar0 = { OCELL, CFLD, NULL, "", 0.0, REC|STR|DONTFREE };
|
||||
static Cell dollar1 = { OCELL, CFLD, NULL, "", 0.0, FLD|STR|DONTFREE };
|
||||
static Cell dollar0 = { OCELL, CFLD, NULL, EMPTY, 0.0, REC|STR|DONTFREE, NULL };
|
||||
static Cell dollar1 = { OCELL, CFLD, NULL, EMPTY, 0.0, FLD|STR|DONTFREE, NULL };
|
||||
|
||||
void recinit(unsigned int n)
|
||||
{
|
||||
if ( (record = (char *) malloc(n)) == NULL
|
||||
|| (fields = (char *) malloc(n+1)) == NULL
|
||||
|| (fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *))) == NULL
|
||||
|| (fldtab[0] = (Cell *) malloc(sizeof(Cell))) == NULL )
|
||||
if ( (record = malloc(n)) == NULL
|
||||
|| (fields = malloc(n+1)) == NULL
|
||||
|| (fldtab = malloc((nfields+1) * sizeof(*fldtab))) == NULL
|
||||
|| (fldtab[0] = malloc(sizeof(**fldtab))) == NULL )
|
||||
FATAL("out of space for $0 and fields");
|
||||
*fldtab[0] = dollar0;
|
||||
fldtab[0]->sval = record;
|
||||
@ -74,11 +81,11 @@ void makefields(int n1, int n2) /* create $n1..$n2 inclusive */
|
||||
int i;
|
||||
|
||||
for (i = n1; i <= n2; i++) {
|
||||
fldtab[i] = (Cell *) malloc(sizeof (struct Cell));
|
||||
fldtab[i] = malloc(sizeof(**fldtab));
|
||||
if (fldtab[i] == NULL)
|
||||
FATAL("out of space in makefields %d", i);
|
||||
*fldtab[i] = dollar1;
|
||||
sprintf(temp, "%d", i);
|
||||
snprintf(temp, sizeof(temp), "%d", i);
|
||||
fldtab[i]->nval = tostring(temp);
|
||||
}
|
||||
}
|
||||
@ -101,10 +108,10 @@ void initgetrec(void)
|
||||
|
||||
static int firsttime = 1;
|
||||
|
||||
int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
|
||||
int getrec(uschar **pbuf, int *pbufsize, int isrecord) /* get next input record */
|
||||
{ /* note: cares whether buf == record */
|
||||
int c;
|
||||
char *buf = *pbuf;
|
||||
uschar *buf = *pbuf;
|
||||
uschar saveb0;
|
||||
int bufsize = *pbufsize, savebufsize = bufsize;
|
||||
|
||||
@ -179,37 +186,84 @@ void nextfile(void)
|
||||
argno++;
|
||||
}
|
||||
|
||||
int readrec(char **pbuf, int *pbufsize, FILE *inf) /* read one record into buf */
|
||||
int readrec(uschar **pbuf, int *pbufsize, FILE *inf) /* read one record into buf */
|
||||
{
|
||||
int sep, c;
|
||||
char *rr, *buf = *pbuf;
|
||||
uschar *rr, *buf = *pbuf;
|
||||
int bufsize = *pbufsize;
|
||||
size_t len;
|
||||
|
||||
if (strlen(*FS) >= sizeof(inputFS))
|
||||
FATAL("field separator %.10s... is too long", *FS);
|
||||
strcpy(inputFS, *FS); /* for subsequent field splitting */
|
||||
if ((len = strlen(*FS)) < len_inputFS) {
|
||||
strcpy(inputFS, *FS); /* for subsequent field splitting */
|
||||
} else {
|
||||
len_inputFS = len + 1;
|
||||
inputFS = realloc(inputFS, len_inputFS);
|
||||
if (inputFS == NULL)
|
||||
FATAL("field separator %.10s... is too long", *FS);
|
||||
memcpy(inputFS, *FS, len_inputFS);
|
||||
}
|
||||
if ((sep = **RS) == 0) {
|
||||
sep = '\n';
|
||||
while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */
|
||||
;
|
||||
if (c != EOF)
|
||||
ungetc(c, inf);
|
||||
}
|
||||
for (rr = buf; ; ) {
|
||||
for (; (c=getc(inf)) != sep && c != EOF; ) {
|
||||
if (rr-buf+1 > bufsize)
|
||||
if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 1"))
|
||||
FATAL("input record `%.30s...' too long", buf);
|
||||
} else if ((*RS)[1]) {
|
||||
fa *pfa = makedfa(*RS, 1);
|
||||
int tempstat = pfa->initstat;
|
||||
char *brr = buf;
|
||||
char *rrr = NULL;
|
||||
int x;
|
||||
for (rr = buf; ; ) {
|
||||
while ((c = getc(inf)) != EOF) {
|
||||
if (rr-buf+3 > bufsize)
|
||||
if (!adjbuf(&buf, &bufsize, 3+rr-buf,
|
||||
recsize, &rr, "readrec 2"))
|
||||
FATAL("input record `%.30s...'"
|
||||
" too long", buf);
|
||||
*rr++ = c;
|
||||
*rr = '\0';
|
||||
if (!(x = nematch(pfa, brr))) {
|
||||
pfa->initstat = tempstat;
|
||||
if (rrr) {
|
||||
rr = rrr;
|
||||
ungetc(c, inf);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pfa->initstat = 2;
|
||||
brr = rrr = rr = patbeg;
|
||||
}
|
||||
}
|
||||
if (rrr || c == EOF)
|
||||
break;
|
||||
if ((c = getc(inf)) == '\n' || c == EOF)
|
||||
/* 2 in a row */
|
||||
break;
|
||||
*rr++ = '\n';
|
||||
*rr++ = c;
|
||||
}
|
||||
} else {
|
||||
for (rr = buf; ; ) {
|
||||
for (; (c=getc(inf)) != sep && c != EOF; ) {
|
||||
if (rr-buf+1 > bufsize)
|
||||
if (!adjbuf(&buf, &bufsize, 1+rr-buf,
|
||||
recsize, &rr, "readrec 1"))
|
||||
FATAL("input record `%.30s...'"
|
||||
" too long", buf);
|
||||
*rr++ = c;
|
||||
}
|
||||
if (**RS == sep || c == EOF)
|
||||
break;
|
||||
if ((c = getc(inf)) == '\n' || c == EOF)
|
||||
/* 2 in a row */
|
||||
break;
|
||||
if (!adjbuf(&buf, &bufsize, 2+rr-buf, recsize, &rr,
|
||||
"readrec 2"))
|
||||
FATAL("input record `%.30s...' too long", buf);
|
||||
*rr++ = '\n';
|
||||
*rr++ = c;
|
||||
}
|
||||
if (**RS == sep || c == EOF)
|
||||
break;
|
||||
if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
|
||||
break;
|
||||
if (!adjbuf(&buf, &bufsize, 2+rr-buf, recsize, &rr, "readrec 2"))
|
||||
FATAL("input record `%.30s...' too long", buf);
|
||||
*rr++ = '\n';
|
||||
*rr++ = c;
|
||||
}
|
||||
if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 3"))
|
||||
FATAL("input record `%.30s...' too long", buf);
|
||||
@ -226,7 +280,7 @@ char *getargv(int n) /* get ARGV[n] */
|
||||
char *s, temp[50];
|
||||
extern Array *ARGVtab;
|
||||
|
||||
sprintf(temp, "%d", n);
|
||||
snprintf(temp, sizeof(temp), "%d", n);
|
||||
x = setsymtab(temp, "", 0.0, STR, ARGVtab);
|
||||
s = getsval(x);
|
||||
dprintf( ("getargv(%d) returns |%s|\n", n, s) );
|
||||
@ -268,14 +322,13 @@ void fldbld(void) /* create fields from current record */
|
||||
n = strlen(r);
|
||||
if (n > fieldssize) {
|
||||
xfree(fields);
|
||||
if ((fields = (char *) malloc(n+1)) == NULL)
|
||||
if ((fields = malloc(n+1)) == NULL)
|
||||
FATAL("out of space for fields in fldbld %d", n);
|
||||
fieldssize = n;
|
||||
}
|
||||
fr = fields;
|
||||
i = 0; /* number of fields accumulated here */
|
||||
strcpy(inputFS, *FS);
|
||||
if (strlen(inputFS) > 1) { /* it's a regular expression */
|
||||
if (inputFS[0] && inputFS[1]) { /* it's a regular expression */
|
||||
i = refldbld(r, inputFS);
|
||||
} else if ((sep = *inputFS) == ' ') { /* default whitespace */
|
||||
for (i = 0; ; ) {
|
||||
@ -364,7 +417,7 @@ void cleanfld(int n1, int n2) /* clean out fields n1 .. n2 inclusive */
|
||||
p = fldtab[i];
|
||||
if (freeable(p))
|
||||
xfree(p->sval);
|
||||
p->sval = "";
|
||||
p->sval = EMPTY;
|
||||
p->tval = FLD | STR | DONTFREE;
|
||||
}
|
||||
}
|
||||
@ -395,8 +448,8 @@ void growfldtab(int n) /* make new fields up to at least $n */
|
||||
if (n > nf)
|
||||
nf = n;
|
||||
s = (nf+1) * (sizeof (struct Cell *)); /* freebsd: how much do we need? */
|
||||
if (s / sizeof(struct Cell *) - 1 == nf) /* didn't overflow */
|
||||
fldtab = (Cell **) realloc(fldtab, s);
|
||||
if (s / sizeof(struct Cell *) - 1 == (size_t)nf) /* didn't overflow */
|
||||
fldtab = realloc(fldtab, s);
|
||||
else /* overflow sizeof int */
|
||||
xfree(fldtab); /* make it null */
|
||||
if (fldtab == NULL)
|
||||
@ -416,7 +469,7 @@ int refldbld(const char *rec, const char *fs) /* build fields from reg expr in F
|
||||
n = strlen(rec);
|
||||
if (n > fieldssize) {
|
||||
xfree(fields);
|
||||
if ((fields = (char *) malloc(n+1)) == NULL)
|
||||
if ((fields = malloc(n+1)) == NULL)
|
||||
FATAL("out of space for fields in refldbld %d", n);
|
||||
fieldssize = n;
|
||||
}
|
||||
@ -438,8 +491,8 @@ int refldbld(const char *rec, const char *fs) /* build fields from reg expr in F
|
||||
if (nematch(pfa, rec)) {
|
||||
pfa->initstat = 2; /* horrible coupling to b.c */
|
||||
dprintf( ("match %s (%d chars)\n", patbeg, patlen) );
|
||||
strncpy(fr, rec, patbeg-rec);
|
||||
fr += patbeg - rec + 1;
|
||||
strncpy(fr, rec, ((const char*)patbeg)-rec);
|
||||
fr += ((const char*)patbeg) - rec + 1;
|
||||
*(fr-1) = '\0';
|
||||
rec = patbeg + patlen;
|
||||
} else {
|
||||
@ -455,7 +508,8 @@ int refldbld(const char *rec, const char *fs) /* build fields from reg expr in F
|
||||
void recbld(void) /* create $0 from $1..$NF if necessary */
|
||||
{
|
||||
int i;
|
||||
char *r, *p;
|
||||
uschar *r;
|
||||
char *p;
|
||||
|
||||
if (donerec == 1)
|
||||
return;
|
||||
@ -517,11 +571,6 @@ void SYNTAX(const char *fmt, ...)
|
||||
eprint();
|
||||
}
|
||||
|
||||
void fpecatch(int n)
|
||||
{
|
||||
FATAL("floating point exception %d", n);
|
||||
}
|
||||
|
||||
extern int bracecnt, brackcnt, parencnt;
|
||||
|
||||
void bracecheck(void)
|
||||
@ -603,7 +652,6 @@ void error()
|
||||
void eprint(void) /* try to print context around error */
|
||||
{
|
||||
char *p, *q;
|
||||
int c;
|
||||
static int been_here = 0;
|
||||
extern char ebuf[], *ep;
|
||||
|
||||
@ -627,11 +675,25 @@ void eprint(void) /* try to print context around error */
|
||||
if (*p)
|
||||
putc(*p, stderr);
|
||||
fprintf(stderr, " <<< ");
|
||||
if (*ep)
|
||||
#if 0
|
||||
/*
|
||||
* The following code was used to print the rest of the line of
|
||||
* error context. It naively counts brackets, parens and braces in
|
||||
* order to minimize the parsing effect of dropping the rest of the
|
||||
* line but it does not work in all the cases. It is too much work
|
||||
* to save the current program input point and restore it in all the
|
||||
* cases just for the benefit of error printing so for now this
|
||||
* code is disabled. In particular this code is confused if the
|
||||
* [ { ( ) } ] is inside a quoted string or a pattern.
|
||||
*/
|
||||
if (*ep) {
|
||||
int c;
|
||||
while ((c = input()) != '\n' && c != '\0' && c != EOF) {
|
||||
putc(c, stderr);
|
||||
bclass(c);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
putc('\n', stderr);
|
||||
ep = ebuf;
|
||||
}
|
||||
@ -686,7 +748,9 @@ int is_number(const char *s)
|
||||
char *ep;
|
||||
errno = 0;
|
||||
r = strtod(s, &ep);
|
||||
if (ep == s || r == HUGE_VAL || errno == ERANGE)
|
||||
if (ep == s || errno == ERANGE)
|
||||
return 0;
|
||||
if (ep - s >= 3 && strncasecmp(ep - 3, "nan", 3) == 0)
|
||||
return 0;
|
||||
while (*ep == ' ' || *ep == '\t' || *ep == '\n')
|
||||
ep++;
|
||||
|
73
external/historical/nawk/dist/main.c
vendored
73
external/historical/nawk/dist/main.c
vendored
@ -24,6 +24,10 @@ THIS SOFTWARE.
|
||||
|
||||
const char *version = "version 20100523";
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@ -32,7 +36,7 @@ const char *version = "version 20100523";
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
extern char **environ;
|
||||
extern int nfields;
|
||||
@ -53,11 +57,52 @@ int curpfile = 0; /* current filename */
|
||||
|
||||
int safe = 0; /* 1 => "safe" mode */
|
||||
|
||||
static char *
|
||||
setfs(char *p)
|
||||
{
|
||||
#ifdef notdef
|
||||
/* wart: t=>\t */
|
||||
if (p[0] == 't' && p[1] == 0)
|
||||
return "\t";
|
||||
else
|
||||
#endif
|
||||
if (p[0] != 0)
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void fpecatch(int n
|
||||
#ifdef SA_SIGINFO
|
||||
, siginfo_t *si, void *uc
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef SA_SIGINFO
|
||||
static const char *emsg[] = {
|
||||
"Unknown error",
|
||||
"Integer divide by zero",
|
||||
"Integer overflow",
|
||||
"Floating point divide by zero",
|
||||
"Floating point overflow",
|
||||
"Floating point underflow",
|
||||
"Floating point inexact result",
|
||||
"Invalid Floating point operation",
|
||||
"Subscript out of range",
|
||||
};
|
||||
#endif
|
||||
FATAL("floating point exception"
|
||||
#ifdef SA_SIGINFO
|
||||
": %s\n", emsg[si->si_code >= 1 && si->si_code <= 8 ?
|
||||
si->si_code : 0]
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *fs = NULL;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
||||
cmdname = argv[0];
|
||||
if (argc == 1) {
|
||||
@ -66,7 +111,18 @@ int main(int argc, char *argv[])
|
||||
cmdname);
|
||||
exit(1);
|
||||
}
|
||||
signal(SIGFPE, fpecatch);
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = fpecatch;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
(void)sigaction(SIGFPE, &sa, NULL);
|
||||
}
|
||||
#else
|
||||
(void)signal(SIGFPE, fpecatch);
|
||||
#endif
|
||||
yyin = NULL;
|
||||
symtab = makesymtab(NSYMTAB/NSYMTAB);
|
||||
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
|
||||
@ -96,16 +152,11 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case 'F': /* set field separator */
|
||||
if (argv[1][2] != 0) { /* arg is -Fsomething */
|
||||
if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */
|
||||
fs = "\t";
|
||||
else if (argv[1][2] != 0)
|
||||
fs = &argv[1][2];
|
||||
fs = setfs(argv[1] + 2);
|
||||
} else { /* arg is -F something */
|
||||
argc--; argv++;
|
||||
if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */
|
||||
fs = "\t";
|
||||
else if (argc > 1 && argv[1][0] != 0)
|
||||
fs = &argv[1][0];
|
||||
if (argc > 1)
|
||||
fs = setfs(argv[1]);
|
||||
}
|
||||
if (fs == NULL || *fs == '\0')
|
||||
WARNING("field separator FS is empty");
|
||||
|
4
external/historical/nawk/dist/makefile
vendored
4
external/historical/nawk/dist/makefile
vendored
@ -27,6 +27,8 @@ CFLAGS = -O2
|
||||
CFLAGS =
|
||||
|
||||
CC = gcc -Wall -g
|
||||
CC = /opt/SUNWspro/bin/cc
|
||||
CC = /opt/pure/purify/purify cc
|
||||
CC = cc
|
||||
CC = gcc -Wall -g -Wwrite-strings
|
||||
CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
|
||||
@ -83,4 +85,4 @@ names:
|
||||
@echo $(LISTING)
|
||||
|
||||
clean:
|
||||
rm -f a.out *.o *.obj maketab maketab.exe *.bb *.bbg *.da *.gcov *.gcno *.gcda # proctab.c
|
||||
rm -f a.out *.o *.obj maketab maketab.exe ytab.[ch] *.bb *.bbg *.da *.gcov *.gcno *.gcda # proctab.c
|
||||
|
30
external/historical/nawk/dist/maketab.c
vendored
30
external/historical/nawk/dist/maketab.c
vendored
@ -28,11 +28,15 @@ THIS SOFTWARE.
|
||||
* it finds the indices in ytab.h, produced by yacc.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
struct xx
|
||||
{ int token;
|
||||
@ -103,6 +107,7 @@ struct xx
|
||||
{ ARG, "arg", "arg" },
|
||||
{ VARNF, "getnf", "NF" },
|
||||
{ GETLINE, "awkgetline", "getline" },
|
||||
{ GENSUB, "gensub", "gensub" },
|
||||
{ 0, "", "" },
|
||||
};
|
||||
|
||||
@ -120,27 +125,30 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("#include <stdio.h>\n");
|
||||
printf("#include \"awk.h\"\n");
|
||||
printf("#include \"ytab.h\"\n\n");
|
||||
printf("#include \"awkgram.h\"\n\n");
|
||||
for (i = SIZE; --i >= 0; )
|
||||
names[i] = "";
|
||||
|
||||
if ((fp = fopen("ytab.h", "r")) == NULL) {
|
||||
fprintf(stderr, "maketab can't open ytab.h!\n");
|
||||
if ((fp = fopen("awkgram.h", "r")) == NULL) {
|
||||
fprintf(stderr, "maketab can't open awkgram.h!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("static char *printname[%d] = {\n", SIZE);
|
||||
printf("static const char * const printname[%d] = {\n", SIZE);
|
||||
i = 0;
|
||||
while (fgets(buf, sizeof buf, fp) != NULL) {
|
||||
n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok);
|
||||
n = sscanf(buf, "%1c %199s %199s %d", &c, def, name, &tok);
|
||||
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); */
|
||||
continue;
|
||||
}
|
||||
names[tok-FIRSTTOKEN] = (char *) malloc(strlen(name)+1);
|
||||
strcpy(names[tok-FIRSTTOKEN], name);
|
||||
printf("\t(char *) \"%s\",\t/* %d */\n", name, tok);
|
||||
names[tok-FIRSTTOKEN] = strdup(name);
|
||||
if (names[tok-FIRSTTOKEN] == NULL) {
|
||||
fprintf(stderr, "maketab out of space copying %s", name);
|
||||
continue;
|
||||
}
|
||||
printf("\t\"%s\",\t/* %d */\n", name, tok);
|
||||
i++;
|
||||
}
|
||||
printf("};\n\n");
|
||||
@ -155,11 +163,11 @@ int main(int argc, char *argv[])
|
||||
printf("\t%s,\t/* %s */\n", table[i], names[i]);
|
||||
printf("};\n\n");
|
||||
|
||||
printf("char *tokname(int n)\n"); /* print a tokname() function */
|
||||
printf("const char *tokname(int n)\n"); /* print a tokname() function */
|
||||
printf("{\n");
|
||||
printf(" static char buf[100];\n\n");
|
||||
printf(" if (n < FIRSTTOKEN || n > LASTTOKEN) {\n");
|
||||
printf(" sprintf(buf, \"token %%d\", n);\n");
|
||||
printf(" snprintf(buf, sizeof(buf), \"token %%d\", n);\n");
|
||||
printf(" return buf;\n");
|
||||
printf(" }\n");
|
||||
printf(" return printname[n-FIRSTTOKEN];\n");
|
||||
|
31
external/historical/nawk/dist/parse.c
vendored
31
external/historical/nawk/dist/parse.c
vendored
@ -22,18 +22,22 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
Node *nodealloc(int n)
|
||||
{
|
||||
Node *x;
|
||||
|
||||
x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *));
|
||||
x = malloc(sizeof(Node) + (n-1)*sizeof(Node *));
|
||||
if (x == NULL)
|
||||
FATAL("out of space in nodealloc");
|
||||
x->nnext = NULL;
|
||||
@ -93,6 +97,20 @@ Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
|
||||
return(x);
|
||||
}
|
||||
|
||||
Node *node5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
|
||||
{
|
||||
Node *x;
|
||||
|
||||
x = nodealloc(5);
|
||||
x->nobj = a;
|
||||
x->narg[0] = b;
|
||||
x->narg[1] = c;
|
||||
x->narg[2] = d;
|
||||
x->narg[3] = e;
|
||||
x->narg[4] = f;
|
||||
return(x);
|
||||
}
|
||||
|
||||
Node *stat1(int a, Node *b)
|
||||
{
|
||||
Node *x;
|
||||
@ -165,6 +183,15 @@ Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
|
||||
return(x);
|
||||
}
|
||||
|
||||
Node *op5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
|
||||
{
|
||||
Node *x;
|
||||
|
||||
x = node5(a,b,c,d,e, f);
|
||||
x->ntype = NEXPR;
|
||||
return(x);
|
||||
}
|
||||
|
||||
Node *celltonode(Cell *a, int b)
|
||||
{
|
||||
Node *x;
|
||||
|
206
external/historical/nawk/dist/proctab.c
vendored
206
external/historical/nawk/dist/proctab.c
vendored
@ -1,105 +1,110 @@
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
static char *printname[93] = {
|
||||
(char *) "FIRSTTOKEN", /* 258 */
|
||||
(char *) "PROGRAM", /* 259 */
|
||||
(char *) "PASTAT", /* 260 */
|
||||
(char *) "PASTAT2", /* 261 */
|
||||
(char *) "XBEGIN", /* 262 */
|
||||
(char *) "XEND", /* 263 */
|
||||
(char *) "NL", /* 264 */
|
||||
(char *) "ARRAY", /* 265 */
|
||||
(char *) "MATCH", /* 266 */
|
||||
(char *) "NOTMATCH", /* 267 */
|
||||
(char *) "MATCHOP", /* 268 */
|
||||
(char *) "FINAL", /* 269 */
|
||||
(char *) "DOT", /* 270 */
|
||||
(char *) "ALL", /* 271 */
|
||||
(char *) "CCL", /* 272 */
|
||||
(char *) "NCCL", /* 273 */
|
||||
(char *) "CHAR", /* 274 */
|
||||
(char *) "OR", /* 275 */
|
||||
(char *) "STAR", /* 276 */
|
||||
(char *) "QUEST", /* 277 */
|
||||
(char *) "PLUS", /* 278 */
|
||||
(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 */
|
||||
static const char * const printname[94] = {
|
||||
"FIRSTTOKEN", /* 257 */
|
||||
"PROGRAM", /* 258 */
|
||||
"PASTAT", /* 259 */
|
||||
"PASTAT2", /* 260 */
|
||||
"XBEGIN", /* 261 */
|
||||
"XEND", /* 262 */
|
||||
"NL", /* 263 */
|
||||
"ARRAY", /* 264 */
|
||||
"MATCH", /* 265 */
|
||||
"NOTMATCH", /* 266 */
|
||||
"MATCHOP", /* 267 */
|
||||
"FINAL", /* 268 */
|
||||
"DOT", /* 269 */
|
||||
"ALL", /* 270 */
|
||||
"CCL", /* 271 */
|
||||
"NCCL", /* 272 */
|
||||
"CHAR", /* 273 */
|
||||
"OR", /* 274 */
|
||||
"STAR", /* 275 */
|
||||
"QUEST", /* 276 */
|
||||
"PLUS", /* 277 */
|
||||
"EMPTYRE", /* 278 */
|
||||
"AND", /* 279 */
|
||||
"BOR", /* 280 */
|
||||
"APPEND", /* 281 */
|
||||
"EQ", /* 282 */
|
||||
"GE", /* 283 */
|
||||
"GT", /* 284 */
|
||||
"LE", /* 285 */
|
||||
"LT", /* 286 */
|
||||
"NE", /* 287 */
|
||||
"IN", /* 288 */
|
||||
"ARG", /* 289 */
|
||||
"BLTIN", /* 290 */
|
||||
"BREAK", /* 291 */
|
||||
"CLOSE", /* 292 */
|
||||
"CONTINUE", /* 293 */
|
||||
"DELETE", /* 294 */
|
||||
"DO", /* 295 */
|
||||
"EXIT", /* 296 */
|
||||
"FOR", /* 297 */
|
||||
"FUNC", /* 298 */
|
||||
"SUB", /* 299 */
|
||||
"GSUB", /* 300 */
|
||||
"IF", /* 301 */
|
||||
"INDEX", /* 302 */
|
||||
"LSUBSTR", /* 303 */
|
||||
"MATCHFCN", /* 304 */
|
||||
"NEXT", /* 305 */
|
||||
"NEXTFILE", /* 306 */
|
||||
"ADD", /* 307 */
|
||||
"MINUS", /* 308 */
|
||||
"MULT", /* 309 */
|
||||
"DIVIDE", /* 310 */
|
||||
"MOD", /* 311 */
|
||||
"ASSIGN", /* 312 */
|
||||
"ASGNOP", /* 313 */
|
||||
"ADDEQ", /* 314 */
|
||||
"SUBEQ", /* 315 */
|
||||
"MULTEQ", /* 316 */
|
||||
"DIVEQ", /* 317 */
|
||||
"MODEQ", /* 318 */
|
||||
"POWEQ", /* 319 */
|
||||
"PRINT", /* 320 */
|
||||
"PRINTF", /* 321 */
|
||||
"SPRINTF", /* 322 */
|
||||
"ELSE", /* 323 */
|
||||
"INTEST", /* 324 */
|
||||
"CONDEXPR", /* 325 */
|
||||
"POSTINCR", /* 326 */
|
||||
"PREINCR", /* 327 */
|
||||
"POSTDECR", /* 328 */
|
||||
"PREDECR", /* 329 */
|
||||
"VAR", /* 330 */
|
||||
"IVAR", /* 331 */
|
||||
"VARNF", /* 332 */
|
||||
"CALL", /* 333 */
|
||||
"NUMBER", /* 334 */
|
||||
"STRING", /* 335 */
|
||||
"REGEXPR", /* 336 */
|
||||
"GETLINE", /* 337 */
|
||||
"GENSUB", /* 338 */
|
||||
"RETURN", /* 339 */
|
||||
"SPLIT", /* 340 */
|
||||
"SUBSTR", /* 341 */
|
||||
"WHILE", /* 342 */
|
||||
"CAT", /* 343 */
|
||||
"NOT", /* 344 */
|
||||
"UMINUS", /* 345 */
|
||||
"POWER", /* 346 */
|
||||
"DECR", /* 347 */
|
||||
"INCR", /* 348 */
|
||||
"INDIRECT", /* 349 */
|
||||
"LASTTOKEN", /* 350 */
|
||||
};
|
||||
|
||||
|
||||
Cell *(*proctab[93])(Node **, int) = {
|
||||
Cell *(*proctab[94])(Node **, int) = {
|
||||
nullproc, /* FIRSTTOKEN */
|
||||
program, /* PROGRAM */
|
||||
pastat, /* PASTAT */
|
||||
@ -183,24 +188,25 @@ Cell *(*proctab[93])(Node **, int) = {
|
||||
awkgetline, /* GETLINE */
|
||||
substr, /* SUBSTR */
|
||||
split, /* SPLIT */
|
||||
gensub, /* GENSUB */
|
||||
jump, /* RETURN */
|
||||
whilestat, /* WHILE */
|
||||
cat, /* CAT */
|
||||
arith, /* UMINUS */
|
||||
boolop, /* NOT */
|
||||
arith, /* UMINUS */
|
||||
arith, /* POWER */
|
||||
nullproc, /* INCR */
|
||||
nullproc, /* DECR */
|
||||
nullproc, /* INCR */
|
||||
indirect, /* INDIRECT */
|
||||
nullproc, /* LASTTOKEN */
|
||||
};
|
||||
|
||||
char *tokname(int n)
|
||||
const char *tokname(int n)
|
||||
{
|
||||
static char buf[100];
|
||||
|
||||
if (n < FIRSTTOKEN || n > LASTTOKEN) {
|
||||
sprintf(buf, "token %d", n);
|
||||
snprintf(buf, sizeof(buf), "token %d", n);
|
||||
return buf;
|
||||
}
|
||||
return printname[n-FIRSTTOKEN];
|
||||
|
26
external/historical/nawk/dist/proto.h
vendored
26
external/historical/nawk/dist/proto.h
vendored
@ -43,8 +43,8 @@ extern fa *mkdfa(const char *, int);
|
||||
extern int makeinit(fa *, int);
|
||||
extern void penter(Node *);
|
||||
extern void freetr(Node *);
|
||||
extern int hexstr(char **);
|
||||
extern int quoted(char **);
|
||||
extern int hexstr(const uschar **);
|
||||
extern int quoted(const uschar **);
|
||||
extern char *cclenter(const char *);
|
||||
extern void overflo(const char *);
|
||||
extern void cfoll(fa *, Node *);
|
||||
@ -73,12 +73,14 @@ extern Node *node1(int, Node *);
|
||||
extern Node *node2(int, Node *, Node *);
|
||||
extern Node *node3(int, Node *, Node *, Node *);
|
||||
extern Node *node4(int, Node *, Node *, Node *, Node *);
|
||||
extern Node *node5(int, Node *, Node *, Node *, Node *, Node *);
|
||||
extern Node *stat3(int, Node *, Node *, Node *);
|
||||
extern Node *op2(int, Node *, Node *);
|
||||
extern Node *op1(int, Node *);
|
||||
extern Node *stat1(int, Node *);
|
||||
extern Node *op3(int, Node *, Node *, Node *);
|
||||
extern Node *op4(int, Node *, Node *, Node *, Node *);
|
||||
extern Node *op5(int, Node *, Node *, Node *, Node *, Node *);
|
||||
extern Node *stat2(int, Node *, Node *);
|
||||
extern Node *stat4(int, Node *, Node *, Node *, Node *);
|
||||
extern Node *celltonode(Cell *, int);
|
||||
@ -88,7 +90,7 @@ extern Node *pa2stat(Node *, Node *, Node *);
|
||||
extern Node *linkum(Node *, Node *);
|
||||
extern void defn(Cell *, Node *, Node *);
|
||||
extern int isarg(const char *);
|
||||
extern char *tokname(int);
|
||||
extern const char *tokname(int);
|
||||
extern Cell *(*proctab[])(Node **, int);
|
||||
extern int ptoi(void *);
|
||||
extern Node *itonp(int);
|
||||
@ -110,15 +112,16 @@ extern double getfval(Cell *);
|
||||
extern char *getsval(Cell *);
|
||||
extern char *getpssval(Cell *); /* for print */
|
||||
extern char *tostring(const char *);
|
||||
extern char *tostringN(const char *, size_t n);
|
||||
extern char *qstring(const char *, int);
|
||||
|
||||
extern void recinit(unsigned int);
|
||||
extern void initgetrec(void);
|
||||
extern void makefields(int, int);
|
||||
extern void growfldtab(int n);
|
||||
extern int getrec(char **, int *, int);
|
||||
extern int getrec(uschar **, int *, int);
|
||||
extern void nextfile(void);
|
||||
extern int readrec(char **buf, int *bufsize, FILE *inf);
|
||||
extern int readrec(uschar **buf, int *bufsize, FILE *inf);
|
||||
extern char *getargv(int);
|
||||
extern void setclvar(char *);
|
||||
extern void fldbld(void);
|
||||
@ -128,12 +131,14 @@ extern int refldbld(const char *, const char *);
|
||||
extern void recbld(void);
|
||||
extern Cell *fieldadr(int);
|
||||
extern void yyerror(const char *);
|
||||
extern void fpecatch(int);
|
||||
extern void bracecheck(void);
|
||||
extern void bcheck2(int, int, int);
|
||||
extern void SYNTAX(const char *, ...);
|
||||
extern void FATAL(const char *, ...);
|
||||
extern void WARNING(const char *, ...);
|
||||
extern void SYNTAX(const char *, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
extern void FATAL(const char *, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
extern void WARNING(const char *, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
extern void error(void);
|
||||
extern void eprint(void);
|
||||
extern void bclass(int);
|
||||
@ -141,7 +146,7 @@ extern double errcheck(double, const char *);
|
||||
extern int isclvar(const char *);
|
||||
extern int is_number(const char *);
|
||||
|
||||
extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what);
|
||||
extern int adjbuf(uschar **pb, int *sz, int min, int q, uschar **pbp, const char *what);
|
||||
extern void run(Node *);
|
||||
extern Cell *execute(Node *);
|
||||
extern Cell *program(Node **, int);
|
||||
@ -190,6 +195,7 @@ extern Cell *closefile(Node **, int);
|
||||
extern void closeall(void);
|
||||
extern Cell *sub(Node **, int);
|
||||
extern Cell *gsub(Node **, int);
|
||||
extern Cell *gensub(Node **, int);
|
||||
|
||||
extern FILE *popen(const char *, const char *);
|
||||
extern int pclose(FILE *);
|
||||
|
547
external/historical/nawk/dist/run.c
vendored
547
external/historical/nawk/dist/run.c
vendored
@ -22,9 +22,15 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <setjmp.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
@ -32,9 +38,11 @@ THIS SOFTWARE.
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
#define tempfree(x) if (istemp(x)) tfree(x); else
|
||||
#define tempfree(x) do { if (istemp(x)) tfree(x); } while (/*CONSTCOND*/0)
|
||||
|
||||
void stdinit(void);
|
||||
|
||||
/*
|
||||
#undef tempfree
|
||||
@ -70,28 +78,28 @@ extern int pairstack[];
|
||||
Node *winner = NULL; /* root of parse tree */
|
||||
Cell *tmps; /* free temporary cells for execution */
|
||||
|
||||
static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM };
|
||||
static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM, NULL };
|
||||
Cell *True = &truecell;
|
||||
static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM };
|
||||
static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM, NULL };
|
||||
Cell *False = &falsecell;
|
||||
static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM };
|
||||
static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM, NULL };
|
||||
Cell *jbreak = &breakcell;
|
||||
static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM };
|
||||
static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM, NULL };
|
||||
Cell *jcont = &contcell;
|
||||
static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM };
|
||||
static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM, NULL };
|
||||
Cell *jnext = &nextcell;
|
||||
static Cell nextfilecell ={ OJUMP, JNEXTFILE, 0, 0, 0.0, NUM };
|
||||
static Cell nextfilecell ={ OJUMP, JNEXTFILE, 0, 0, 0.0, NUM, NULL};
|
||||
Cell *jnextfile = &nextfilecell;
|
||||
static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM };
|
||||
static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM, NULL };
|
||||
Cell *jexit = &exitcell;
|
||||
static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM };
|
||||
static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM, NULL };
|
||||
Cell *jret = &retcell;
|
||||
static Cell tempcell ={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE };
|
||||
static Cell tempcell ={ OCELL, CTEMP, 0, EMPTY, 0.0, NUM|STR|DONTFREE, NULL };
|
||||
|
||||
Node *curnode = NULL; /* the node being executed, for debugging */
|
||||
|
||||
/* buffer memory management */
|
||||
int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
|
||||
int adjbuf(uschar **pbuf, int *psiz, int minlen, int quantum, uschar **pbptr,
|
||||
const char *whatrtn)
|
||||
/* pbuf: address of pointer to buffer being managed
|
||||
* psiz: address of buffer size variable
|
||||
@ -110,7 +118,7 @@ int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
|
||||
/* round up to next multiple of quantum */
|
||||
if (rminlen)
|
||||
minlen += quantum - rminlen;
|
||||
tbuf = (char *) realloc(*pbuf, minlen);
|
||||
tbuf = realloc(*pbuf, minlen);
|
||||
dprintf( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) );
|
||||
if (tbuf == NULL) {
|
||||
if (whatrtn)
|
||||
@ -127,8 +135,6 @@ int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
|
||||
|
||||
void run(Node *a) /* execution of parse tree starts here */
|
||||
{
|
||||
extern void stdinit(void);
|
||||
|
||||
stdinit();
|
||||
execute(a);
|
||||
closeall();
|
||||
@ -216,11 +222,11 @@ struct Frame { /* stack frame for awk function calls */
|
||||
|
||||
struct Frame *frame = NULL; /* base of stack frames; dynamically allocated */
|
||||
int nframe = 0; /* number of frames allocated */
|
||||
struct Frame *fp = NULL; /* frame pointer. bottom level unused */
|
||||
struct Frame *frp = NULL; /* frame pointer. bottom level unused */
|
||||
|
||||
Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
|
||||
{
|
||||
static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE };
|
||||
static const Cell newcopycell = { OCELL, CCOPY, 0, EMPTY, 0.0, NUM|STR|DONTFREE, NULL };
|
||||
int i, ncall, ndef;
|
||||
int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */
|
||||
Node *x;
|
||||
@ -233,21 +239,21 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
|
||||
if (!isfcn(fcn))
|
||||
FATAL("calling undefined function %s", s);
|
||||
if (frame == NULL) {
|
||||
fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame));
|
||||
frp = frame = calloc(nframe += 100, sizeof(*frp));
|
||||
if (frame == NULL)
|
||||
FATAL("out of space for stack frames calling %s", s);
|
||||
}
|
||||
for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */
|
||||
ncall++;
|
||||
ndef = (int) fcn->fval; /* args in defn */
|
||||
dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) );
|
||||
dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (frp-frame)) );
|
||||
if (ncall > ndef)
|
||||
WARNING("function %s called with %d args, uses only %d",
|
||||
s, ncall, ndef);
|
||||
if (ncall + ndef > NARGS)
|
||||
FATAL("function %s has %d arguments, limit %d", s, ncall+ndef, NARGS);
|
||||
for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */
|
||||
dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) );
|
||||
dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (frp-frame)) );
|
||||
y = execute(x);
|
||||
oargs[i] = y;
|
||||
dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
|
||||
@ -264,26 +270,25 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
|
||||
args[i] = gettemp();
|
||||
*args[i] = newcopycell;
|
||||
}
|
||||
fp++; /* now ok to up frame */
|
||||
if (fp >= frame + nframe) {
|
||||
int dfp = fp - frame; /* old index */
|
||||
frame = (struct Frame *)
|
||||
realloc((char *) frame, (nframe += 100) * sizeof(struct Frame));
|
||||
frp++; /* now ok to up frame */
|
||||
if (frp >= frame + nframe) {
|
||||
int dfp = frp - frame; /* old index */
|
||||
frame = realloc(frame, (nframe += 100) * sizeof(*frame));
|
||||
if (frame == NULL)
|
||||
FATAL("out of space for stack frames in %s", s);
|
||||
fp = frame + dfp;
|
||||
frp = frame + dfp;
|
||||
}
|
||||
fp->fcncell = fcn;
|
||||
fp->args = args;
|
||||
fp->nargs = ndef; /* number defined with (excess are locals) */
|
||||
fp->retval = gettemp();
|
||||
frp->fcncell = fcn;
|
||||
frp->args = args;
|
||||
frp->nargs = ndef; /* number defined with (excess are locals) */
|
||||
frp->retval = gettemp();
|
||||
|
||||
dprintf( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) );
|
||||
dprintf( ("start exec of %s, fp=%d\n", s, (int) (frp-frame)) );
|
||||
y = execute((Node *)(fcn->sval)); /* execute body */
|
||||
dprintf( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) );
|
||||
dprintf( ("finished exec of %s, fp=%d\n", s, (int) (frp-frame)) );
|
||||
|
||||
for (i = 0; i < ndef; i++) {
|
||||
Cell *t = fp->args[i];
|
||||
Cell *t = frp->args[i];
|
||||
if (isarr(t)) {
|
||||
if (t->csub == CCOPY) {
|
||||
if (i >= ncall) {
|
||||
@ -312,9 +317,9 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
|
||||
if (freed == 0) {
|
||||
tempfree(y); /* don't free twice! */
|
||||
}
|
||||
z = fp->retval; /* return value */
|
||||
z = frp->retval; /* return value */
|
||||
dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );
|
||||
fp--;
|
||||
frp--;
|
||||
return(z);
|
||||
}
|
||||
|
||||
@ -322,14 +327,18 @@ Cell *copycell(Cell *x) /* make a copy of a cell in a temp */
|
||||
{
|
||||
Cell *y;
|
||||
|
||||
/* copy is not constant or field */
|
||||
|
||||
y = gettemp();
|
||||
y->tval = x->tval & ~(CON|FLD|REC);
|
||||
y->csub = CCOPY; /* prevents freeing until call is over */
|
||||
y->nval = x->nval; /* BUG? */
|
||||
if (isstr(x))
|
||||
if (isstr(x) /* || x->ctype == OCELL */) {
|
||||
y->sval = tostring(x->sval);
|
||||
y->tval &= ~DONTFREE;
|
||||
} else
|
||||
y->tval |= DONTFREE;
|
||||
y->fval = x->fval;
|
||||
y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); /* copy is not constant or field */
|
||||
/* is DONTFREE right? */
|
||||
return y;
|
||||
}
|
||||
|
||||
@ -337,11 +346,11 @@ Cell *arg(Node **a, int n) /* nth argument of a function */
|
||||
{
|
||||
|
||||
n = ptoi(a[0]); /* argument number, counting from 0 */
|
||||
dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) );
|
||||
if (n+1 > fp->nargs)
|
||||
dprintf( ("arg(%d), fp->nargs=%d\n", n, frp->nargs) );
|
||||
if (n+1 > frp->nargs)
|
||||
FATAL("argument #%d of function %s was not supplied",
|
||||
n+1, fp->fcncell->nval);
|
||||
return fp->args[n];
|
||||
n+1, frp->fcncell->nval);
|
||||
return frp->args[n];
|
||||
}
|
||||
|
||||
Cell *jump(Node **a, int n) /* break, continue, next, nextfile, return */
|
||||
@ -360,14 +369,14 @@ Cell *jump(Node **a, int n) /* break, continue, next, nextfile, return */
|
||||
if (a[0] != NULL) {
|
||||
y = execute(a[0]);
|
||||
if ((y->tval & (STR|NUM)) == (STR|NUM)) {
|
||||
setsval(fp->retval, getsval(y));
|
||||
fp->retval->fval = getfval(y);
|
||||
fp->retval->tval |= NUM;
|
||||
setsval(frp->retval, getsval(y));
|
||||
frp->retval->fval = getfval(y);
|
||||
frp->retval->tval |= NUM;
|
||||
}
|
||||
else if (y->tval & STR)
|
||||
setsval(fp->retval, getsval(y));
|
||||
setsval(frp->retval, getsval(y));
|
||||
else if (y->tval & NUM)
|
||||
setfval(fp->retval, getfval(y));
|
||||
setfval(frp->retval, getfval(y));
|
||||
else /* can't happen */
|
||||
FATAL("bad type variable %d", y->tval);
|
||||
tempfree(y);
|
||||
@ -393,11 +402,11 @@ Cell *awkgetline(Node **a, int n) /* get next line from specific input */
|
||||
Cell *r, *x;
|
||||
extern Cell **fldtab;
|
||||
FILE *fp;
|
||||
char *buf;
|
||||
uschar *buf;
|
||||
int bufsize = recsize;
|
||||
int mode;
|
||||
|
||||
if ((buf = (char *) malloc(bufsize)) == NULL)
|
||||
if ((buf = malloc(bufsize)) == NULL)
|
||||
FATAL("out of memory in getline");
|
||||
|
||||
fflush(stdout); /* in case someone is waiting for a prompt */
|
||||
@ -453,11 +462,11 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
|
||||
Cell *x, *y, *z;
|
||||
char *s;
|
||||
Node *np;
|
||||
char *buf;
|
||||
uschar *buf;
|
||||
int bufsz = recsize;
|
||||
int nsub = strlen(*SUBSEP);
|
||||
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL)
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in array");
|
||||
|
||||
x = execute(a[0]); /* Cell* for symbol table */
|
||||
@ -467,9 +476,9 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
|
||||
s = getsval(y);
|
||||
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);
|
||||
strlcat(buf, s, bufsz);
|
||||
if (np->nnext)
|
||||
strcat(buf, *SUBSEP);
|
||||
strlcat(buf, *SUBSEP, bufsz);
|
||||
tempfree(y);
|
||||
}
|
||||
if (!isarr(x)) {
|
||||
@ -492,7 +501,7 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
|
||||
{
|
||||
Cell *x, *y;
|
||||
Node *np;
|
||||
char *s;
|
||||
uschar *s;
|
||||
int nsub = strlen(*SUBSEP);
|
||||
|
||||
x = execute(a[0]); /* Cell* for symbol table */
|
||||
@ -505,8 +514,8 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
|
||||
x->sval = (char *) makesymtab(NSYMTAB);
|
||||
} else {
|
||||
int bufsz = recsize;
|
||||
char *buf;
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL)
|
||||
uschar *buf;
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in adelete");
|
||||
buf[0] = 0;
|
||||
for (np = a[1]; np; np = np->nnext) {
|
||||
@ -514,9 +523,9 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
|
||||
s = getsval(y);
|
||||
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);
|
||||
strlcat(buf, s, bufsz);
|
||||
if (np->nnext)
|
||||
strcat(buf, *SUBSEP);
|
||||
strlcat(buf, *SUBSEP, bufsz);
|
||||
tempfree(y);
|
||||
}
|
||||
freeelem(x, buf);
|
||||
@ -530,7 +539,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
|
||||
{
|
||||
Cell *x, *ap, *k;
|
||||
Node *p;
|
||||
char *buf;
|
||||
uschar *buf;
|
||||
char *s;
|
||||
int bufsz = recsize;
|
||||
int nsub = strlen(*SUBSEP);
|
||||
@ -544,7 +553,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
|
||||
ap->tval |= ARR;
|
||||
ap->sval = (char *) makesymtab(NSYMTAB);
|
||||
}
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL) {
|
||||
if ((buf = malloc(bufsz)) == NULL) {
|
||||
FATAL("out of memory in intest");
|
||||
}
|
||||
buf[0] = 0;
|
||||
@ -571,7 +580,8 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
|
||||
Cell *matchop(Node **a, int n) /* ~ and match() */
|
||||
{
|
||||
Cell *x, *y;
|
||||
char *s, *t;
|
||||
uschar *s;
|
||||
char *t;
|
||||
int i;
|
||||
fa *pfa;
|
||||
int (*mf)(fa *, const char *) = match, mode = 0;
|
||||
@ -693,7 +703,7 @@ Cell *gettemp(void) /* get a tempcell */
|
||||
Cell *x;
|
||||
|
||||
if (!tmps) {
|
||||
tmps = (Cell *) calloc(100, sizeof(Cell));
|
||||
tmps = calloc(100, sizeof(*tmps));
|
||||
if (!tmps)
|
||||
FATAL("out of space for temporaries");
|
||||
for(i = 1; i < 100; i++)
|
||||
@ -806,19 +816,20 @@ Cell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */
|
||||
|
||||
int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */
|
||||
{
|
||||
char *fmt;
|
||||
char *p, *t;
|
||||
uschar *fmt, *p, *t;
|
||||
const char *os;
|
||||
Cell *x;
|
||||
int flag = 0, n;
|
||||
int fmtwd; /* format width */
|
||||
int fmtsz = recsize;
|
||||
char *buf = *pbuf;
|
||||
uschar *buf = *pbuf;
|
||||
int bufsize = *pbufsize;
|
||||
#define FMTSZ(a) (fmtsz - ((a) - fmt))
|
||||
#define BUFSZ(a) (bufsize - ((a) - buf))
|
||||
|
||||
os = s;
|
||||
p = buf;
|
||||
if ((fmt = (char *) malloc(fmtsz)) == NULL)
|
||||
if ((fmt = malloc(fmtsz)) == NULL)
|
||||
FATAL("out of memory in format()");
|
||||
while (*s) {
|
||||
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1");
|
||||
@ -839,12 +850,18 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
for (t = fmt; (*t++ = *s) != '\0'; s++) {
|
||||
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')
|
||||
if (*s == 'l' || *s == 'h' || *s == 'L')
|
||||
goto weird;
|
||||
if (isalpha((uschar)*s))
|
||||
break; /* the ansi panoply */
|
||||
if (*s == '*') {
|
||||
if (a == NULL)
|
||||
FATAL("not enough args in printf("
|
||||
"\"%.30s\")", os);
|
||||
x = execute(a);
|
||||
a = a->nnext;
|
||||
sprintf(t-1, "%d", fmtwd=(int) getfval(x));
|
||||
snprintf(t - 1, FMTSZ(t - 1),
|
||||
"%d", fmtwd=(int) getfval(x));
|
||||
if (fmtwd < 0)
|
||||
fmtwd = -fmtwd;
|
||||
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
|
||||
@ -878,6 +895,7 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
flag = 'c';
|
||||
break;
|
||||
default:
|
||||
weird:
|
||||
WARNING("weird printf conversion %s", fmt);
|
||||
flag = '?';
|
||||
break;
|
||||
@ -891,18 +909,18 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
n = fmtwd;
|
||||
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5");
|
||||
switch (flag) {
|
||||
case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */
|
||||
case '?': snprintf(p, BUFSZ(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, "format6");
|
||||
p += strlen(p);
|
||||
sprintf(p, "%s", t);
|
||||
snprintf(p, BUFSZ(p), "%s", t);
|
||||
break;
|
||||
case 'f': sprintf(p, fmt, getfval(x)); break;
|
||||
case 'd': sprintf(p, fmt, (long) getfval(x)); break;
|
||||
case 'u': sprintf(p, fmt, (int) getfval(x)); break;
|
||||
case 'f': snprintf(p, BUFSZ(p), fmt, getfval(x)); break;
|
||||
case 'd': snprintf(p, BUFSZ(p), fmt, (long) getfval(x)); break;
|
||||
case 'u': snprintf(p, BUFSZ(p), fmt, (int) getfval(x)); break;
|
||||
case 's':
|
||||
t = getsval(x);
|
||||
n = strlen(t);
|
||||
@ -910,18 +928,18 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
|
||||
n = fmtwd;
|
||||
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);
|
||||
snprintf(p, BUFSZ(p), fmt, t);
|
||||
break;
|
||||
case 'c':
|
||||
if (isnum(x)) {
|
||||
if (getfval(x))
|
||||
sprintf(p, fmt, (int) getfval(x));
|
||||
snprintf(p, BUFSZ(p), fmt, (int) getfval(x));
|
||||
else {
|
||||
*p++ = '\0'; /* explicit null byte */
|
||||
*p = '\0'; /* next output will start here */
|
||||
}
|
||||
} else
|
||||
sprintf(p, fmt, getsval(x)[0]);
|
||||
snprintf(p, BUFSZ(p), fmt, getsval(x)[0]);
|
||||
break;
|
||||
default:
|
||||
FATAL("can't happen: bad conversion %c in format()", flag);
|
||||
@ -946,7 +964,7 @@ Cell *awksprintf(Node **a, int n) /* sprintf(a[0]) */
|
||||
char *buf;
|
||||
int bufsz=3*recsize;
|
||||
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL)
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in awksprintf");
|
||||
y = a[0]->nnext;
|
||||
x = execute(a[0]);
|
||||
@ -969,7 +987,7 @@ Cell *awkprintf(Node **a, int n) /* printf */
|
||||
int len;
|
||||
int bufsz=3*recsize;
|
||||
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL)
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in awkprintf");
|
||||
y = a[0]->nnext;
|
||||
x = execute(a[0]);
|
||||
@ -1153,7 +1171,7 @@ Cell *cat(Node **a, int q) /* a[0] cat a[1] */
|
||||
getsval(y);
|
||||
n1 = strlen(x->sval);
|
||||
n2 = strlen(y->sval);
|
||||
s = (char *) malloc(n1 + n2 + 1);
|
||||
s = malloc(n1 + n2 + 1);
|
||||
if (s == NULL)
|
||||
FATAL("out of space concatenating %.15s... and %.15s...",
|
||||
x->sval, y->sval);
|
||||
@ -1206,6 +1224,7 @@ Cell *dopa2(Node **a, int n) /* a[0], a[1] { a[2] } */
|
||||
return(False);
|
||||
}
|
||||
|
||||
static char regexpr[] = "(regexpr)";
|
||||
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
{
|
||||
Cell *x = 0, *y, *ap;
|
||||
@ -1223,7 +1242,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
x = execute(a[2]);
|
||||
fs = getsval(x);
|
||||
} else if (arg3type == REGEXPR)
|
||||
fs = "(regexpr)"; /* split(str,arr,/regexpr/) */
|
||||
fs = regexpr; /* split(str,arr,/regexpr/) */
|
||||
else
|
||||
FATAL("illegal type of split");
|
||||
sep = *fs;
|
||||
@ -1247,7 +1266,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
pfa->initstat = 2;
|
||||
do {
|
||||
n++;
|
||||
sprintf(num, "%d", n);
|
||||
snprintf(num, sizeof(num), "%d", n);
|
||||
temp = *patbeg;
|
||||
*patbeg = '\0';
|
||||
if (is_number(s))
|
||||
@ -1258,7 +1277,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
s = patbeg + patlen;
|
||||
if (*(patbeg+patlen-1) == 0 || *s == 0) {
|
||||
n++;
|
||||
sprintf(num, "%d", n);
|
||||
snprintf(num, sizeof(num), "%d", n);
|
||||
setsymtab(num, "", 0.0, STR, (Array *) ap->sval);
|
||||
pfa->initstat = tempstat;
|
||||
goto spdone;
|
||||
@ -1268,7 +1287,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
/* cf gsub and refldbld */
|
||||
}
|
||||
n++;
|
||||
sprintf(num, "%d", n);
|
||||
snprintf(num, sizeof(num), "%d", n);
|
||||
if (is_number(s))
|
||||
setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval);
|
||||
else
|
||||
@ -1288,7 +1307,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');
|
||||
temp = *s;
|
||||
*s = '\0';
|
||||
sprintf(num, "%d", n);
|
||||
snprintf(num, sizeof(num), "%d", n);
|
||||
if (is_number(t))
|
||||
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
|
||||
else
|
||||
@ -1301,7 +1320,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
for (n = 0; *s != 0; s++) {
|
||||
char buf[2];
|
||||
n++;
|
||||
sprintf(num, "%d", n);
|
||||
snprintf(num, sizeof(num), "%d", n);
|
||||
buf[0] = *s;
|
||||
buf[1] = 0;
|
||||
if (isdigit((uschar)buf[0]))
|
||||
@ -1317,7 +1336,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
s++;
|
||||
temp = *s;
|
||||
*s = '\0';
|
||||
sprintf(num, "%d", n);
|
||||
snprintf(num, sizeof(num), "%d", n);
|
||||
if (is_number(t))
|
||||
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
|
||||
else
|
||||
@ -1461,15 +1480,77 @@ Cell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */
|
||||
return True;
|
||||
}
|
||||
|
||||
void flush_all(void);
|
||||
|
||||
static char *nawk_toXXX(const char *s,
|
||||
int (*fun_c)(int),
|
||||
wint_t (*fun_wc)(wint_t))
|
||||
{
|
||||
char *buf = NULL;
|
||||
char *pbuf = NULL;
|
||||
const char *ps = NULL;
|
||||
size_t n = 0;
|
||||
mbstate_t mbs, mbs2;
|
||||
wchar_t wc;
|
||||
size_t sz = MB_CUR_MAX;
|
||||
|
||||
if (sz == 1) {
|
||||
buf = tostring(s);
|
||||
|
||||
for (pbuf = buf; *pbuf; pbuf++)
|
||||
*pbuf = fun_c((uschar)*pbuf);
|
||||
|
||||
return buf;
|
||||
} else {
|
||||
/* upper/lower character may be shorter/longer */
|
||||
buf = tostringN(s, strlen(s) * sz + 1);
|
||||
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
memset(&mbs2, 0, sizeof(mbs2));
|
||||
|
||||
ps = s;
|
||||
pbuf = buf;
|
||||
while (n = mbrtowc(&wc, ps, sz, &mbs),
|
||||
n > 0 && n != (size_t)-1 && n != (size_t)-2)
|
||||
{
|
||||
ps += n;
|
||||
|
||||
n = wcrtomb(pbuf, fun_wc(wc), &mbs2);
|
||||
if (n == (size_t)-1)
|
||||
FATAL("illegal wide character %s", s);
|
||||
|
||||
pbuf += n;
|
||||
}
|
||||
|
||||
*pbuf = 0;
|
||||
|
||||
if (n)
|
||||
FATAL("illegal byte sequence %s", s);
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
static char *nawk_toupper(const char *s)
|
||||
{
|
||||
return nawk_toXXX(s, toupper, towupper);
|
||||
}
|
||||
|
||||
static char *nawk_tolower(const char *s)
|
||||
{
|
||||
return nawk_toXXX(s, tolower, towlower);
|
||||
}
|
||||
|
||||
Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */
|
||||
{
|
||||
Cell *x, *y;
|
||||
Awkfloat u;
|
||||
int t;
|
||||
char *p, *buf;
|
||||
int t, sz;
|
||||
char *buf, *fmt;
|
||||
Node *nextarg;
|
||||
FILE *fp;
|
||||
void flush_all(void);
|
||||
time_t tv;
|
||||
struct tm *tm;
|
||||
|
||||
t = ptoi(a[0]);
|
||||
x = execute(a[1]);
|
||||
@ -1521,16 +1602,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
|
||||
break;
|
||||
case FTOUPPER:
|
||||
case FTOLOWER:
|
||||
buf = tostring(getsval(x));
|
||||
if (t == FTOUPPER) {
|
||||
for (p = buf; *p; p++)
|
||||
if (islower((uschar) *p))
|
||||
*p = toupper((uschar)*p);
|
||||
} else {
|
||||
for (p = buf; *p; p++)
|
||||
if (isupper((uschar) *p))
|
||||
*p = tolower((uschar)*p);
|
||||
}
|
||||
if (t == FTOUPPER)
|
||||
buf = nawk_toupper(getsval(x));
|
||||
else
|
||||
buf = nawk_tolower(getsval(x));
|
||||
tempfree(x);
|
||||
x = gettemp();
|
||||
setsval(x, buf);
|
||||
@ -1541,10 +1616,40 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
|
||||
flush_all(); /* fflush() or fflush("") -> all */
|
||||
u = 0;
|
||||
} else if ((fp = openfile(FFLUSH, getsval(x))) == NULL)
|
||||
u = EOF;
|
||||
u = -1;
|
||||
else
|
||||
u = fflush(fp);
|
||||
break;
|
||||
case FSYSTIME:
|
||||
u = time((time_t *) 0); break;
|
||||
case FSTRFTIME:
|
||||
/* strftime([format [,timestamp]]) */
|
||||
if (nextarg) {
|
||||
y = execute(nextarg), nextarg = nextarg->nnext;
|
||||
tv = (time_t) getfval(y);
|
||||
tempfree(y);
|
||||
} else
|
||||
tv = time((time_t *) 0);
|
||||
tm = localtime(&tv);
|
||||
|
||||
if (isrec(x)) {
|
||||
/* format argument not provided, use default */
|
||||
fmt = tostring("%a %b %d %H:%M:%S %Z %Y");
|
||||
} else
|
||||
fmt = tostring(getsval(x));
|
||||
|
||||
sz = 32, buf = NULL;
|
||||
do {
|
||||
if ((buf = realloc(buf, (sz *= 2))) == NULL)
|
||||
FATAL("out of memory in strftime");
|
||||
} while(strftime(buf, sz, fmt, tm) == 0);
|
||||
|
||||
y = gettemp();
|
||||
setsval(y, buf);
|
||||
free(fmt);
|
||||
free(buf);
|
||||
|
||||
return y;
|
||||
default: /* can't happen */
|
||||
FATAL("illegal function type %d", t);
|
||||
break;
|
||||
@ -1613,28 +1718,36 @@ struct files {
|
||||
FILE *fp;
|
||||
const char *fname;
|
||||
int mode; /* '|', 'a', 'w' => LE/LT, GT */
|
||||
} files[FOPEN_MAX] ={
|
||||
{ NULL, "/dev/stdin", LT }, /* watch out: don't free this! */
|
||||
{ NULL, "/dev/stdout", GT },
|
||||
{ NULL, "/dev/stderr", GT }
|
||||
};
|
||||
} *files;
|
||||
size_t nfiles;
|
||||
|
||||
void stdinit(void) /* in case stdin, etc., are not constants */
|
||||
{
|
||||
nfiles = FOPEN_MAX;
|
||||
files = calloc(nfiles, sizeof(*files));
|
||||
if (files == NULL)
|
||||
FATAL("can't allocate file memory for %zu files", nfiles);
|
||||
files[0].fp = stdin;
|
||||
files[0].fname = "/dev/stdin";
|
||||
files[0].mode = LT;
|
||||
files[1].fp = stdout;
|
||||
files[1].fname = "/dev/stdout";
|
||||
files[1].mode = GT;
|
||||
files[2].fp = stderr;
|
||||
files[2].fname = "/dev/stderr";
|
||||
files[2].mode = GT;
|
||||
}
|
||||
|
||||
FILE *openfile(int a, const char *us)
|
||||
{
|
||||
const char *s = us;
|
||||
int i, m;
|
||||
size_t i;
|
||||
int m;
|
||||
FILE *fp = 0;
|
||||
|
||||
if (*s == '\0')
|
||||
FATAL("null file name in print or getline");
|
||||
for (i=0; i < FOPEN_MAX; i++)
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (files[i].fname && strcmp(s, files[i].fname) == 0) {
|
||||
if (a == files[i].mode || (a==APPEND && files[i].mode==GT))
|
||||
return files[i].fp;
|
||||
@ -1644,11 +1757,19 @@ FILE *openfile(int a, const char *us)
|
||||
if (a == FFLUSH) /* didn't find it, so don't create it! */
|
||||
return NULL;
|
||||
|
||||
for (i=0; i < FOPEN_MAX; i++)
|
||||
if (files[i].fp == 0)
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (files[i].fp == NULL)
|
||||
break;
|
||||
if (i >= FOPEN_MAX)
|
||||
FATAL("%s makes too many open files", s);
|
||||
if (i >= nfiles) {
|
||||
struct files *nf;
|
||||
size_t nnf = nfiles + FOPEN_MAX;
|
||||
nf = realloc(files, nnf * sizeof(*nf));
|
||||
if (nf == NULL)
|
||||
FATAL("cannot grow files for %s and %zu files", s, nnf);
|
||||
(void)memset(&nf[nfiles], 0, FOPEN_MAX * sizeof(*nf));
|
||||
nfiles = nnf;
|
||||
files = nf;
|
||||
}
|
||||
fflush(stdout); /* force a semblance of order */
|
||||
m = a;
|
||||
if (a == GT) {
|
||||
@ -1674,9 +1795,9 @@ FILE *openfile(int a, const char *us)
|
||||
|
||||
const char *filename(FILE *fp)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < FOPEN_MAX; i++)
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (fp == files[i].fp)
|
||||
return files[i].fname;
|
||||
return "???";
|
||||
@ -1685,24 +1806,28 @@ const char *filename(FILE *fp)
|
||||
Cell *closefile(Node **a, int n)
|
||||
{
|
||||
Cell *x;
|
||||
int i, stat;
|
||||
size_t i;
|
||||
int stat;
|
||||
|
||||
n = n;
|
||||
x = execute(a[0]);
|
||||
getsval(x);
|
||||
stat = -1;
|
||||
for (i = 0; i < FOPEN_MAX; i++) {
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
|
||||
if (ferror(files[i].fp))
|
||||
WARNING( "i/o error occurred on %s", files[i].fname );
|
||||
if (files[i].mode == '|' || files[i].mode == LE)
|
||||
stat = pclose(files[i].fp);
|
||||
stat = pclose(files[i].fp) == -1;
|
||||
else
|
||||
stat = fclose(files[i].fp);
|
||||
if (stat == EOF)
|
||||
WARNING( "i/o error occurred closing %s", files[i].fname );
|
||||
stat = fclose(files[i].fp) == EOF;
|
||||
if (stat) {
|
||||
stat = -1;
|
||||
WARNING( "i/o error occurred closing %s",
|
||||
files[i].fname );
|
||||
}
|
||||
if (i > 2) /* don't do /dev/std... */
|
||||
xfree(files[i].fname);
|
||||
free(__UNCONST(files[i].fname));
|
||||
files[i].fname = NULL; /* watch out for ref thru this */
|
||||
files[i].fp = NULL;
|
||||
}
|
||||
@ -1715,17 +1840,22 @@ Cell *closefile(Node **a, int n)
|
||||
|
||||
void closeall(void)
|
||||
{
|
||||
int i, stat;
|
||||
size_t i;
|
||||
int stat;
|
||||
|
||||
for (i = 0; i < FOPEN_MAX; i++) {
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
if (files[i].fp) {
|
||||
if (ferror(files[i].fp))
|
||||
WARNING( "i/o error occurred on %s", files[i].fname );
|
||||
if (files[i].mode == '|' || files[i].mode == LE)
|
||||
stat = pclose(files[i].fp);
|
||||
if (i == 0)
|
||||
stat = fpurge(files[i].fp) == EOF;
|
||||
else if (i <= 2)
|
||||
stat = fflush(files[i].fp) == EOF;
|
||||
else if (files[i].mode == '|' || files[i].mode == LE)
|
||||
stat = pclose(files[i].fp) == -1;
|
||||
else
|
||||
stat = fclose(files[i].fp);
|
||||
if (stat == EOF)
|
||||
stat = fclose(files[i].fp) == EOF;
|
||||
if (stat)
|
||||
WARNING( "i/o error occurred while closing %s", files[i].fname );
|
||||
}
|
||||
}
|
||||
@ -1733,24 +1863,25 @@ void closeall(void)
|
||||
|
||||
void flush_all(void)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < FOPEN_MAX; i++)
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (files[i].fp)
|
||||
fflush(files[i].fp);
|
||||
}
|
||||
|
||||
void backsub(char **pb_ptr, char **sptr_ptr);
|
||||
void backsub(uschar **pb_ptr, const uschar **sptr_ptr);
|
||||
|
||||
Cell *sub(Node **a, int nnn) /* substitute command */
|
||||
{
|
||||
char *sptr, *pb, *q;
|
||||
const uschar *sptr;
|
||||
uschar *q;
|
||||
Cell *x, *y, *result;
|
||||
char *t, *buf;
|
||||
uschar *t, *buf, *pb;
|
||||
fa *pfa;
|
||||
int bufsz = recsize;
|
||||
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL)
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in sub");
|
||||
x = execute(a[3]); /* target string */
|
||||
t = getsval(x);
|
||||
@ -1805,13 +1936,15 @@ Cell *sub(Node **a, int nnn) /* substitute command */
|
||||
Cell *gsub(Node **a, int nnn) /* global substitute */
|
||||
{
|
||||
Cell *x, *y;
|
||||
char *rptr, *sptr, *t, *pb, *q;
|
||||
char *buf;
|
||||
const char *rptr;
|
||||
const uschar *sptr;
|
||||
uschar *t, *q;
|
||||
uschar *pb, *buf;
|
||||
fa *pfa;
|
||||
int mflag, tempstat, num;
|
||||
int bufsz = recsize;
|
||||
|
||||
if ((buf = (char *) malloc(bufsz)) == NULL)
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in gsub");
|
||||
mflag = 0; /* if mflag == 0, can replace empty string */
|
||||
num = 0;
|
||||
@ -1903,9 +2036,149 @@ Cell *gsub(Node **a, int nnn) /* global substitute */
|
||||
return(x);
|
||||
}
|
||||
|
||||
void backsub(char **pb_ptr, char **sptr_ptr) /* handle \\& variations */
|
||||
Cell *gensub(Node **a, int nnn) /* global selective substitute */
|
||||
/* XXX incomplete - doesn't support backreferences \0 ... \9 */
|
||||
{
|
||||
Cell *x, *y, *res, *h;
|
||||
char *rptr;
|
||||
const uschar *sptr;
|
||||
uschar *q, *pb, *t, *buf;
|
||||
fa *pfa;
|
||||
int mflag, tempstat, num, whichm;
|
||||
int bufsz = recsize;
|
||||
|
||||
if ((buf = malloc(bufsz)) == NULL)
|
||||
FATAL("out of memory in gensub");
|
||||
mflag = 0; /* if mflag == 0, can replace empty string */
|
||||
num = 0;
|
||||
x = execute(a[4]); /* source string */
|
||||
t = getsval(x);
|
||||
res = copycell(x); /* target string - initially copy of source */
|
||||
if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */
|
||||
pfa = (fa *) a[1]; /* regular expression */
|
||||
else {
|
||||
y = execute(a[1]);
|
||||
pfa = makedfa(getsval(y), 1);
|
||||
tempfree(y);
|
||||
}
|
||||
y = execute(a[2]); /* replacement string */
|
||||
h = execute(a[3]); /* which matches should be replaced */
|
||||
sptr = getsval(h);
|
||||
if (sptr[0] == 'g' || sptr[0] == 'G')
|
||||
whichm = -1;
|
||||
else {
|
||||
/*
|
||||
* The specified number is index of replacement, starting
|
||||
* from 1. GNU awk treats index lower than 0 same as
|
||||
* 1, we do same for compatibility.
|
||||
*/
|
||||
whichm = (int) getfval(h) - 1;
|
||||
if (whichm < 0)
|
||||
whichm = 0;
|
||||
}
|
||||
tempfree(h);
|
||||
|
||||
if (pmatch(pfa, t)) {
|
||||
char *sl;
|
||||
|
||||
tempstat = pfa->initstat;
|
||||
pfa->initstat = 2;
|
||||
pb = buf;
|
||||
rptr = getsval(y);
|
||||
/*
|
||||
* XXX if there are any backreferences in subst string,
|
||||
* complain now.
|
||||
*/
|
||||
for(sl=rptr; (sl = strchr(sl, '\\')) && sl[1]; sl++) {
|
||||
if (strchr("0123456789", sl[1])) {
|
||||
FATAL("gensub doesn't support backreferences (subst \"%s\")", rptr);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (whichm >= 0 && whichm != num) {
|
||||
num++;
|
||||
adjbuf(&buf, &bufsz, (pb - buf) + (patbeg - t) + patlen, recsize, &pb, "gensub");
|
||||
|
||||
/* copy the part of string up to and including
|
||||
* match to output buffer */
|
||||
while (t < patbeg + patlen)
|
||||
*pb++ = *t++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (patlen == 0 && *patbeg != 0) { /* matched empty string */
|
||||
if (mflag == 0) { /* can replace empty */
|
||||
num++;
|
||||
sptr = rptr;
|
||||
while (*sptr != 0) {
|
||||
adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gensub");
|
||||
if (*sptr == '\\') {
|
||||
backsub(&pb, &sptr);
|
||||
} else if (*sptr == '&') {
|
||||
sptr++;
|
||||
adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gensub");
|
||||
for (q = patbeg; q < patbeg+patlen; )
|
||||
*pb++ = *q++;
|
||||
} else
|
||||
*pb++ = *sptr++;
|
||||
}
|
||||
}
|
||||
if (*t == 0) /* at end */
|
||||
goto done;
|
||||
adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gensub");
|
||||
*pb++ = *t++;
|
||||
if (pb > buf + bufsz) /* BUG: not sure of this test */
|
||||
FATAL("gensub result0 %.30s too big; can't happen", buf);
|
||||
mflag = 0;
|
||||
}
|
||||
else { /* matched nonempty string */
|
||||
num++;
|
||||
sptr = t;
|
||||
adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gensub");
|
||||
while (sptr < patbeg)
|
||||
*pb++ = *sptr++;
|
||||
sptr = rptr;
|
||||
while (*sptr != 0) {
|
||||
adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gensub");
|
||||
if (*sptr == '\\') {
|
||||
backsub(&pb, &sptr);
|
||||
} else if (*sptr == '&') {
|
||||
sptr++;
|
||||
adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gensub");
|
||||
for (q = patbeg; q < patbeg+patlen; )
|
||||
*pb++ = *q++;
|
||||
} else
|
||||
*pb++ = *sptr++;
|
||||
}
|
||||
t = patbeg + patlen;
|
||||
if (patlen == 0 || *t == 0 || *(t-1) == 0)
|
||||
goto done;
|
||||
if (pb > buf + bufsz)
|
||||
FATAL("gensub result1 %.30s too big; can't happen", buf);
|
||||
mflag = 1;
|
||||
}
|
||||
} while (pmatch(pfa,t));
|
||||
sptr = t;
|
||||
adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gensub");
|
||||
while ((*pb++ = *sptr++) != 0)
|
||||
;
|
||||
done: if (pb > buf + bufsz)
|
||||
FATAL("gensub result2 %.30s too big; can't happen", buf);
|
||||
*pb = '\0';
|
||||
setsval(res, buf);
|
||||
pfa->initstat = tempstat;
|
||||
}
|
||||
tempfree(x);
|
||||
tempfree(y);
|
||||
free(buf);
|
||||
return(res);
|
||||
}
|
||||
|
||||
void backsub(uschar **pb_ptr, const uschar **sptr_ptr)/* handle \\& variations */
|
||||
{ /* sptr[0] == '\\' */
|
||||
char *pb = *pb_ptr, *sptr = *sptr_ptr;
|
||||
uschar *pb = *pb_ptr;
|
||||
const uschar *sptr = *sptr_ptr;
|
||||
|
||||
if (sptr[1] == '\\') {
|
||||
if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */
|
||||
|
44
external/historical/nawk/dist/tran.c
vendored
44
external/historical/nawk/dist/tran.c
vendored
@ -22,6 +22,10 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
@ -29,7 +33,7 @@ THIS SOFTWARE.
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "awk.h"
|
||||
#include "ytab.h"
|
||||
#include "awkgram.h"
|
||||
|
||||
#define FULLTAB 2 /* rehash when table gets this x full */
|
||||
#define GROWTAB 4 /* grow table by this factor */
|
||||
@ -108,7 +112,7 @@ void arginit(int ac, char **av) /* set up ARGV and ARGC */
|
||||
ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */
|
||||
cp->sval = (char *) ARGVtab;
|
||||
for (i = 0; i < ac; i++) {
|
||||
sprintf(temp, "%d", i);
|
||||
snprintf(temp, sizeof(temp), "%d", i);
|
||||
if (is_number(*av))
|
||||
setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);
|
||||
else
|
||||
@ -144,8 +148,8 @@ Array *makesymtab(int n) /* make a new symbol table */
|
||||
Array *ap;
|
||||
Cell **tp;
|
||||
|
||||
ap = (Array *) malloc(sizeof(Array));
|
||||
tp = (Cell **) calloc(n, sizeof(Cell *));
|
||||
ap = malloc(sizeof(*ap));
|
||||
tp = calloc(n, sizeof(*tp));
|
||||
if (ap == NULL || tp == NULL)
|
||||
FATAL("out of space in makesymtab");
|
||||
ap->nelem = 0;
|
||||
@ -210,12 +214,15 @@ Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp)
|
||||
int h;
|
||||
Cell *p;
|
||||
|
||||
if (n != NULL && (p = lookup(n, tp)) != NULL) {
|
||||
if (n == NULL)
|
||||
n = "";
|
||||
|
||||
if ((p = lookup(n, tp)) != NULL) {
|
||||
dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
|
||||
p, NN(p->nval), NN(p->sval), p->fval, p->tval) );
|
||||
return(p);
|
||||
}
|
||||
p = (Cell *) malloc(sizeof(Cell));
|
||||
p = malloc(sizeof(*p));
|
||||
if (p == NULL)
|
||||
FATAL("out of space for symbol table at %s", n);
|
||||
p->nval = tostring(n);
|
||||
@ -250,7 +257,7 @@ void rehash(Array *tp) /* rehash items in small table into big one */
|
||||
Cell *cp, *op, **np;
|
||||
|
||||
nsz = GROWTAB * tp->size;
|
||||
np = (Cell **) calloc(nsz, sizeof(Cell *));
|
||||
np = calloc(nsz, sizeof(*np));
|
||||
if (np == NULL) /* can't do it, but can keep running. */
|
||||
return; /* someone else will run out later. */
|
||||
for (i = 0; i < tp->size; i++) {
|
||||
@ -282,6 +289,7 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
|
||||
{
|
||||
int fldno;
|
||||
|
||||
f += 0.0; /* normalise negative zero to positive zero */
|
||||
if ((vp->tval & (NUM | STR)) == 0)
|
||||
funnyvar(vp, "assign to");
|
||||
if (isfld(vp)) {
|
||||
@ -361,7 +369,7 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
|
||||
|
||||
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
|
||||
{
|
||||
char s[100]; /* BUG: unchecked */
|
||||
char s[100];
|
||||
double dtemp;
|
||||
|
||||
if ((vp->tval & (NUM | STR)) == 0)
|
||||
@ -374,9 +382,9 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
|
||||
if (freeable(vp))
|
||||
xfree(vp->sval);
|
||||
if (modf(vp->fval, &dtemp) == 0) /* it's integral */
|
||||
sprintf(s, "%.30g", vp->fval);
|
||||
snprintf(s, sizeof(s), "%.30g", vp->fval);
|
||||
else
|
||||
sprintf(s, *fmt, vp->fval);
|
||||
snprintf(s, sizeof(s), *fmt, vp->fval);
|
||||
vp->sval = tostring(s);
|
||||
vp->tval &= ~DONTFREE;
|
||||
vp->tval |= STR;
|
||||
@ -400,7 +408,17 @@ char *tostring(const char *s) /* make a copy of string s */
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = (char *) malloc(strlen(s)+1);
|
||||
p = strdup(s);
|
||||
if (p == NULL)
|
||||
FATAL("out of space in tostring on %s", s);
|
||||
return(p);
|
||||
}
|
||||
|
||||
char *tostringN(const char *s, size_t n) /* make a copy of string s */
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = malloc(n);
|
||||
if (p == NULL)
|
||||
FATAL("out of space in tostring on %s", s);
|
||||
strcpy(p, s);
|
||||
@ -411,10 +429,10 @@ char *qstring(const char *is, int delim) /* collect string up to next delim */
|
||||
{
|
||||
const char *os = is;
|
||||
int c, n;
|
||||
uschar *s = (uschar *) is;
|
||||
const uschar *s = (const uschar *) is;
|
||||
uschar *buf, *bp;
|
||||
|
||||
if ((buf = (uschar *) malloc(strlen(is)+3)) == NULL)
|
||||
if ((buf = malloc(strlen(is)+3)) == NULL)
|
||||
FATAL( "out of space in qstring(%s)", s);
|
||||
for (bp = buf; (c = *s) != delim; s++) {
|
||||
if (c == '\n')
|
||||
|
Loading…
Reference in New Issue
Block a user