shithub: kwa

Download patch

ref: 8e3c92b4eae6ff958d8af946caf6fb7d7f3bfbf7
parent: c3eea8755d4adbf3dc4cb9bda166a9e02c2064b5
author: qwx <qwx@sciops.net>
date: Wed Sep 24 13:04:55 EDT 2025

keep conversion result whenever using is_number

--- a/lib.c
+++ b/lib.c
@@ -121,10 +121,8 @@
 					xfree(fldtab[0]->sval);
 				fldtab[0]->sval = buf;	/* buf == record */
 				fldtab[0]->tval = REC | STR | DONTFREE;
-				if (is_number(fldtab[0]->sval)) {
-					fldtab[0]->fval = atof(fldtab[0]->sval);
+				if (to_number(fldtab[0]->sval, &fldtab[0]->fval))
 					fldtab[0]->tval |= NUM;
-				}
 			}
 			setfval(nrloc, nrloc->fval+1);
 			setfval(fnrloc, fnrloc->fval+1);
@@ -213,10 +211,8 @@
 	p = qstring(p, '\0');
 	q = setsymtab(s, p, 0.0, STR, symtab);
 	setsval(q, p);
-	if (is_number(q->sval)) {
-		q->fval = atof(q->sval);
+	if (to_number(q->sval, &q->fval))
 		q->tval |= NUM;
-	}
 	   dprint( ("command line set %s to |%s|\n", s, p) );
 }
 
@@ -305,10 +301,8 @@
 	donefld = 1;
 	for (j = 1; j <= lastfld; j++) {
 		p = fldtab[j];
-		if(is_number(p->sval)) {
-			p->fval = atof(p->sval);
+		if (to_number(p->sval, &p->fval))
 			p->tval |= NUM;
-		}
 	}
 	setfval(nfloc, (Awkfloat) lastfld);
 	if (dbg) {
@@ -643,7 +637,7 @@
 
 /* strtod is supposed to be a proper test of what's a valid number */
 
-int is_number(char *s)
+int to_number(char *s, Awkfloat *fp)
 {
 	double r;
 	char *ep;
@@ -674,6 +668,8 @@
 	}
 
 	r = strtod(s, &ep);
+	if (fp != nil)	/* relied upon by getfval */
+		*fp = r;
 	if (ep == s || isInf(r, 1) || isInf(r, -1) || isNaN(r))
 		return 0;
 	while (*ep == ' ' || *ep == '\t' || *ep == '\n')
--- a/proto.h
+++ b/proto.h
@@ -93,7 +93,7 @@
 extern	void	bclass(int);
 extern	double	errcheck(double, char *);
 extern	int	isclvar(char *);
-extern	int	is_number(char *);
+extern	int	to_number(char *, Awkfloat *);
 
 extern	int	adjbuf(char **pb, int *sz, int min, int q, char **pbp, char *what);
 extern	void	run(Node *);
--- a/run.c
+++ b/run.c
@@ -405,10 +405,8 @@
 				tfree(x);
 		} else {			/* getline <file */
 			setsval(fldtab[0], buf);
-			if (is_number(fldtab[0]->sval)) {
-				fldtab[0]->fval = atof(fldtab[0]->sval);
+			if (to_number(fldtab[0]->sval, &fldtab[0]->fval))
 				fldtab[0]->tval |= NUM;
-			}
 		}
 	} else {			/* bare getline; use current input */
 		if (a[0] == nil)	/* getline */
@@ -712,9 +710,11 @@
 
 	x = execute(a[0]);
 	m = (int) getfval(x);
-	if (m == 0 && !is_number(s = getsval(x)))	/* suspicion! */
-		FATAL("illegal field $(%s), name \"%s\"", s, x->nval);
-		/* BUG: can x->nval ever be null??? */
+	if (m == 0) {
+		if (!to_number(s = getsval(x), &x->fval))	/* suspicion! */
+			FATAL("illegal field $(%s), name \"%s\"", s, x->nval);
+			/* BUG: can x->nval ever be null??? */
+	}
 	if (istemp(x))
 		tfree(x);
 	x = fieldadr(m);
@@ -1239,6 +1239,7 @@
 	Cell *x = 0, *y, *ap;
 	char *s, *t, *fs = 0;
 	char temp, num[50];
+	Awkfloat f;
 	int n, nb, sep, arg3type;
 
 	y = execute(a[0]);	/* source string */
@@ -1279,8 +1280,8 @@
 				sprint(num, "%d", n);
 				temp = *patbeg;
 				*patbeg = '\0';
-				if (is_number(t))
-					setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+				if (to_number(t, &f))
+					setsymtab(num, t, f, STR|NUM, (Array *) ap->sval);
 				else
 					setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
 				*patbeg = temp;
@@ -1295,8 +1296,8 @@
 		}
 		n++;
 		sprint(num, "%d", n);
-		if (is_number(t))
-			setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+		if (to_number(t, &f))
+			setsymtab(num, t, f, STR|NUM, (Array *) ap->sval);
 		else
 			setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
   spdone:
@@ -1316,8 +1317,8 @@
 			temp = *s;
 			*s = '\0';
 			sprint(num, "%d", n);
-			if (is_number(t))
-				setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+			if (to_number(t, &f))
+				setsymtab(num, t, f, STR|NUM, (Array *) ap->sval);
 			else
 				setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
 			*s = temp;
@@ -1348,8 +1349,8 @@
 			temp = *s;
 			*s = '\0';
 			sprint(num, "%d", n);
-			if (is_number(t))
-				setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+			if (to_number(t, &f))
+				setsymtab(num, t, f, STR|NUM, (Array *) ap->sval);
 			else
 				setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
 			*s = temp;
--- a/tran.c
+++ b/tran.c
@@ -74,6 +74,7 @@
 	Cell *cp;
 	int i;
 	char temp[50];
+	Awkfloat f;
 
 	AARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
 	cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
@@ -81,8 +82,8 @@
 	cp->sval = (char *) ARGVtab;
 	for (i = 0; i < ac; i++) {
 		sprint(temp, "%d", i);
-		if (is_number(*av))
-			setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);
+		if (to_number(*av, &f))
+			setsymtab(temp, *av, f, STR|NUM, ARGVtab);
 		else
 			setsymtab(temp, *av, 0.0, STR, ARGVtab);
 		av++;
@@ -94,6 +95,7 @@
 	int	fd, i, n;
 	char	*k, *v;
 	Dir	*buf;
+	Awkfloat f;
 
 	ENVtab = makesymtab(NSYMTAB);
 	if ((fd = open("/env", OREAD)) < 0)
@@ -107,8 +109,8 @@
 				continue;
 			if ((v = getenv(k)) == nil)
 				continue;
-			if (is_number(v))
-				setsymtab(k, v, atof(v), STR|NUM, ENVtab);
+			if (to_number(v, &f))
+				setsymtab(k, v, f, STR|NUM, ENVtab);
 			else
 				setsymtab(k, v, 0.0, STR, ENVtab);
 			free(v);
@@ -333,9 +335,11 @@
 	else if (isrec(vp) && donerec == 0)
 		recbld();
 	if (!isnum(vp)) {	/* not a number */
-		vp->fval = atof(vp->sval);	/* best guess */
-		if (is_number(vp->sval) && !(vp->tval&CON))
-			vp->tval |= NUM;	/* make NUM only sparingly */
+		vp->fval = 0;
+		if (to_number(vp->sval, &vp->fval)) {
+			if (!(vp->tval&CON))
+				vp->tval |= NUM;	/* make NUM only sparingly */
+		}
 	}
 	   dprint( ("getfval %p: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) );
 	return(vp->fval);
--