Blame


1 63a68686 2008-11-03 jas /****************************************************************
2 63a68686 2008-11-03 jas Copyright (C) Lucent Technologies 1997
3 63a68686 2008-11-03 jas All Rights Reserved
4 63a68686 2008-11-03 jas
5 63a68686 2008-11-03 jas Permission to use, copy, modify, and distribute this software and
6 63a68686 2008-11-03 jas its documentation for any purpose and without fee is hereby
7 63a68686 2008-11-03 jas granted, provided that the above copyright notice appear in all
8 63a68686 2008-11-03 jas copies and that both that the copyright notice and this
9 63a68686 2008-11-03 jas permission notice and warranty disclaimer appear in supporting
10 63a68686 2008-11-03 jas documentation, and that the name Lucent Technologies or any of
11 63a68686 2008-11-03 jas its entities not be used in advertising or publicity pertaining
12 63a68686 2008-11-03 jas to distribution of the software without specific, written prior
13 63a68686 2008-11-03 jas permission.
14 63a68686 2008-11-03 jas
15 63a68686 2008-11-03 jas LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 63a68686 2008-11-03 jas INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 63a68686 2008-11-03 jas IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 63a68686 2008-11-03 jas SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 63a68686 2008-11-03 jas WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 63a68686 2008-11-03 jas IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 63a68686 2008-11-03 jas ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 63a68686 2008-11-03 jas THIS SOFTWARE.
23 63a68686 2008-11-03 jas ****************************************************************/
24 63a68686 2008-11-03 jas
25 63a68686 2008-11-03 jas #define DEBUG
26 63a68686 2008-11-03 jas #include <stdio.h>
27 63a68686 2008-11-03 jas #include <math.h>
28 63a68686 2008-11-03 jas #include <ctype.h>
29 63a68686 2008-11-03 jas #include <string.h>
30 63a68686 2008-11-03 jas #include <stdlib.h>
31 63a68686 2008-11-03 jas #include "awk.h"
32 63a68686 2008-11-03 jas #include "y.tab.h"
33 63a68686 2008-11-03 jas
34 63a68686 2008-11-03 jas #define FULLTAB 2 /* rehash when table gets this x full */
35 63a68686 2008-11-03 jas #define GROWTAB 4 /* grow table by this factor */
36 63a68686 2008-11-03 jas
37 63a68686 2008-11-03 jas Array *symtab; /* main symbol table */
38 63a68686 2008-11-03 jas
39 63a68686 2008-11-03 jas char **FS; /* initial field sep */
40 63a68686 2008-11-03 jas char **RS; /* initial record sep */
41 63a68686 2008-11-03 jas char **OFS; /* output field sep */
42 63a68686 2008-11-03 jas char **ORS; /* output record sep */
43 63a68686 2008-11-03 jas char **OFMT; /* output format for numbers */
44 63a68686 2008-11-03 jas char **CONVFMT; /* format for conversions in getsval */
45 63a68686 2008-11-03 jas Awkfloat *NF; /* number of fields in current record */
46 63a68686 2008-11-03 jas Awkfloat *NR; /* number of current record */
47 63a68686 2008-11-03 jas Awkfloat *FNR; /* number of current record in current file */
48 63a68686 2008-11-03 jas char **FILENAME; /* current filename argument */
49 63a68686 2008-11-03 jas Awkfloat *ARGC; /* number of arguments from command line */
50 63a68686 2008-11-03 jas char **SUBSEP; /* subscript separator for a[i,j,k]; default \034 */
51 63a68686 2008-11-03 jas Awkfloat *RSTART; /* start of re matched with ~; origin 1 (!) */
52 63a68686 2008-11-03 jas Awkfloat *RLENGTH; /* length of same */
53 63a68686 2008-11-03 jas
54 63a68686 2008-11-03 jas Cell *nrloc; /* NR */
55 63a68686 2008-11-03 jas Cell *nfloc; /* NF */
56 63a68686 2008-11-03 jas Cell *fnrloc; /* FNR */
57 63a68686 2008-11-03 jas Array *ARGVtab; /* symbol table containing ARGV[...] */
58 63a68686 2008-11-03 jas Array *ENVtab; /* symbol table containing ENVIRON[...] */
59 63a68686 2008-11-03 jas Cell *rstartloc; /* RSTART */
60 63a68686 2008-11-03 jas Cell *rlengthloc; /* RLENGTH */
61 63a68686 2008-11-03 jas Cell *symtabloc; /* SYMTAB */
62 63a68686 2008-11-03 jas
63 63a68686 2008-11-03 jas Cell *nullloc; /* a guaranteed empty cell */
64 63a68686 2008-11-03 jas Node *nullnode; /* zero&null, converted into a node for comparisons */
65 63a68686 2008-11-03 jas Cell *literal0;
66 63a68686 2008-11-03 jas
67 63a68686 2008-11-03 jas extern Cell **fldtab;
68 63a68686 2008-11-03 jas
69 63a68686 2008-11-03 jas void syminit(void) /* initialize symbol table with builtin vars */
70 63a68686 2008-11-03 jas {
71 63a68686 2008-11-03 jas literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);
72 63a68686 2008-11-03 jas /* this is used for if(x)... tests: */
73 63a68686 2008-11-03 jas nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab);
74 63a68686 2008-11-03 jas nullnode = celltonode(nullloc, CCON);
75 63a68686 2008-11-03 jas
76 63a68686 2008-11-03 jas FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval;
77 63a68686 2008-11-03 jas RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
78 63a68686 2008-11-03 jas OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval;
79 63a68686 2008-11-03 jas ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
80 63a68686 2008-11-03 jas OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
81 63a68686 2008-11-03 jas CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
82 63a68686 2008-11-03 jas FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval;
83 63a68686 2008-11-03 jas nfloc = setsymtab("NF", "", 0.0, NUM, symtab);
84 63a68686 2008-11-03 jas NF = &nfloc->fval;
85 63a68686 2008-11-03 jas nrloc = setsymtab("NR", "", 0.0, NUM, symtab);
86 63a68686 2008-11-03 jas NR = &nrloc->fval;
87 63a68686 2008-11-03 jas fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
88 63a68686 2008-11-03 jas FNR = &fnrloc->fval;
89 63a68686 2008-11-03 jas SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval;
90 63a68686 2008-11-03 jas rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab);
91 63a68686 2008-11-03 jas RSTART = &rstartloc->fval;
92 63a68686 2008-11-03 jas rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);
93 63a68686 2008-11-03 jas RLENGTH = &rlengthloc->fval;
94 63a68686 2008-11-03 jas symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab);
95 63a68686 2008-11-03 jas symtabloc->sval = (char *) symtab;
96 63a68686 2008-11-03 jas }
97 63a68686 2008-11-03 jas
98 63a68686 2008-11-03 jas void arginit(int ac, char **av) /* set up ARGV and ARGC */
99 63a68686 2008-11-03 jas {
100 63a68686 2008-11-03 jas Cell *cp;
101 63a68686 2008-11-03 jas int i;
102 63a68686 2008-11-03 jas char temp[50];
103 63a68686 2008-11-03 jas
104 63a68686 2008-11-03 jas ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
105 63a68686 2008-11-03 jas cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
106 63a68686 2008-11-03 jas ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */
107 63a68686 2008-11-03 jas cp->sval = (char *) ARGVtab;
108 63a68686 2008-11-03 jas for (i = 0; i < ac; i++) {
109 63a68686 2008-11-03 jas sprintf(temp, "%d", i);
110 63a68686 2008-11-03 jas if (is_number(*av))
111 63a68686 2008-11-03 jas setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);
112 63a68686 2008-11-03 jas else
113 63a68686 2008-11-03 jas setsymtab(temp, *av, 0.0, STR, ARGVtab);
114 63a68686 2008-11-03 jas av++;
115 63a68686 2008-11-03 jas }
116 63a68686 2008-11-03 jas }
117 63a68686 2008-11-03 jas
118 63a68686 2008-11-03 jas void envinit(char **envp) /* set up ENVIRON variable */
119 63a68686 2008-11-03 jas {
120 63a68686 2008-11-03 jas Cell *cp;
121 63a68686 2008-11-03 jas char *p;
122 63a68686 2008-11-03 jas
123 63a68686 2008-11-03 jas cp = setsymtab("ENVIRON", "", 0.0, ARR, symtab);
124 63a68686 2008-11-03 jas ENVtab = makesymtab(NSYMTAB);
125 63a68686 2008-11-03 jas cp->sval = (char *) ENVtab;
126 63a68686 2008-11-03 jas for ( ; *envp; envp++) {
127 63a68686 2008-11-03 jas if ((p = strchr(*envp, '=')) == NULL)
128 63a68686 2008-11-03 jas continue;
129 63a68686 2008-11-03 jas *p++ = 0; /* split into two strings at = */
130 63a68686 2008-11-03 jas if (is_number(p))
131 63a68686 2008-11-03 jas setsymtab(*envp, p, atof(p), STR|NUM, ENVtab);
132 63a68686 2008-11-03 jas else
133 63a68686 2008-11-03 jas setsymtab(*envp, p, 0.0, STR, ENVtab);
134 63a68686 2008-11-03 jas p[-1] = '='; /* restore in case env is passed down to a shell */
135 63a68686 2008-11-03 jas }
136 63a68686 2008-11-03 jas }
137 63a68686 2008-11-03 jas
138 63a68686 2008-11-03 jas Array *makesymtab(int n) /* make a new symbol table */
139 63a68686 2008-11-03 jas {
140 63a68686 2008-11-03 jas Array *ap;
141 63a68686 2008-11-03 jas Cell **tp;
142 63a68686 2008-11-03 jas
143 63a68686 2008-11-03 jas ap = (Array *) malloc(sizeof(Array));
144 63a68686 2008-11-03 jas tp = (Cell **) calloc(n, sizeof(Cell *));
145 63a68686 2008-11-03 jas if (ap == NULL || tp == NULL)
146 63a68686 2008-11-03 jas FATAL("out of space in makesymtab");
147 63a68686 2008-11-03 jas ap->nelem = 0;
148 63a68686 2008-11-03 jas ap->size = n;
149 63a68686 2008-11-03 jas ap->tab = tp;
150 63a68686 2008-11-03 jas return(ap);
151 63a68686 2008-11-03 jas }
152 63a68686 2008-11-03 jas
153 63a68686 2008-11-03 jas void freesymtab(Cell *ap) /* free a symbol table */
154 63a68686 2008-11-03 jas {
155 63a68686 2008-11-03 jas Cell *cp, *temp;
156 63a68686 2008-11-03 jas Array *tp;
157 63a68686 2008-11-03 jas int i;
158 63a68686 2008-11-03 jas
159 63a68686 2008-11-03 jas if (!isarr(ap))
160 63a68686 2008-11-03 jas return;
161 63a68686 2008-11-03 jas tp = (Array *) ap->sval;
162 63a68686 2008-11-03 jas if (tp == NULL)
163 63a68686 2008-11-03 jas return;
164 63a68686 2008-11-03 jas for (i = 0; i < tp->size; i++) {
165 63a68686 2008-11-03 jas for (cp = tp->tab[i]; cp != NULL; cp = temp) {
166 63a68686 2008-11-03 jas xfree(cp->nval);
167 63a68686 2008-11-03 jas if (freeable(cp))
168 63a68686 2008-11-03 jas xfree(cp->sval);
169 63a68686 2008-11-03 jas temp = cp->cnext; /* avoids freeing then using */
170 fa325e9b 2020-01-10 cross free(cp);
171 63a68686 2008-11-03 jas }
172 63a68686 2008-11-03 jas tp->tab[i] = 0;
173 63a68686 2008-11-03 jas }
174 63a68686 2008-11-03 jas free(tp->tab);
175 63a68686 2008-11-03 jas free(tp);
176 63a68686 2008-11-03 jas }
177 63a68686 2008-11-03 jas
178 63a68686 2008-11-03 jas void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */
179 63a68686 2008-11-03 jas {
180 63a68686 2008-11-03 jas Array *tp;
181 63a68686 2008-11-03 jas Cell *p, *prev = NULL;
182 63a68686 2008-11-03 jas int h;
183 fa325e9b 2020-01-10 cross
184 63a68686 2008-11-03 jas tp = (Array *) ap->sval;
185 63a68686 2008-11-03 jas h = hash(s, tp->size);
186 63a68686 2008-11-03 jas for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)
187 63a68686 2008-11-03 jas if (strcmp(s, p->nval) == 0) {
188 63a68686 2008-11-03 jas if (prev == NULL) /* 1st one */
189 63a68686 2008-11-03 jas tp->tab[h] = p->cnext;
190 63a68686 2008-11-03 jas else /* middle somewhere */
191 63a68686 2008-11-03 jas prev->cnext = p->cnext;
192 63a68686 2008-11-03 jas if (freeable(p))
193 63a68686 2008-11-03 jas xfree(p->sval);
194 63a68686 2008-11-03 jas free(p->nval);
195 63a68686 2008-11-03 jas free(p);
196 63a68686 2008-11-03 jas tp->nelem--;
197 63a68686 2008-11-03 jas return;
198 63a68686 2008-11-03 jas }
199 63a68686 2008-11-03 jas }
200 63a68686 2008-11-03 jas
201 63a68686 2008-11-03 jas Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp)
202 63a68686 2008-11-03 jas {
203 63a68686 2008-11-03 jas int h;
204 63a68686 2008-11-03 jas Cell *p;
205 63a68686 2008-11-03 jas
206 63a68686 2008-11-03 jas if (n != NULL && (p = lookup(n, tp)) != NULL) {
207 63a68686 2008-11-03 jas dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
208 63a68686 2008-11-03 jas p, p->nval, p->sval, p->fval, p->tval) );
209 63a68686 2008-11-03 jas return(p);
210 63a68686 2008-11-03 jas }
211 63a68686 2008-11-03 jas p = (Cell *) malloc(sizeof(Cell));
212 63a68686 2008-11-03 jas if (p == NULL)
213 63a68686 2008-11-03 jas FATAL("out of space for symbol table at %s", n);
214 63a68686 2008-11-03 jas p->nval = tostring(n);
215 63a68686 2008-11-03 jas p->sval = s ? tostring(s) : tostring("");
216 63a68686 2008-11-03 jas p->fval = f;
217 63a68686 2008-11-03 jas p->tval = t;
218 63a68686 2008-11-03 jas p->csub = CUNK;
219 63a68686 2008-11-03 jas p->ctype = OCELL;
220 63a68686 2008-11-03 jas tp->nelem++;
221 63a68686 2008-11-03 jas if (tp->nelem > FULLTAB * tp->size)
222 63a68686 2008-11-03 jas rehash(tp);
223 63a68686 2008-11-03 jas h = hash(n, tp->size);
224 63a68686 2008-11-03 jas p->cnext = tp->tab[h];
225 63a68686 2008-11-03 jas tp->tab[h] = p;
226 63a68686 2008-11-03 jas dprintf( ("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",
227 63a68686 2008-11-03 jas p, p->nval, p->sval, p->fval, p->tval) );
228 63a68686 2008-11-03 jas return(p);
229 63a68686 2008-11-03 jas }
230 63a68686 2008-11-03 jas
231 63a68686 2008-11-03 jas int hash(char *s, int n) /* form hash value for string s */
232 63a68686 2008-11-03 jas {
233 63a68686 2008-11-03 jas unsigned hashval;
234 63a68686 2008-11-03 jas
235 63a68686 2008-11-03 jas for (hashval = 0; *s != '\0'; s++)
236 63a68686 2008-11-03 jas hashval = (*s + 31 * hashval);
237 63a68686 2008-11-03 jas return hashval % n;
238 63a68686 2008-11-03 jas }
239 63a68686 2008-11-03 jas
240 63a68686 2008-11-03 jas void rehash(Array *tp) /* rehash items in small table into big one */
241 63a68686 2008-11-03 jas {
242 63a68686 2008-11-03 jas int i, nh, nsz;
243 63a68686 2008-11-03 jas Cell *cp, *op, **np;
244 63a68686 2008-11-03 jas
245 63a68686 2008-11-03 jas nsz = GROWTAB * tp->size;
246 63a68686 2008-11-03 jas np = (Cell **) calloc(nsz, sizeof(Cell *));
247 63a68686 2008-11-03 jas if (np == NULL) /* can't do it, but can keep running. */
248 63a68686 2008-11-03 jas return; /* someone else will run out later. */
249 63a68686 2008-11-03 jas for (i = 0; i < tp->size; i++) {
250 63a68686 2008-11-03 jas for (cp = tp->tab[i]; cp; cp = op) {
251 63a68686 2008-11-03 jas op = cp->cnext;
252 63a68686 2008-11-03 jas nh = hash(cp->nval, nsz);
253 63a68686 2008-11-03 jas cp->cnext = np[nh];
254 63a68686 2008-11-03 jas np[nh] = cp;
255 63a68686 2008-11-03 jas }
256 63a68686 2008-11-03 jas }
257 63a68686 2008-11-03 jas free(tp->tab);
258 63a68686 2008-11-03 jas tp->tab = np;
259 63a68686 2008-11-03 jas tp->size = nsz;
260 63a68686 2008-11-03 jas }
261 63a68686 2008-11-03 jas
262 63a68686 2008-11-03 jas Cell *lookup(char *s, Array *tp) /* look for s in tp */
263 63a68686 2008-11-03 jas {
264 63a68686 2008-11-03 jas Cell *p;
265 63a68686 2008-11-03 jas int h;
266 63a68686 2008-11-03 jas
267 63a68686 2008-11-03 jas h = hash(s, tp->size);
268 63a68686 2008-11-03 jas for (p = tp->tab[h]; p != NULL; p = p->cnext)
269 63a68686 2008-11-03 jas if (strcmp(s, p->nval) == 0)
270 63a68686 2008-11-03 jas return(p); /* found it */
271 63a68686 2008-11-03 jas return(NULL); /* not found */
272 63a68686 2008-11-03 jas }
273 63a68686 2008-11-03 jas
274 63a68686 2008-11-03 jas Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
275 63a68686 2008-11-03 jas {
276 63a68686 2008-11-03 jas int fldno;
277 63a68686 2008-11-03 jas
278 fa325e9b 2020-01-10 cross if ((vp->tval & (NUM | STR)) == 0)
279 63a68686 2008-11-03 jas funnyvar(vp, "assign to");
280 63a68686 2008-11-03 jas if (isfld(vp)) {
281 63a68686 2008-11-03 jas donerec = 0; /* mark $0 invalid */
282 63a68686 2008-11-03 jas fldno = atoi(vp->nval);
283 63a68686 2008-11-03 jas if (fldno > *NF)
284 63a68686 2008-11-03 jas newfld(fldno);
285 63a68686 2008-11-03 jas dprintf( ("setting field %d to %g\n", fldno, f) );
286 63a68686 2008-11-03 jas } else if (isrec(vp)) {
287 63a68686 2008-11-03 jas donefld = 0; /* mark $1... invalid */
288 63a68686 2008-11-03 jas donerec = 1;
289 63a68686 2008-11-03 jas }
290 63a68686 2008-11-03 jas if (freeable(vp))
291 63a68686 2008-11-03 jas xfree(vp->sval); /* free any previous string */
292 63a68686 2008-11-03 jas vp->tval &= ~STR; /* mark string invalid */
293 63a68686 2008-11-03 jas vp->tval |= NUM; /* mark number ok */
294 63a68686 2008-11-03 jas dprintf( ("setfval %p: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval) );
295 63a68686 2008-11-03 jas return vp->fval = f;
296 63a68686 2008-11-03 jas }
297 63a68686 2008-11-03 jas
298 63a68686 2008-11-03 jas void funnyvar(Cell *vp, char *rw)
299 63a68686 2008-11-03 jas {
300 63a68686 2008-11-03 jas if (isarr(vp))
301 63a68686 2008-11-03 jas FATAL("can't %s %s; it's an array name.", rw, vp->nval);
302 63a68686 2008-11-03 jas if (vp->tval & FCN)
303 63a68686 2008-11-03 jas FATAL("can't %s %s; it's a function.", rw, vp->nval);
304 63a68686 2008-11-03 jas WARNING("funny variable %p: n=%s s=\"%s\" f=%g t=%o",
305 63a68686 2008-11-03 jas vp, vp->nval, vp->sval, vp->fval, vp->tval);
306 63a68686 2008-11-03 jas }
307 63a68686 2008-11-03 jas
308 63a68686 2008-11-03 jas char *setsval(Cell *vp, char *s) /* set string val of a Cell */
309 63a68686 2008-11-03 jas {
310 63a68686 2008-11-03 jas char *t;
311 63a68686 2008-11-03 jas int fldno;
312 63a68686 2008-11-03 jas
313 63a68686 2008-11-03 jas dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) );
314 63a68686 2008-11-03 jas if ((vp->tval & (NUM | STR)) == 0)
315 63a68686 2008-11-03 jas funnyvar(vp, "assign to");
316 63a68686 2008-11-03 jas if (isfld(vp)) {
317 63a68686 2008-11-03 jas donerec = 0; /* mark $0 invalid */
318 63a68686 2008-11-03 jas fldno = atoi(vp->nval);
319 63a68686 2008-11-03 jas if (fldno > *NF)
320 63a68686 2008-11-03 jas newfld(fldno);
321 63a68686 2008-11-03 jas dprintf( ("setting field %d to %s (%p)\n", fldno, s, s) );
322 63a68686 2008-11-03 jas } else if (isrec(vp)) {
323 63a68686 2008-11-03 jas donefld = 0; /* mark $1... invalid */
324 63a68686 2008-11-03 jas donerec = 1;
325 63a68686 2008-11-03 jas }
326 63a68686 2008-11-03 jas t = tostring(s); /* in case it's self-assign */
327 63a68686 2008-11-03 jas vp->tval &= ~NUM;
328 63a68686 2008-11-03 jas vp->tval |= STR;
329 63a68686 2008-11-03 jas if (freeable(vp))
330 63a68686 2008-11-03 jas xfree(vp->sval);
331 63a68686 2008-11-03 jas vp->tval &= ~DONTFREE;
332 63a68686 2008-11-03 jas dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) );
333 63a68686 2008-11-03 jas return(vp->sval = t);
334 63a68686 2008-11-03 jas }
335 63a68686 2008-11-03 jas
336 63a68686 2008-11-03 jas Awkfloat getfval(Cell *vp) /* get float val of a Cell */
337 63a68686 2008-11-03 jas {
338 63a68686 2008-11-03 jas if ((vp->tval & (NUM | STR)) == 0)
339 63a68686 2008-11-03 jas funnyvar(vp, "read value of");
340 63a68686 2008-11-03 jas if (isfld(vp) && donefld == 0)
341 63a68686 2008-11-03 jas fldbld();
342 63a68686 2008-11-03 jas else if (isrec(vp) && donerec == 0)
343 63a68686 2008-11-03 jas recbld();
344 63a68686 2008-11-03 jas if (!isnum(vp)) { /* not a number */
345 63a68686 2008-11-03 jas vp->fval = atof(vp->sval); /* best guess */
346 63a68686 2008-11-03 jas if (is_number(vp->sval) && !(vp->tval&CON))
347 63a68686 2008-11-03 jas vp->tval |= NUM; /* make NUM only sparingly */
348 63a68686 2008-11-03 jas }
349 63a68686 2008-11-03 jas dprintf( ("getfval %p: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) );
350 63a68686 2008-11-03 jas return(vp->fval);
351 63a68686 2008-11-03 jas }
352 63a68686 2008-11-03 jas
353 63a68686 2008-11-03 jas char *getsval(Cell *vp) /* get string val of a Cell */
354 63a68686 2008-11-03 jas {
355 63a68686 2008-11-03 jas char s[100]; /* BUG: unchecked */
356 63a68686 2008-11-03 jas double dtemp;
357 63a68686 2008-11-03 jas
358 63a68686 2008-11-03 jas if ((vp->tval & (NUM | STR)) == 0)
359 63a68686 2008-11-03 jas funnyvar(vp, "read value of");
360 63a68686 2008-11-03 jas if (isfld(vp) && donefld == 0)
361 63a68686 2008-11-03 jas fldbld();
362 63a68686 2008-11-03 jas else if (isrec(vp) && donerec == 0)
363 63a68686 2008-11-03 jas recbld();
364 63a68686 2008-11-03 jas if (isstr(vp) == 0) {
365 63a68686 2008-11-03 jas if (freeable(vp))
366 63a68686 2008-11-03 jas xfree(vp->sval);
367 63a68686 2008-11-03 jas if (modf(vp->fval, &dtemp) == 0) /* it's integral */
368 63a68686 2008-11-03 jas sprintf(s, "%.30g", vp->fval);
369 63a68686 2008-11-03 jas else
370 63a68686 2008-11-03 jas sprintf(s, *CONVFMT, vp->fval);
371 63a68686 2008-11-03 jas vp->sval = tostring(s);
372 63a68686 2008-11-03 jas vp->tval &= ~DONTFREE;
373 63a68686 2008-11-03 jas vp->tval |= STR;
374 63a68686 2008-11-03 jas }
375 63a68686 2008-11-03 jas dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) );
376 63a68686 2008-11-03 jas return(vp->sval);
377 63a68686 2008-11-03 jas }
378 63a68686 2008-11-03 jas
379 63a68686 2008-11-03 jas char *tostring(char *s) /* make a copy of string s */
380 63a68686 2008-11-03 jas {
381 63a68686 2008-11-03 jas char *p;
382 63a68686 2008-11-03 jas
383 63a68686 2008-11-03 jas p = (char *) malloc(strlen(s)+1);
384 63a68686 2008-11-03 jas if (p == NULL)
385 63a68686 2008-11-03 jas FATAL("out of space in tostring on %s", s);
386 63a68686 2008-11-03 jas strcpy(p, s);
387 63a68686 2008-11-03 jas return(p);
388 63a68686 2008-11-03 jas }
389 63a68686 2008-11-03 jas
390 63a68686 2008-11-03 jas char *qstring(char *s, int delim) /* collect string up to next delim */
391 63a68686 2008-11-03 jas {
392 63a68686 2008-11-03 jas char *os = s;
393 63a68686 2008-11-03 jas int c, n;
394 63a68686 2008-11-03 jas char *buf, *bp;
395 63a68686 2008-11-03 jas
396 63a68686 2008-11-03 jas if ((buf = (char *) malloc(strlen(s)+3)) == NULL)
397 63a68686 2008-11-03 jas FATAL( "out of space in qstring(%s)", s);
398 63a68686 2008-11-03 jas for (bp = buf; (c = *s) != delim; s++) {
399 63a68686 2008-11-03 jas if (c == '\n')
400 63a68686 2008-11-03 jas SYNTAX( "newline in string %.20s...", os );
401 63a68686 2008-11-03 jas else if (c != '\\')
402 63a68686 2008-11-03 jas *bp++ = c;
403 63a68686 2008-11-03 jas else { /* \something */
404 63a68686 2008-11-03 jas c = *++s;
405 63a68686 2008-11-03 jas if (c == 0) { /* \ at end */
406 63a68686 2008-11-03 jas *bp++ = '\\';
407 63a68686 2008-11-03 jas break; /* for loop */
408 fa325e9b 2020-01-10 cross }
409 63a68686 2008-11-03 jas switch (c) {
410 63a68686 2008-11-03 jas case '\\': *bp++ = '\\'; break;
411 63a68686 2008-11-03 jas case 'n': *bp++ = '\n'; break;
412 63a68686 2008-11-03 jas case 't': *bp++ = '\t'; break;
413 63a68686 2008-11-03 jas case 'b': *bp++ = '\b'; break;
414 63a68686 2008-11-03 jas case 'f': *bp++ = '\f'; break;
415 63a68686 2008-11-03 jas case 'r': *bp++ = '\r'; break;
416 63a68686 2008-11-03 jas default:
417 63a68686 2008-11-03 jas if (!isdigit(c)) {
418 63a68686 2008-11-03 jas *bp++ = c;
419 63a68686 2008-11-03 jas break;
420 63a68686 2008-11-03 jas }
421 63a68686 2008-11-03 jas n = c - '0';
422 63a68686 2008-11-03 jas if (isdigit(s[1])) {
423 63a68686 2008-11-03 jas n = 8 * n + *++s - '0';
424 63a68686 2008-11-03 jas if (isdigit(s[1]))
425 63a68686 2008-11-03 jas n = 8 * n + *++s - '0';
426 63a68686 2008-11-03 jas }
427 63a68686 2008-11-03 jas *bp++ = n;
428 63a68686 2008-11-03 jas break;
429 63a68686 2008-11-03 jas }
430 63a68686 2008-11-03 jas }
431 63a68686 2008-11-03 jas }
432 63a68686 2008-11-03 jas *bp++ = 0;
433 63a68686 2008-11-03 jas return buf;
434 63a68686 2008-11-03 jas }