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, r,f=%d,%d\n", (void*)vp, NN(vp->nval), s, vp->tval, donerec, donefld) ); if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (isfld(vp)) { donerec = 0; /* mark $0 invalid */ fldno = atoi(vp->nval); if (fldno > *NF) newfld(fldno); dprintf( ("setting field %d to %s (%p)\n", fldno, s, s) ); } else if (isrec(vp)) { donefld = 0; /* mark $1... invalid */ donerec = 1; } t = tostring(s); /* in case it's self-assign */ if (freeable(vp)) xfree(vp->sval); vp->tval &= ~NUM; vp->tval |= STR; vp->tval &= ~DONTFREE; dprintf( ("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n", (void*)vp, NN(vp->nval), t,t, vp->tval, donerec, donefld) ); return(vp->sval = t); }
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */ { char s[100]; /* BUG: unchecked */ double dtemp; if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if (isfld(vp) && donefld == 0) fldbld(); else if (isrec(vp) && donerec == 0) recbld(); if (isstr(vp) == 0) { if (freeable(vp)) xfree(vp->sval); if (modf(vp->fval, &dtemp) == 0) /* it's integral */ sprintf(s, "%.30g", vp->fval); else sprintf(s, *fmt, vp->fval); vp->sval = tostring(s); vp->tval &= ~DONTFREE; vp->tval |= STR; } dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", (void*)vp, NN(vp->nval), vp->sval, vp->sval, vp->tval) ); return(vp->sval); }
uchar *r_getsval(Cell *vp) { uchar s[100]; double dtemp; /* if (vp->tval & ARR) ERROR "illegal reference to array %s", vp->nval FATAL; return ""; */ if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if ((vp->tval & FLD) && donefld == 0) fldbld(); else if ((vp->tval & REC) && donerec == 0) recbld(); if ((vp->tval & STR) == 0) { if (!(vp->tval&DONTFREE)) xfree(vp->sval); if (modf(vp->fval, &dtemp) == 0) /* it's integral */ sprintf((char *)s, "%.20g", vp->fval); else sprintf((char *)s, (char *)*OFMT, vp->fval); vp->sval = tostring(s); vp->tval &= ~DONTFREE; vp->tval |= STR; } dprintf( ("getsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, vp->sval, vp->tval) ); return(vp->sval); }
Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */ { int fldno; if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (isfld(vp)) { donerec = 0; /* mark $0 invalid */ fldno = atoi(vp->nval); if (fldno > *NF) newfld(fldno); dprintf( ("setting field %d to %g\n", fldno, f) ); } else if (isrec(vp)) { donefld = 0; /* mark $1... invalid */ donerec = 1; } if (freeable(vp)) xfree(vp->sval); /* free any previous string */ vp->tval &= ~STR; /* mark string invalid */ vp->tval |= NUM; /* mark number ok */ if (f == -0) /* who would have thought this possible? */ f = 0; dprintf( ("setfval %p: %s = %g, t=%o\n", (void*)vp, NN(vp->nval), f, vp->tval) ); return vp->fval = f; }
Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */ { int fldno; f += 0.0; /* normalise negative zero to positive zero */ if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (isfld(vp)) { donerec = 0; /* mark $0 invalid */ fldno = atoi(vp->nval); if (fldno > *NF) newfld(fldno); dprintf( ("setting field %d to %g\n", fldno, f) ); } else if (&vp->fval == NF) { donerec = 0; /* mark $0 invalid */ setlastfld(f); dprintf( ("setting NF to %g\n", f) ); } else if (isrec(vp)) { donefld = 0; /* mark $1... invalid */ donerec = 1; } if (freeable(vp)) 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, NN(vp->nval), f, vp->tval) ); return vp->fval = f; }
uchar *r_getsval(Cell *vp) /* get string val of a Cell */ { uchar s[100]; double dtemp; if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if ((vp->tval & FLD) && donefld == 0) fldbld(); else if ((vp->tval & REC) && donerec == 0) recbld(); if ((vp->tval & STR) == 0) { if (!(vp->tval&DONTFREE)) xfree(vp->sval); if (modf(vp->fval, &dtemp) == 0) /* it's integral */ sprintf((char *)s, "%.20g", vp->fval); else sprintf((char *)s, (char *)*CONVFMT, vp->fval); vp->sval = tostring(s); vp->tval &= ~DONTFREE; vp->tval |= STR; } dprintf( ("getsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, vp->sval, vp->tval) ); return(vp->sval); }
Awkfloat getfval(Cell *vp) /* get float val of a Cell */ { if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if (isfld(vp) && donefld == 0) fldbld(); 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 */ } dprintf( ("getfval %p: %s = %g, t=%o\n", vp, NN(vp->nval), vp->fval, vp->tval) ); return(vp->fval); }
Awkfloat setfval(Cell *vp, Awkfloat f) { if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (vp->tval & FLD) { donerec = 0; /* mark $0 invalid */ if (vp-fldtab > *NF) newfld(vp-fldtab); dprintf( ("setting field %d to %g\n", vp-fldtab, f) ); } else if (vp->tval & REC) { donefld = 0; /* mark $1... invalid */ donerec = 1; } vp->tval &= ~STR; /* mark string invalid */ vp->tval |= NUM; /* mark number ok */ dprintf( ("setfval %o: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval) ); return vp->fval = f; }
Awkfloat r_getfval(Cell *vp) { /* if (vp->tval & ARR) ERROR "illegal reference to array %s", vp->nval FATAL; return 0.0; */ if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if ((vp->tval & FLD) && donefld == 0) fldbld(); else if ((vp->tval & REC) && donerec == 0) recbld(); if (!isnum(vp)) { /* not a number */ vp->fval = atof(vp->sval); /* best guess */ if (isnumber(vp->sval) && !(vp->tval&CON)) vp->tval |= NUM; /* make NUM only sparingly */ } dprintf( ("getfval %o: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) ); return(vp->fval); }
uchar *setsval(Cell *vp, uchar *s) { if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (vp->tval & FLD) { donerec = 0; /* mark $0 invalid */ if (vp-fldtab > *NF) newfld(vp-fldtab); dprintf( ("setting field %d to %s\n", vp-fldtab, s) ); } else if (vp->tval & REC) { donefld = 0; /* mark $1... invalid */ donerec = 1; } vp->tval &= ~NUM; vp->tval |= STR; if (freeable(vp)) xfree(vp->sval); vp->tval &= ~DONTFREE; dprintf( ("setsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) ); return(vp->sval = tostring(s)); }
Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ { /* this is subtle; don't muck with it. */ Cell *x, *y; Awkfloat xf, yf; double v; y = execute(a[1]); x = execute(a[0]); if (n == ASSIGN) { /* ordinary assignment */ if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */ ; /* leave alone unless it's a field */ else if ((y->tval & (STR|NUM)) == (STR|NUM)) { setsval(x, getsval(y)); x->fval = getfval(y); x->tval |= NUM; } else if (y->tval & STR) setsval(x, getsval(y)); else if (y->tval & NUM) setfval(x, getfval(y)); else funnyvar(y, "read value of"); tempfree(y); return(x); } xf = getfval(x); yf = getfval(y); switch (n) { case ADDEQ: xf += yf; break; case SUBEQ: xf -= yf; break; case MULTEQ: xf *= yf; break; case DIVEQ: if (yf == 0) ERROR "division by zero in /=" FATAL; xf /= yf; break; case MODEQ: if (yf == 0) ERROR "division by zero in %%=" FATAL; modf(xf/yf, &v); xf = xf - yf * v; break; case POWEQ: if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ xf = ipow(xf, (int) yf); else xf = errcheck(pow(xf, yf), "pow"); break; default: ERROR "illegal assignment operator %d", n FATAL; break; } tempfree(y); setfval(x, xf); return(x); }