ref: fd46a754a9afcbf7086052cd7852012831ea4fbd
parent: b30c2cae2ee8c2c7cd27ecdead8fb71730497ab5
author: qwx <qwx@sciops.net>
date: Mon Nov 3 04:08:50 EST 2025
add awk-ofmt: enable OFMT and update conversion as needed (pending)
--- /dev/null
+++ b/awk-ofmt
@@ -1,0 +1,166 @@
+diff fdb503349c9e8007902b26211170cdc8dfa745af uncommitted
+--- a/sys/src/cmd/awk/awk.h
++++ b/sys/src/cmd/awk/awk.h
+@@ -61,6 +61,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 */
+@@ -91,7 +92,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/sys/src/cmd/awk/lib.c
++++ b/sys/src/cmd/awk/lib.c
+@@ -49,8 +49,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/sys/src/cmd/awk/proto.h
++++ b/sys/src/cmd/awk/proto.h
+@@ -87,6 +87,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/sys/src/cmd/awk/run.c
++++ b/sys/src/cmd/awk/run.c
+@@ -36,23 +36,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 */
+
+@@ -224,7 +224,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 */
+@@ -1656,6 +1656,7 @@
+ Cell *printstat(Node **a, int) /* print a[0] */
+ {+ int r;
++ char *s;
+ Node *x;
+ Cell *y;
+ Biobuf *fp;
+@@ -1666,7 +1667,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/sys/src/cmd/awk/tran.c
++++ b/sys/src/cmd/awk/tran.c
+@@ -236,6 +236,7 @@
+ }
+ p->csub = CUNK;
+ p->ctype = OCELL;
++ p->conv = 0;
+ tp->nelemt++;
+ if (tp->nelemt > FULLTAB * tp->size)
+ rehash(tp);
+@@ -372,8 +373,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;
+
+@@ -383,19 +385,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->conv != 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 */
--
⑨