Merge nawk version 20030729 changes, and resolve conflicts.
This commit is contained in:
parent
2b2ae88a13
commit
19de07894e
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue