ref: 1ffa8bd8f32394b7c972bf6d15d27007d22cf33c
parent: 681f270acd130d2c0d6aa78e1caf9dc3a1fcc3fb
author: qwx <qwx@sciops.net>
date: Sun Oct 26 18:26:04 EDT 2025
fix OFMT not doing anything and update strings if OFMT/CONVFMT changed based on work by Kenneth Stailey and onetrueawk.
--- a/awk.h
+++ b/awk.h
@@ -55,6 +55,7 @@
uchar ctype; /* OCELL, OBOOL, OJUMP, etc. */
uchar csub; /* CCON, CTEMP, CFLD, etc. */
short tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */
+ int conv; /* "pointer" to last used conv */
char *nval; /* name, for variables only */
char *sval; /* string value */
Awkfloat fval; /* value as number */
@@ -85,7 +86,7 @@
#define FCN 040 /* this is a function name */
#define FLD 0100 /* this is a field $1, $2, ... */
#define REC 0200 /* this is $0 */
-
+#define FMT 0400 /* OFMT used instead of CONVFMT */
/* function types */
#define FLENGTH 1
--- a/lib.c
+++ b/lib.c
@@ -25,8 +25,8 @@
int argno = 1; /* current input argument number */
extern Awkfloat *AARGC;
-static Cell dollar0 = { OCELL, CFLD, REC|STR|DONTFREE, nil, EMPTY, 0.0 };-static Cell dollar1 = { OCELL, CFLD, FLD|STR|DONTFREE, nil, EMPTY, 0.0 };+static Cell dollar0 = { OCELL, CFLD, REC|STR|DONTFREE, 0, nil, EMPTY, 0.0 };+static Cell dollar1 = { OCELL, CFLD, FLD|STR|DONTFREE, 0, nil, EMPTY, 0.0 };void recinit(unsigned int n)
{--- a/proto.h
+++ b/proto.h
@@ -63,6 +63,7 @@
extern char *setsval(Cell *, char *);
extern double getfval(Cell *);
extern char *getsval(Cell *);
+extern char *getpssval(Cell *); /* for print */
extern char *tostring(char *);
extern char *qstring(char *, int);
--- a/run.c
+++ b/run.c
@@ -12,23 +12,23 @@
Node *winner = nil; /* root of parse tree */
Cell *tmps; /* free temporary cells for execution */
-static Cell truecell ={ OBOOL, BTRUE, NUM, 0, 0, 1.0 };+static Cell truecell ={ OBOOL, BTRUE, NUM, 0, 0, 0, 1.0 };Cell *True = &truecell;
-static Cell falsecell ={ OBOOL, BFALSE, NUM, 0, 0, 0.0 };+static Cell falsecell ={ OBOOL, BFALSE, NUM, 0, 0, 0, 0.0 };Cell *False = &falsecell;
-static Cell breakcell ={ OJUMP, JBREAK, NUM, 0, 0, 0.0 };+static Cell breakcell ={ OJUMP, JBREAK, NUM, 0, 0, 0, 0.0 };Cell *jbreak = &breakcell;
-static Cell contcell ={ OJUMP, JCONT, NUM, 0, 0, 0.0 };+static Cell contcell ={ OJUMP, JCONT, NUM, 0, 0, 0, 0.0 };Cell *jcont = &contcell;
-static Cell nextcell ={ OJUMP, JNEXT, NUM, 0, 0, 0.0 };+static Cell nextcell ={ OJUMP, JNEXT, NUM, 0, 0, 0, 0.0 };Cell *jnext = &nextcell;
-static Cell nextfilecell ={ OJUMP, JNEXTFILE, NUM, 0, 0, 0.0 };+static Cell nextfilecell ={ OJUMP, JNEXTFILE, NUM, 0, 0, 0, 0.0 };Cell *jnextfile = &nextfilecell;
-static Cell exitcell ={ OJUMP, JEXIT, NUM, 0, 0, 0.0 };+static Cell exitcell ={ OJUMP, JEXIT, NUM, 0, 0, 0, 0.0 };Cell *jexit = &exitcell;
-static Cell retcell ={ OJUMP, JRET, NUM, 0, 0, 0.0 };+static Cell retcell ={ OJUMP, JRET, NUM, 0, 0, 0, 0.0 };Cell *jret = &retcell;
-static Cell tempcell ={ OCELL, CTEMP, NUM|STR|DONTFREE, 0, EMPTY, 0.0 };+static Cell tempcell ={ OCELL, CTEMP, NUM|STR|DONTFREE, 0, 0, EMPTY, 0.0 };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, NUM|STR|DONTFREE, 0, EMPTY, 0.0 };+ static Cell newcopycell = { OCELL, CCOPY, NUM|STR|DONTFREE, 0, 0, EMPTY, 0.0 };int i, ncall, ndef;
Node *x;
Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */
@@ -1633,6 +1633,7 @@
Cell *printstat(Node **a, int) /* print a[0] */
{int r;
+ char *s;
Node *x;
Cell *y;
Biobuf *fp;
@@ -1643,7 +1644,8 @@
fp = redirect(ptoi(a[1]), a[2]);
for (x = a[0]; x != nil; x = x->nnext) {y = execute(x);
- Bwrite(fp, getsval(y), strlen(getsval(y)));
+ s = getpssval(y);
+ Bwrite(fp, s, strlen(s));
if (istemp(y))
tfree(y);
if (x->nnext == nil)
--- a/tran.c
+++ b/tran.c
@@ -352,8 +352,9 @@
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 */
{+ int conv;
char s[100]; /* BUG: unchecked */
double dtemp;
@@ -363,19 +364,37 @@
fldbld();
else if (isrec(vp) && donerec == 0)
recbld();
- if (isstr(vp) == 0) {+ conv = (uintptr)fmt >> 32 ^ (uintptr)fmt & 0xffffffff;
+ if (isstr(vp) == 0
+ || ((vp->tval & DONTFREE) == 0 && isnum(vp) && !isfld(vp))
+ && (fmt == OFMT ^ (vp->tval & FMT) != 0 || vp->conv != conv)) {if (freeable(vp))
xfree(vp->sval);
if (modf(vp->fval, &dtemp) == 0) /* it's integral */
sprint(s, "%.30g", vp->fval);
else
- sprint(s, *CONVFMT, vp->fval);
+ sprint(s, *fmt, vp->fval);
vp->sval = tostring(s);
vp->tval &= ~DONTFREE;
vp->tval |= STR;
+ if (fmt == OFMT)
+ vp->tval |= FMT;
+ else
+ vp->tval &= ~FMT;
+ vp->conv = conv;
}
dprint( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) );return(vp->sval);
+}
+
+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(char *s) /* make a copy of string s */
--
⑨