Merge nawk version 20030729 changes, and resolve conflicts.

This commit is contained in:
jdolecek 2003-08-02 22:41:59 +00:00
parent 2b2ae88a13
commit 19de07894e
12 changed files with 304 additions and 166 deletions

49
dist/nawk/README vendored
View File

@ -38,27 +38,27 @@ which should produce a sequence of messages roughly like this:
yacc -d awkgram.y
conflicts: 43 shift/reduce, 85 reduce/reduce
mv y.tab.c awkgram.c
mv y.tab.h awkgram.h
cc -O -c awkgram.c
cc -O -c b.c
cc -O -c main.c
cc -O -c parse.c
cc -O maketab.c -o maketab
mv y.tab.c ytab.c
mv y.tab.h ytab.h
cc -c ytab.c
cc -c b.c
cc -c main.c
cc -c parse.c
cc maketab.c -o maketab
./maketab >proctab.c
cc -O -c proctab.c
cc -O -c tran.c
cc -O -c lib.c
cc -O -c run.c
cc -O -c lex.c
cc -O ytab.o b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o -lm
cc -c proctab.c
cc -c tran.c
cc -c lib.c
cc -c run.c
cc -c lex.c
cc ytab.o b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o -lm
This produces an executable a.out; you will eventually want to
move this to some place like /usr/bin/awk.
If your system is does not have yacc or bison (the GNU
equivalent), you must compile the pieces manually. We have
included yacc output in awkgram.c and awkgram.h, and backup copies in
included yacc output in ytab.c and ytab.h, and backup copies in
case you overwrite them. We have also included a copy of
proctab.c so you do not need to run maketab.
@ -68,16 +68,27 @@ compilers on a variety of systems, but new systems or compilers
may raise some new complaint; reports of difficulties are
welcome.
This also compiles with Visual C++ on Windows 95 and Windows NT,
This also compiles with Visual C++ on all flavors of Windows,
*if* you provide versions of popen and pclose. The file
missing95.c contains versions that can be used to get started
with, though the underlying support has mysterious properties,
the symptom of which can be truncated pipe output. Beware.
the symptom of which can be truncated pipe output. Beware. The
file makefile.win gives hints on how to proceed; if you run
vcvars32.bat, it will set up necessary paths and parameters so
you can subsequently run nmake -f makefile.win. Beware also that
when running on Windows under command.com, various quoting
conventions are different from Unix systems: single quotes won't
work around arguments, and various characters like % are
interpreted within double quotes.
This is also said to compile on Macintosh systems, using the
This compiles without change on Macintosh OS X using gcc and
the standard developer tools.
This is also said to compile on Macintosh OS 9 systems, using the
file "buildmac" provided by Dan Allen (danallen@microsoft.com),
to whom many thanks. Dan also provided buildwin.bat, a simple
script for compiling on NT if you prefer.
to whom many thanks.
The version of malloc that comes with some systems is sometimes
astonishly slow. If awk seems slow, you might try fixing that.
More generally, turning on optimization can significantly improve
awk's speed, perhaps by 1/3 for highest levels.

2
dist/nawk/awk.h vendored
View File

@ -30,6 +30,8 @@ typedef unsigned char uschar;
#define xfree(a) { if ((a) != NULL) { free((char *) a); a = NULL; } }
#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf
*/
#define DEBUG
#ifdef DEBUG
/* uses have to be doubly parenthesized */

100
dist/nawk/b.c vendored
View File

@ -33,7 +33,7 @@ THIS SOFTWARE.
#include "awk.h"
#include "awkgram.h"
#define HAT (NCHARS-2) /* matches ^ in regular expr */
#define HAT (NCHARS+2) /* matches ^ in regular expr */
/* NCHARS is 2**n */
#define MAXLIN 22
@ -75,7 +75,7 @@ int patlen;
fa *fatab[NFA];
int nfatab = 0; /* entries in fatab */
fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */
fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
{
int i, use, nuse;
fa *pfa;
@ -93,7 +93,7 @@ fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */
return mkdfa(s, anchor);
for (i = 0; i < nfatab; i++) /* is it there already? */
if (fatab[i]->anchor == anchor
&& strcmp(fatab[i]->restr, s) == 0) {
&& strcmp((const char *) fatab[i]->restr, s) == 0) {
fatab[i]->use = now++;
return fatab[i];
}
@ -117,7 +117,7 @@ fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */
return pfa;
}
fa *mkdfa(char *s, int anchor) /* does the real work of making a dfa */
fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */
/* anchor = 1 for anchored matches, else 0 */
{
Node *p, *p1;
@ -282,7 +282,7 @@ int quoted(char **pp) /* pick up next thing after a \\ */
return c;
}
char *cclenter(char *argp) /* add a character class */
char *cclenter(const char *argp) /* add a character class */
{
int i, c, c2;
uschar *p = (uschar *) argp;
@ -328,7 +328,7 @@ char *cclenter(char *argp) /* add a character class */
return (char *) tostring((char *) buf);
}
void overflo(char *s)
void overflo(const char *s)
{
FATAL("regular expression too big: %.30s...", s);
}
@ -446,7 +446,7 @@ void follow(Node *v) /* collects leaves that can follow v into setvec */
}
}
int member(int c, char *sarg) /* is c in s? */
int member(int c, const char *sarg) /* is c in s? */
{
uschar *s = (uschar *) sarg;
@ -456,7 +456,7 @@ int member(int c, char *sarg) /* is c in s? */
return(0);
}
int match(fa *f, char *p0) /* shortest match ? */
int match(fa *f, const char *p0) /* shortest match ? */
{
int s, ns;
uschar *p = (uschar *) p0;
@ -475,7 +475,7 @@ int match(fa *f, char *p0) /* shortest match ? */
return(0);
}
int pmatch(fa *f, char *p0) /* longest match, for sub */
int pmatch(fa *f, const char *p0) /* longest match, for sub */
{
int s, ns;
uschar *p = (uschar *) p0;
@ -528,7 +528,7 @@ int pmatch(fa *f, char *p0) /* longest match, for sub */
return (0);
}
int nematch(fa *f, char *p0) /* non-empty match, for sub */
int nematch(fa *f, const char *p0) /* non-empty match, for sub */
{
int s, ns;
uschar *p = (uschar *) p0;
@ -580,15 +580,17 @@ int nematch(fa *f, char *p0) /* non-empty match, for sub */
return (0);
}
Node *reparse(char *p) /* parses regular expression pointed to by p */
Node *reparse(const char *p) /* parses regular expression pointed to by p */
{ /* uses relex() to scan regular expression */
Node *np;
dprintf( ("reparse <%s>\n", p) );
lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */
rtok = relex();
/* GNU compatibility: an empty regexp matches anything */
if (rtok == '\0')
FATAL("empty regular expression");
/* FATAL("empty regular expression"); previous */
return(op2(ALL, NIL, NIL));
np = regexp();
if (rtok != '\0')
FATAL("syntax error in regular expression %s at %s", lastre, prestr);
@ -683,6 +685,56 @@ Node *unary(Node *np)
}
}
/*
* Character class definitions conformant to the POSIX locale as
* defined in IEEE P1003.1 draft 7 of June 2001, assuming the source
* and operating character sets are both ASCII (ISO646) or supersets
* thereof.
*
* Note that to avoid overflowing the temporary buffer used in
* relex(), the expanded character class (prior to range expansion)
* must be less than twice the size of their full name.
*/
/* Because isblank doesn't show up in any of the header files on any
* system i use, it's defined here. if some other locale has a richer
* definition of "blank", define HAS_ISBLANK and provide your own
* version.
* the parentheses here are an attempt to find a path through the maze
* of macro definition and/or function and/or version provided. thanks
* to nelson beebe for the suggestion; let's see if it works everywhere.
*/
#ifndef HAS_ISBLANK
int (isblank)(int c)
{
return c==' ' || c=='\t';
}
#endif
static const struct charclass {
const char *cc_name;
int cc_namelen;
int (*cc_func)(int);
} charclasses[] = {
{ "alnum", 5, isalnum },
{ "alpha", 5, isalpha },
{ "blank", 5, isblank },
{ "cntrl", 5, iscntrl },
{ "digit", 5, isdigit },
{ "graph", 5, isgraph },
{ "lower", 5, islower },
{ "print", 5, isprint },
{ "punct", 5, ispunct },
{ "space", 5, isspace },
{ "upper", 5, isupper },
{ "xdigit", 6, isxdigit },
{ NULL, 0, NULL },
};
int relex(void) /* lexical analyzer for reparse */
{
int c, n;
@ -690,6 +742,8 @@ int relex(void) /* lexical analyzer for reparse */
static uschar *buf = 0;
static int bufsz = 100;
uschar *bp;
const struct charclass *cc;
int i;
switch (c = *prestr++) {
case '|': return OR;
@ -719,7 +773,7 @@ int relex(void) /* lexical analyzer for reparse */
}
else
cflag = 0;
n = 2 * strlen(prestr)+1;
n = 2 * strlen((const char *) prestr)+1;
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0))
FATAL("out of space for reg expr %.10s...", lastre);
for (; ; ) {
@ -730,6 +784,24 @@ int relex(void) /* lexical analyzer for reparse */
*bp++ = c;
/* } else if (c == '\n') { */
/* FATAL("newline in character class %.20s...", lastre); */
} else if (c == '[' && *prestr == ':') {
/* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */
for (cc = charclasses; cc->cc_name; cc++)
if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0)
break;
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, 0))
FATAL("out of space for reg expr %.10s...", lastre);
if (cc->cc_func(i)) {
*bp++ = i;
n++;
}
}
} else
*bp++ = c;
} else if (c == '\0') {
FATAL("nonterminated character class %.20s", lastre);
} else if (bp == buf) { /* 1st char is special */
@ -752,8 +824,6 @@ int cgoto(fa *f, int s, int c)
int i, j, k;
int *p, *q;
if (c < 0 || c > 255)
FATAL("can't happen: neg char %d in cgoto", c);
while (f->accept >= maxsetvec) { /* guessing here! */
maxsetvec *= 4;
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));

