ref: 6d0ade9e0f10517872304e94c2c5d0e3a14c426d
parent: a288969bf6c2d73cb8e77ece798a6009ffb57d99
author: qwx <qwx@sciops.net>
date: Thu Sep 25 16:50:39 EDT 2025
allow a string value to be unset, use common constant sval should never be nil.
--- a/awk.h
+++ b/awk.h
@@ -42,6 +42,8 @@
extern int donerec; /* 1 if record is valid (no fld has changed */
extern char inputFS[]; /* FS at time of input, for field splitting */
+extern char EMPTY[];
+
extern int dbg;
extern char *patbeg; /* beginning of pattern matched */
--- a/lex.c
+++ b/lex.c
@@ -285,7 +285,7 @@
unputstr("(NF)");RET(INDIRECT);
}
- yylval.cp = setsymtab(buf, "", 0.0, STR|NUM, symtab);
+ yylval.cp = setsymtab(buf, EMPTY, 0.0, STR|NUM, symtab);
RET(IVAR);
} else {unputstr(buf);
@@ -446,7 +446,7 @@
SYNTAX( "return not in function" );
RET(kp->type);
case VARNF:
- yylval.cp = setsymtab("NF", "", 0.0, NUM, symtab);+ yylval.cp = setsymtab("NF", EMPTY, 0.0, NUM, symtab);RET(VARNF);
default:
RET(kp->type);
@@ -457,7 +457,7 @@
yylval.i = n;
RET(ARG);
} else {- yylval.cp = setsymtab(w, "", 0.0, STR|NUM|DONTFREE, symtab);
+ yylval.cp = setsymtab(w, EMPTY, 0.0, STR|NUM|DONTFREE, symtab);
if (c == '(') {RET(CALL);
} else {--- a/lib.c
+++ b/lib.c
@@ -6,7 +6,7 @@
#include "y.tab.h"
Biobuf *infile;
-char *file = "";
+char *file = EMPTY;
char *record;
int recsize = RECSIZE;
char *fields;
@@ -25,8 +25,8 @@
int argno = 1; /* current input argument number */
extern Awkfloat *AARGC;
-static Cell dollar0 = { OCELL, CFLD, nil, "", 0.0, REC|STR|DONTFREE };-static Cell dollar1 = { OCELL, CFLD, nil, "", 0.0, FLD|STR|DONTFREE };+static Cell dollar0 = { OCELL, CFLD, nil, EMPTY, 0.0, REC|STR|DONTFREE };+static Cell dollar1 = { OCELL, CFLD, nil, EMPTY, 0.0, FLD|STR|DONTFREE };void recinit(unsigned int n)
{@@ -194,7 +194,7 @@
extern Array *ARGVtab;
sprint(temp, "%d", n);
- x = setsymtab(temp, "", 0.0, STR, ARGVtab);
+ x = setsymtab(temp, EMPTY, 0.0, STR, ARGVtab);
s = getsval(x);
dprint( ("getargv(%d) returns |%s|\n", n, s) );return s;
@@ -322,7 +322,7 @@
p = fldtab[i];
if (freeable(p))
xfree(p->sval);
- p->sval = "";
+ p->sval = EMPTY;
p->tval = FLD | STR | DONTFREE;
}
}
--- a/parse.c
+++ b/parse.c
@@ -166,7 +166,8 @@
if (isfcn(cp))
SYNTAX( "%s is a function, not an array", cp->nval );
else if (!isarr(cp)) {- xfree(cp->sval);
+ if (freeable(cp))
+ xfree(cp->sval);
cp->sval = (char *) makesymtab(NSYMTAB);
cp->tval = ARR;
}
--- a/run.c
+++ b/run.c
@@ -28,7 +28,7 @@
Cell *jexit = &exitcell;
static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM };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 };Node *curnode = nil; /* the node being executed, for debugging */
@@ -200,7 +200,7 @@
Cell *call(Node **a, int) /* function call. very kludgy and fragile */
{- static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE };+ static Cell newcopycell = { OCELL, CCOPY, 0, EMPTY, 0.0, NUM|STR|DONTFREE };int i, ncall, ndef;
Node *x;
Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */
@@ -304,10 +304,11 @@
y = gettemp();
y->csub = CCOPY; /* prevents freeing until call is over */
y->nval = x->nval; /* BUG? */
- y->sval = x->sval ? tostring(x->sval) : nil;
+ y->sval = x->sval != nil && x->sval != EMPTY ? tostring(x->sval) : EMPTY;
y->fval = x->fval;
y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); /* copy is not constant or field */
- /* is DONTFREE right? */
+ if (y->sval == EMPTY)
+ y->tval |= DONTFREE;
return y;
}
@@ -466,7 +467,7 @@
x->tval |= ARR;
x->sval = (char *) makesymtab(NSYMTAB);
}
- z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval);
+ z = setsymtab(buf, EMPTY, 0.0, STR|NUM, (Array *) x->sval);
z->ctype = OCELL;
z->csub = CVAR;
if (istemp(x))
@@ -747,7 +748,7 @@
tfree(z);
}
x = gettemp();
- setsval(x, "");
+ setsval(x, EMPTY);
return(x);
}
m = (int) getfval(y);
@@ -1289,7 +1290,7 @@
if (t[-1] == 0 || *t == 0) {n++;
sprint(num, "%d", n);
- setsymtab(num, "", 0.0, STR, (Array *) ap->sval);
+ setsymtab(num, EMPTY, 0.0, STR, (Array *) ap->sval);
goto spdone;
}
} while (nematch(p,s,t));
--- a/tran.c
+++ b/tran.c
@@ -8,6 +8,8 @@
#define FULLTAB 2 /* rehash when table gets this x full */
#define GROWTAB 4 /* grow table by this factor */
+char EMPTY[] = {'\0'};+
Array *symtab; /* main symbol table */
char **FS; /* initial field sep */
@@ -44,7 +46,7 @@
{ literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);/* this is used for if(x)... tests: */
- nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab);+ nullloc = setsymtab("$zero&null", EMPTY, 0.0, NUM|STR|CON|DONTFREE, symtab);nullnode = celltonode(nullloc, CCON);
FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval;@@ -53,19 +55,19 @@
ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval; OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval; CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;- FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval;- nfloc = setsymtab("NF", "", 0.0, NUM, symtab);+ FILENAME = &setsymtab("FILENAME", EMPTY, 0.0, STR|DONTFREE, symtab)->sval;+ nfloc = setsymtab("NF", EMPTY, 0.0, NUM, symtab);NF = &nfloc->fval;
- nrloc = setsymtab("NR", "", 0.0, NUM, symtab);+ nrloc = setsymtab("NR", EMPTY, 0.0, NUM, symtab);NR = &nrloc->fval;
- fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);+ fnrloc = setsymtab("FNR", EMPTY, 0.0, NUM, symtab);FNR = &fnrloc->fval;
SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval;- rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab);+ rstartloc = setsymtab("RSTART", EMPTY, 0.0, NUM, symtab);RSTART = &rstartloc->fval;
- rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);+ rlengthloc = setsymtab("RLENGTH", EMPTY, 0.0, NUM, symtab);RLENGTH = &rlengthloc->fval;
- symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab);+ symtabloc = setsymtab("SYMTAB", EMPTY, 0.0, ARR, symtab);symtabloc->sval = (char *) symtab;
}
@@ -76,8 +78,8 @@
char temp[50];
Awkfloat f;
- AARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;- cp = setsymtab("ARGV", "", 0.0, ARR, symtab);+ AARGC = &setsymtab("ARGC", EMPTY, (Awkfloat) ac, NUM, symtab)->fval;+ cp = setsymtab("ARGV", EMPTY, 0.0, ARR, symtab);ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */
cp->sval = (char *) ARGVtab;
for (i = 0; i < ac; i++) {@@ -205,8 +207,10 @@
p->sval = (char *) ENVtab;
p->tval = ARR;
} else {- p->sval = s ? tostring(s) : tostring("");+ p->sval = s != nil && s != EMPTY ? tostring(s) : EMPTY;
p->tval = t;
+ if (p->sval == EMPTY)
+ p->tval |= DONTFREE;
}
p->csub = CUNK;
p->ctype = OCELL;
@@ -316,12 +320,15 @@
donefld = 0; /* mark $1... invalid */
donerec = 1;
}
- t = tostring(s); /* in case it's self-assign */
+ t = s != nil && s != EMPTY ? tostring(s) : EMPTY; /* in case it's self-assign */
vp->tval &= ~NUM;
vp->tval |= STR;
if (freeable(vp))
xfree(vp->sval);
- vp->tval &= ~DONTFREE;
+ if (t != EMPTY)
+ vp->tval &= ~DONTFREE;
+ else
+ vp->tval |= DONTFREE;
dprint( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) );return(vp->sval = t);
}
--
⑨