28
dist/nawk/lex.c vendored
View File

@ -38,7 +38,7 @@ int brackcnt = 0;
int parencnt = 0;
typedef struct Keyword {
char *word;
const char *word;
int sub;
int type;
} Keyword;
@ -112,7 +112,7 @@ int peek(void)
int gettok(char **pbuf, int *psz) /* get next input token */
{
int c;
int c, retc;
char *buf = *pbuf;
int sz = *psz;
char *bp = buf;
@ -140,6 +140,7 @@ int gettok(char **pbuf, int *psz) /* get next input token */
}
}
*bp = 0;
retc = 'a'; /* alphanumeric */
} else { /* it's a number */
char *rem;
/* read input until can't be a number */
@ -158,11 +159,17 @@ int gettok(char **pbuf, int *psz) /* get next input token */
*bp = 0;
strtod(buf, &rem); /* parse the number */
unputstr(rem); /* put rest back for later */
rem[0] = 0;
if (rem == buf) { /* it wasn't a valid number at all */
buf[1] = 0; /* so return one character as token */
retc = buf[0]; /* character is its own type */
} else { /* some prefix was a number */
rem[0] = 0; /* so truncate where failure started */
retc = '0'; /* number */
}
}
*pbuf = buf;
*psz = sz;
return buf[0];
return retc;
}
int word(char *);
@ -193,7 +200,7 @@ int yylex(void)
return 0;
if (isalpha(c) || c == '_')
return word(buf);
if (isdigit(c) || c == '.') {
if (isdigit(c)) {
yylval.cp = setsymtab(buf, tostring(buf), atof(buf), CON|NUM, symtab);
/* should this also have STR set? */
RET(NUMBER);
@ -318,6 +325,9 @@ int yylex(void)
}
yylval.cp = setsymtab(buf, "", 0.0, STR|NUM, symtab);
RET(IVAR);
} else if (c == 0) { /* */
SYNTAX( "unexpected end of input after $" );
RET(';');
} else {
unputstr(buf);
RET(INDIRECT);
@ -373,6 +383,8 @@ int string(void)
case 0:
SYNTAX( "non-terminated string %.10s...", buf );
lineno++;
if (c == 0) /* hopeless */
FATAL( "giving up" );
break;
case '\\':
c = input();
@ -494,7 +506,7 @@ int word(char *w)
}
}
void startreg(void) /* next call to yyles will return a regular expression */
void startreg(void) /* next call to yylex will return a regular expression */
{
reg = 1;
}
@ -524,6 +536,8 @@ int regexpr(void)
}
}
*bp = 0;
if (c == 0)
SYNTAX("non-terminated regular expression %.10s...", buf);
yylval.s = tostring(buf);
unput('/');
RET(REGEXPR);
@ -569,7 +583,7 @@ void unput(int c) /* put lexical character back on input */
ep = ebuf + sizeof(ebuf) - 1;
}
void unputstr(char *s) /* put a string back on input */
void unputstr(const char *s) /* put a string back on input */
{
int i;

27
dist/nawk/lib.c vendored
View File

@ -308,6 +308,13 @@ void fldbld(void) /* create fields from current record */
}
*fr = 0;
} else if (*r != 0) { /* if 0, it's a null field */
/* subtlecase : if length(FS) == 1 && length(RS > 0)
* \n is NOT a field separator (cf awk book 61,84).
* this variable is tested in the inner while loop.
*/
int rtest = '\n'; /* normal case */
if (strlen(*RS) > 0)
rtest = '\0';
for (;;) {
i++;
if (i > nfields)
@ -316,7 +323,7 @@ void fldbld(void) /* create fields from current record */
xfree(fldtab[i]->sval);
fldtab[i]->sval = fr;
fldtab[i]->tval = FLD | STR | DONTFREE;
while (*r != sep && *r != '\n' && *r != '\0') /* \n is always a separator */
while (*r != sep && *r != rtest && *r != '\0') /* \n is always a separator */
*fr++ = *r++;
*fr++ = 0;
if (*r++ == 0)
@ -390,7 +397,7 @@ void growfldtab(int n) /* make new fields up to at least $n */
nfields = nf;
}
int refldbld(char *rec, char *fs) /* build fields from reg expr in FS */
int refldbld(const char *rec, const char *fs) /* build fields from reg expr in FS */
{
/* this relies on having fields[] the same length as $0 */
/* the fields are all stored in this one array with \0's */
@ -475,12 +482,12 @@ void recbld(void) /* create $0 from $1..$NF if necessary */
int errorflag = 0;
void yyerror(char *s)
void yyerror(const char *s)
{
SYNTAX(s);
}
void SYNTAX(char *fmt, ...)
void SYNTAX(const char *fmt, ...)
{
extern char *cmdname, *curfname;
static int been_here = 0;
@ -535,7 +542,7 @@ void bcheck2(int n, int c1, int c2)
fprintf(stderr, "\t%d extra %c's\n", -n, c2);
}
void FATAL(char *fmt, ...)
void FATAL(const char *fmt, ...)
{
extern char *cmdname;
va_list varg;
@ -551,7 +558,7 @@ void FATAL(char *fmt, ...)
exit(2);
}
void WARNING(char *fmt, ...)
void WARNING(const char *fmt, ...)
{
extern char *cmdname;
va_list varg;
@ -633,7 +640,7 @@ void bclass(int c)
}
}
double errcheck(double x, char *s)
double errcheck(double x, const char *s)
{
if (errno == EDOM) {
@ -648,9 +655,9 @@ double errcheck(double x, char *s)
return x;
}
int isclvar(char *s) /* is s of form var=something ? */
int isclvar(const char *s) /* is s of form var=something ? */
{
char *os = s;
const char *os = s;
if (!isalpha((uschar) *s) && *s != '_')
return 0;
@ -665,7 +672,7 @@ int isclvar(char *s) /* is s of form var=something ? */
/* wrong: violates 4.10.1.4 of ansi C standard */
#include <math.h>
int is_number(char *s)
int is_number(const char *s)
{
double r;
char *ep;

24
dist/nawk/main.c vendored
View File

@ -22,11 +22,12 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
char *version = "version 20001115";
const char * const version = "version 20030729";
#define DEBUG
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
@ -53,9 +54,10 @@ int safe = 0; /* 1 => "safe" mode */
int main(int argc, char *argv[])
{
char *fs = NULL, *marg;
int temp;
const char *fs = NULL;
setlocale(LC_CTYPE, "");
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
cmdname = argv[0];
if (argc == 1) {
fprintf(stderr, "Usage: %s [-f programfile | 'program'] [-Ffieldsep] [-v var=value] [files]\n", cmdname);
@ -106,19 +108,8 @@ int main(int argc, char *argv[])
setclvar(argv[1]);
break;
case 'm': /* more memory: -mr=record, -mf=fields */
/* no longer needed */
marg = argv[1];
if (argv[1][3])
temp = atoi(&argv[1][3]);
else {
argv++; argc--;
temp = atoi(&argv[1][0]);
}
switch (marg[2]) {
case 'r': recsize = temp; break;
case 'f': nfields = temp; break;
default: FATAL("unknown option %s\n", marg);
}
/* no longer supported */
WARNING("obsolete option %s ignored", argv[1]);
break;
case 'd':
dbg = atoi(&argv[1][2]);
@ -158,6 +149,7 @@ int main(int argc, char *argv[])
if (!safe)
envinit(environ);
yyparse();
setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
if (fs)
*FS = qstring(fs, '\0');
dprintf( ("errorflag=%d\n", errorflag) );

37
dist/nawk/makefile vendored
View File

@ -26,7 +26,9 @@ CFLAGS = -g
CFLAGS = -O2
CFLAGS =
CC = gcc -Wall -g -Wwrite-strings
CC = gcc -Wall -g
CC = /opt/SUNWspro/bin/cc
CC = /opt/pure/purify/purify cc
CC = cc
@ -36,37 +38,40 @@ YFLAGS = -d
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o
SOURCE = awk.h awkgram.c awkgram.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c
SOURCE = awk.h ytab.c ytab.h proto.h awkgram.y lex.c b.c main.c \
maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c
LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c lib.c run.c tran.c missing95.c
LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c \
lib.c run.c tran.c missing95.c
SHIP = README FIXES $(SOURCE) awkgram[ch].bak makefile awk.1 buildwin.bat mac.code
SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win \
vcvars32.bat buildwin.bat mac.code awk.1
a.out: awkgram.o $(OFILES)
$(CC) $(CFLAGS) awkgram.o $(OFILES) $(ALLOC) -lm
a.out: ytab.o $(OFILES)
$(CC) $(CFLAGS) ytab.o $(OFILES) $(ALLOC) -lm
$(OFILES): awk.h awkgram.h proto.h
$(OFILES): awk.h ytab.h proto.h
awkgram.o: awk.h proto.h awkgram.y
ytab.o: awk.h proto.h awkgram.y
$(YACC) $(YFLAGS) awkgram.y
mv y.tab.c awkgram.c
mv y.tab.h awkgram.h
$(CC) $(CFLAGS) -c awkgram.c
mv y.tab.c ytab.c
mv y.tab.h ytab.h
$(CC) $(CFLAGS) -c ytab.c
proctab.c: maketab
./maketab >proctab.c
maketab: awkgram.h maketab.c
maketab: ytab.h maketab.c
$(CC) $(CFLAGS) maketab.c -o maketab
bundle:
@cp awkgram.h awkgramh.bak
@cp awkgram.c awkgramc.bak
@cp ytab.h ytabh.bak
@cp ytab.c ytabc.bak
@bundle $(SHIP)
tar:
@cp awkgram.h awkgramh.bak
@cp awkgram.c awkgramc.bak
@cp ytab.h ytabh.bak
@cp ytab.c ytabc.bak
@bundle $(SHIP) >awk.shar
@tar cf awk.tar $(SHIP)
gzip awk.tar
@ -78,4 +83,4 @@ names:
@echo $(LISTING)
clean:
rm -f a.out *.o maketab # proctab.c
rm -f a.out *.o *.obj maketab maketab.exe # proctab.c

8
dist/nawk/maketab.c vendored
View File

@ -36,8 +36,8 @@ THIS SOFTWARE.
struct xx
{ int token;
char *name;
char *pname;
const char *name;
const char *pname;
} proc[] = {
{ PROGRAM, "program", NULL },
{ BOR, "boolop", " || " },
@ -108,12 +108,12 @@ struct xx
};
#define SIZE (LASTTOKEN - FIRSTTOKEN + 1)
char *table[SIZE];
const char *table[SIZE];
char *names[SIZE];
int main(int argc, char *argv[])
{
struct xx *p;
const struct xx *p;
int i, n, tok;
char c;
FILE *fp;

2
dist/nawk/parse.c vendored
View File

@ -276,7 +276,7 @@ void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
dprintf( ("defining func %s (%d args)\n", v->nval, n) );
}
int isarg(char *s) /* is s in argument list for current function? */
int isarg(const char *s) /* is s in argument list for current function? */
{ /* return -1 if not, otherwise arg # */
extern Node *arglist;
Node *p = arglist;

61
dist/nawk/proto.h vendored
View File

@ -33,28 +33,28 @@ extern int yylex(void);
extern void startreg(void);
extern int input(void);
extern void unput(int);
extern void unputstr(char *);
extern void unputstr(const char *);
extern int yylook(void);
extern int yyback(int *, int);
extern int yyinput(void);
extern fa *makedfa(char *, int);
extern fa *mkdfa(char *, int);
extern fa *makedfa(const char *, int);
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 char *cclenter(char *);
extern void overflo(char *);
extern char *cclenter(const char *);
extern void overflo(const char *);
extern void cfoll(fa *, Node *);
extern int first(Node *);
extern void follow(Node *);
extern int member(int, char *);
extern int match(fa *, char *);
extern int pmatch(fa *, char *);
extern int nematch(fa *, char *);
extern Node *reparse(char *);
extern int member(int, const char *);
extern int match(fa *, const char *);
extern int pmatch(fa *, const char *);
extern int nematch(fa *, const char *);
extern Node *reparse(const char *);
extern Node *regexp(void);
extern Node *primary(void);
extern Node *concat(Node *);
@ -89,7 +89,7 @@ extern Node *makearr(Node *);
extern Node *pa2stat(Node *, Node *, Node *);
extern Node *linkum(Node *, Node *);
extern void defn(Cell *, Node *, Node *);
extern int isarg(char *);
extern int isarg(const char *);
extern const char *tokname(int);
extern Cell *(*proctab[])(Node **, int);
extern int ptoi(void *);
@ -100,18 +100,19 @@ extern void arginit(int, char **);
extern void envinit(char **);
extern Array *makesymtab(int);
extern void freesymtab(Cell *);
extern void freeelem(Cell *, char *);
extern Cell *setsymtab(char *, char *, double, unsigned int, Array *);
extern int hash(char *, int);
extern void freeelem(Cell *, const char *);
extern Cell *setsymtab(const char *, const char *, double, unsigned int, Array *);
extern int hash(const char *, int);
extern void rehash(Array *);
extern Cell *lookup(char *, Array *);
extern Cell *lookup(const char *, Array *);
extern double setfval(Cell *, double);
extern void funnyvar(Cell *, char *);
extern char *setsval(Cell *, char *);
extern void funnyvar(Cell *, const char *);
extern char *setsval(Cell *, const char *);
extern double getfval(Cell *);
extern char *getsval(Cell *);
extern char *tostring(char *);
extern char *qstring(char *, int);
extern char *getpssval(Cell *); /* for print */
extern char *tostring(const char *);
extern char *qstring(const char *, int);
extern void recinit(unsigned int);
extern void initgetrec(void);
@ -125,24 +126,24 @@ extern void setclvar(char *);
extern void fldbld(void);
extern void cleanfld(int, int);
extern void newfld(int);
extern int refldbld(char *, char *);
extern int refldbld(const char *, const char *);
extern void recbld(void);
extern Cell *fieldadr(int);
extern void yyerror(char *);
extern void yyerror(const char *);
extern void fpecatch(int);
extern void bracecheck(void);
extern void bcheck2(int, int, int);
extern void SYNTAX(char *, ...);
extern void FATAL(char *, ...);
extern void WARNING(char *, ...);
extern void SYNTAX(const char *, ...);
extern void FATAL(const char *, ...);
extern void WARNING(const char *, ...);
extern void error(void);
extern void eprint(void);
extern void bclass(int);
extern double errcheck(double, char *);
extern int isclvar(char *);
extern int is_number(char *);
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, char *what);
extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what);
extern void run(Node *);
extern Cell *execute(Node *);
extern Cell *program(Node **, int);
@ -164,7 +165,7 @@ extern Cell *field(Node **, int);
extern Cell *indirect(Node **, int);
extern Cell *substr(Node **, int);
extern Cell *sindex(Node **, int);
extern int format(char **, int *, char *, Node *);
extern int format(char **, int *, const char *, Node *);
extern Cell *awksprintf(Node **, int);
extern Cell *awkprintf(Node **, int);
extern Cell *arith(Node **, int);
@ -185,7 +186,7 @@ extern Cell *bltin(Node **, int);
extern Cell *printstat(Node **, int);
extern Cell *nullproc(Node **, int);
extern FILE *redirect(int, Node *);
extern FILE *openfile(int, char *);
extern FILE *openfile(int, const char *);
extern const char *filename(FILE *);
extern Cell *closefile(Node **, int);
extern void closeall(void);

81
dist/nawk/run.c vendored
View File

@ -92,7 +92,7 @@ Node *curnode = NULL; /* the node being executed, for debugging */
/* buffer memory management */
int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
char *whatrtn)
const char *whatrtn)
/* pbuf: address of pointer to buffer being managed
* psiz: address of buffer size variable
* minlen: minimum length of buffer needed
@ -247,7 +247,7 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
y = execute(x);
oargs[i] = y;
dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
i, y->nval, y->fval, isarr(y) ? "(array)" : y->sval, y->tval) );
i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) );
if (isfcn(y))
FATAL("can't use function %s as argument in %s", y->nval, s);
if (isarr(y))
@ -463,7 +463,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
tempfree(y);
}
if (!isarr(x)) {
dprintf( ("making %s into an array\n", x->nval) );
dprintf( ("making %s into an array\n", NN(x->nval)) );
if (freeable(x))
xfree(x->sval);
x->tval &= ~(STR|NUM|DONTFREE);
@ -564,7 +564,7 @@ Cell *matchop(Node **a, int n) /* ~ and match() */
char *s, *t;
int i;
fa *pfa;
int (*mf)(fa *, char *) = match, mode = 0;
int (*mf)(fa *, const char *) = match, mode = 0;
if (n == MATCHFCN) {
mf = pmatch;
@ -669,7 +669,7 @@ Cell *relop(Node **a, int n) /* a[0 < a[1], etc. */
void tfree(Cell *a) /* free a tempcell */
{
if (freeable(a)) {
dprintf( ("freeing %s %s %o\n", a->nval, a->sval, a->tval) );
dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) );
xfree(a->sval);
}
if (a == tmps)
@ -790,10 +790,11 @@ Cell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */
#define MAXNUMSIZE 50
int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversions */
int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */
{
char *fmt;
char *p, *t, *os;
char *p, *t;
const char *os;
Cell *x;
int flag = 0, n;
int fmtwd; /* format width */
@ -844,27 +845,27 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
switch (*s) {
case 'f': case 'e': case 'g': case 'E': case 'G':
flag = 1;
flag = 'f';
break;
case 'd': case 'i':
flag = 2;
flag = 'd';
if(*(s-1) == 'l') break;
*(t-1) = 'l';
*t = 'd';
*++t = '\0';
break;
case 'o': case 'x': case 'X': case 'u':
flag = *(s-1) == 'l' ? 2 : 3;
flag = *(s-1) == 'l' ? 'd' : 'u';
break;
case 's':
flag = 4;
flag = 's';
break;
case 'c':
flag = 5;
flag = 'c';
break;
default:
WARNING("weird printf conversion %s", fmt);
flag = 0;
flag = '?';
break;
}
if (a == NULL)
@ -876,7 +877,7 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
n = fmtwd;
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format");
switch (flag) {
case 0: sprintf(p, "%s", fmt); /* unknown, so dump it too */
case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */
t = getsval(x);
n = strlen(t);
if (fmtwd > n)
@ -885,10 +886,10 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
p += strlen(p);
sprintf(p, "%s", t);
break;
case 1: sprintf(p, fmt, getfval(x)); break;
case 2: sprintf(p, fmt, (long) getfval(x)); break;
case 3: sprintf(p, fmt, (int) getfval(x)); break;
case 4:
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 's':
t = getsval(x);
n = strlen(t);
if (fmtwd > n)
@ -897,17 +898,19 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);
sprintf(p, fmt, t);
break;
case 5:
case 'c':
if (isnum(x)) {
if (getfval(x))
sprintf(p, fmt, (int) getfval(x));
else {
*p = '\0';
*++p = '\0';
*p++ = '\0'; /* explicit null byte */
*p = '\0'; /* next output will start here */
}
} else
sprintf(p, fmt, getsval(x)[0]);
break;
default:
FATAL("can't happen: bad conversion %c in format()", flag);
}
tempfree(x);
p += strlen(p);
@ -1212,13 +1215,13 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
sep = *fs;
ap = execute(a[1]); /* array name */
freesymtab(ap);
dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) );
dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) );
ap->tval &= ~STR;
ap->tval |= ARR;
ap->sval = (char *) makesymtab(NSYMTAB);
n = 0;
if ((*s != '\0' && strlen(fs) > 1) || arg3type == REGEXPR) { /* reg expr */
if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */
fa *pfa;
if (arg3type == REGEXPR) { /* it's ready already */
pfa = (fa *) a[2];
@ -1442,6 +1445,8 @@ Cell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */
return True;
}
void flush_all(void);
Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */
{
Cell *x, *y;
@ -1458,7 +1463,11 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
nextarg = a[1]->nnext;
switch (t) {
case FLENGTH:
u = strlen(getsval(x)); break;
if (isarr(x))
u = ((Array *) x->sval)->nelem; /* GROT. should be function*/
else
u = strlen(getsval(x));
break;
case FLOG:
u = errcheck(log(getfval(x)), "log"); break;
case FINT:
@ -1503,11 +1512,11 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
if (t == FTOUPPER) {
for (p = buf; *p; p++)
if (islower((uschar) *p))
*p = toupper((uschar) *p);
*p = toupper((uschar)*p);
} else {
for (p = buf; *p; p++)
if (isupper((uschar) *p))
*p = tolower((uschar) *p);
*p = tolower((uschar)*p);
}
tempfree(x);
x = gettemp();
@ -1515,7 +1524,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
free(buf);
return x;
case FFLUSH:
if ((fp = openfile(FFLUSH, getsval(x))) == NULL)
if (isrec(x) || strlen(getsval(x)) == 0) {
flush_all(); /* fflush() or fflush("") -> all */
u = 0;
} else if ((fp = openfile(FFLUSH, getsval(x))) == NULL)
u = EOF;
else
u = fflush(fp);
@ -1576,7 +1588,7 @@ Cell *printstat(Node **a, int n) /* print a[0] */
fp = redirect(ptoi(a[1]), a[2]);
for (x = a[0]; x != NULL; x = x->nnext) {
y = execute(x);
fputs(getsval(y), fp);
fputs(getpssval(y), fp);
tempfree(y);
if (x->nnext == NULL)
fputs(*ORS, fp);
@ -1630,9 +1642,9 @@ void stdinit(void) /* in case stdin, etc., are not constants */
files[2].fp = stderr;
}
FILE *openfile(int a, char *us)
FILE *openfile(int a, const char *us)
{
char *s = us;
const char *s = us;
int i, m;
FILE *fp = 0;
@ -1735,6 +1747,15 @@ void closeall(void)
}
}
void flush_all(void)
{
int i;
for (i = 0; i < FOPEN_MAX; i++)
if (files[i].fp)
fflush(files[i].fp);
}
void backsub(char **pb_ptr, char **sptr_ptr);
Cell *sub(Node **a, int nnn) /* substitute command */

51
dist/nawk/tran.c vendored
View File

@ -170,14 +170,17 @@ void freesymtab(Cell *ap) /* free a symbol table */
xfree(cp->sval);
temp = cp->cnext; /* avoids freeing then using */
free(cp);
tp->nelem--;
}
tp->tab[i] = 0;
}
if (tp->nelem != 0)
WARNING("can't happen: inconsistent element count freeing %s", ap->nval);
free(tp->tab);
free(tp);
}
void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */
void freeelem(Cell *ap, const char *s) /* free elem s from ap (i.e., ap["s"] */
{
Array *tp;
Cell *p, *prev = NULL;
@ -200,14 +203,14 @@ void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */
}
}
Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp)
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) {
dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
p, p->nval, p->sval, p->fval, p->tval) );
p, NN(p->nval), NN(p->sval), p->fval, p->tval) );
return(p);
}
p = (Cell *) malloc(sizeof(Cell));
@ -230,7 +233,7 @@ Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp)
return(p);
}
int hash(char *s, int n) /* form hash value for string s */
int hash(const char *s, int n) /* form hash value for string s */
{
unsigned hashval;
@ -261,7 +264,7 @@ void rehash(Array *tp) /* rehash items in small table into big one */
tp->size = nsz;
}
Cell *lookup(char *s, Array *tp) /* look for s in tp */
Cell *lookup(const char *s, Array *tp) /* look for s in tp */
{
Cell *p;
int h;
@ -293,11 +296,11 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
xfree(vp->sval); /* free any previous string */
vp->tval &= ~STR; /* mark string invalid */
vp->tval |= NUM; /* mark number ok */
dprintf( ("setfval %p: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval) );
dprintf( ("setfval %p: %s = %g, t=%o\n", vp, NN(vp->nval), f, vp->tval) );
return vp->fval = f;
}
void funnyvar(Cell *vp, char *rw)
void funnyvar(Cell *vp, const char *rw)
{
if (isarr(vp))
FATAL("can't %s %s; it's an array name.", rw, vp->nval);
@ -307,12 +310,12 @@ void funnyvar(Cell *vp, char *rw)
vp, vp->nval, vp->sval, vp->fval, vp->tval);
}
char *setsval(Cell *vp, char *s) /* set string val of a Cell */
char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
{
char *t;
int fldno;
dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) );
dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, NN(vp->nval), s, vp->tval) );
if ((vp->tval & (NUM | STR)) == 0)
funnyvar(vp, "assign to");
if (isfld(vp)) {
@ -331,7 +334,7 @@ char *setsval(Cell *vp, char *s) /* set string val of a Cell */
if (freeable(vp))
xfree(vp->sval);
vp->tval &= ~DONTFREE;
dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) );
dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, NN(vp->nval), t,t, vp->tval) );
return(vp->sval = t);
}
@ -348,11 +351,12 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
if (is_number(vp->sval) && !(vp->tval&CON))
vp->tval |= NUM; /* make NUM only sparingly */
}
dprintf( ("getfval %p: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) );
dprintf( ("getfval %p: %s = %g, t=%o\n", vp, NN(vp->nval), vp->fval, vp->tval) );
return(vp->fval);
}
char *getsval(Cell *vp) /* get string val of a Cell */
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
{
char s[100]; /* BUG: unchecked */
double dtemp;
@ -369,16 +373,27 @@ char *getsval(Cell *vp) /* get string val of a Cell */
if (modf(vp->fval, &dtemp) == 0) /* it's integral */
sprintf(s, "%.30g", vp->fval);
else
sprintf(s, *CONVFMT, vp->fval);
sprintf(s, *fmt, vp->fval);
vp->sval = tostring(s);
vp->tval &= ~DONTFREE;
vp->tval |= STR;
}
dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) );
dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, NN(vp->nval), vp->sval, vp->sval, vp->tval) );
return(vp->sval);
}
char *tostring(char *s) /* make a copy of string s */
char *getsval(Cell *vp) /* get string val of a Cell */
{
return get_str_val(vp, CONVFMT);
}
char *getpssval(Cell *vp) /* get string val of a Cell for print */
{
return get_str_val(vp, OFMT);
}
char *tostring(const char *s) /* make a copy of string s */
{
char *p;
@ -389,14 +404,14 @@ char *tostring(char *s) /* make a copy of string s */
return(p);
}
char *qstring(char *is, int delim) /* collect string up to next delim */
char *qstring(const char *is, int delim) /* collect string up to next delim */
{
char *os = is;
const char *os = is;
int c, n;
uschar *s = (uschar *) is;
uschar *buf, *bp;
if ((buf = (uschar *) malloc(strlen(s)+3)) == NULL)
if ((buf = (uschar *) malloc(strlen(is)+3)) == NULL)
FATAL( "out of space in qstring(%s)", s);
for (bp = buf; (c = *s) != delim; s++) {
if (c == '\n')