|
|
1.1 root 1: #define DEBUG
2: #include <stdio.h>
3: #include "awk.h"
4: #include "y.tab.h"
5:
6: Cell *symtab[MAXSYM]; /* symbol table pointers */
7:
8: char **FS; /* initial field sep */
9: char **RS; /* initial record sep */
10: char **OFS; /* output field sep */
11: char **ORS; /* output record sep */
12: char **OFMT; /*output format for numbers*/
13: Awkfloat *NF; /* number of fields in current record */
14: Awkfloat *NR; /* number of current record */
15: Awkfloat *FNR; /* number of current record in current file */
16: char **FILENAME; /* current filename argument */
17: Awkfloat *ARGC; /* number of arguments from command line */
18:
19: Cell *recloc; /* location of record */
20: Cell *nrloc; /* NR */
21: Cell *nfloc; /* NF */
22: Cell *fnrloc; /* FNR */
23: Cell **ARGVtab; /* symbol table containing ARGV[...] */
24:
25: syminit(ac, av)
26: char *av[];
27: {
28: arginit(ac, av);
29: setsymtab("0", "0", 0.0, NUM|STR|CON, symtab);
30: /* this one is used for if(x)... tests: */
31: setsymtab("$zero&null", "", 0.0, NUM|STR|CON, symtab);
32: recloc = setsymtab("$0", record, 0.0, REC|STR|DONTFREE, symtab);
33: dprintf("recloc %o lookup %o\n", recloc, lookup("$0", symtab), NULL);
34: FS = &setsymtab("FS", " ", 0.0, STR, symtab)->sval;
35: RS = &setsymtab("RS", "\n", 0.0, STR, symtab)->sval;
36: OFS = &setsymtab("OFS", " ", 0.0, STR, symtab)->sval;
37: ORS = &setsymtab("ORS", "\n", 0.0, STR, symtab)->sval;
38: OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR, symtab)->sval;
39: FILENAME = &setsymtab("FILENAME", "", 0.0, STR, symtab)->sval;
40: nfloc = setsymtab("NF", "", 0.0, NUM, symtab);
41: NF = &nfloc->fval;
42: nrloc = setsymtab("NR", "", 0.0, NUM, symtab);
43: NR = &nrloc->fval;
44: fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
45: FNR = &fnrloc->fval;
46: }
47:
48: arginit(ac, av)
49: int ac;
50: char *av[];
51: {
52: Cell *cp, **makesymtab();
53: int i;
54: char temp[5];
55:
56: ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
57: cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
58: ARGVtab = makesymtab();
59: cp->sval = (char *) ARGVtab;
60: for (i = 0; i < ac; i++) {
61: sprintf(temp, "%d", i);
62: if (isnumber(*av))
63: setsymtab(temp, *av, atof(*av), STR|NUM, cp->sval);
64: else
65: setsymtab(temp, *av, 0.0, STR, cp->sval);
66: av++;
67: }
68: }
69:
70:
71: Cell **makesymtab()
72: {
73: Cell **cp;
74:
75: cp = (Cell **) Calloc(MAXSYM, sizeof(Cell *));
76: if (cp == NULL)
77: error(FATAL, "out of space in makesymtab");
78: return(cp);
79: }
80:
81: freesymtab(ap) /* free symbol table */
82: Cell *ap;
83: {
84: Cell *cp, **tp;
85: int i;
86:
87: if (!isarr(ap))
88: return;
89: tp = (Cell **) ap->sval;
90: if (tp == NULL)
91: return;
92: for (i = 0; i < MAXSYM; i++) {
93: for (cp = tp[i]; cp != NULL; cp = cp->cnext) {
94: xfree(cp->nval);
95: xfree(cp->sval);
96: Free(cp);
97: }
98: }
99: xfree(tp);
100: }
101:
102: freeelem(ap, s) /* free elem s from ap (i.e., ap["s"] */
103: Cell *ap;
104: char *s;
105: {
106: Cell **tab, *p, *prev = NULL;
107: int h;
108:
109: tab = (Cell **) ap->sval;
110: h = hash(s);
111: for (p = tab[h]; p != NULL; prev = p, p = p->cnext)
112: if (strcmp(s, p->nval) == 0) {
113: if (prev == NULL) /* 1st one */
114: tab[h] = p->cnext;
115: else /* middle somewhere */
116: prev->cnext = p->cnext;
117: if (!(p->tval&DONTFREE))
118: xfree(p->sval);
119: Free(p->nval);
120: Free(p);
121: return;
122: }
123: }
124:
125: Cell *setsymtab(n, s, f, t, tab)
126: char *n, *s;
127: Awkfloat f;
128: unsigned t;
129: Cell **tab;
130: {
131: register h;
132: register Cell *p;
133: Cell *lookup();
134:
135: if (n != NULL && (p = lookup(n, tab)) != NULL) {
136: dprintf("setsymtab found %o: n=%s", p, p->nval, NULL);
137: dprintf(" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval);
138: return(p);
139: }
140: p = (Cell *) Malloc(sizeof(Cell));
141: if (p == NULL)
142: error(FATAL, "symbol table overflow at %s", n);
143: p->nval = tostring(n);
144: p->sval = s ? tostring(s) : tostring("");
145: p->fval = f;
146: p->tval = t;
147: h = hash(n);
148: p->cnext = tab[h];
149: tab[h] = p;
150: dprintf("setsymtab set %o: n=%s", p, p->nval, NULL);
151: dprintf(" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval);
152: return(p);
153: }
154:
155: hash(s) /* form hash value for string s */
156: register unsigned char *s;
157: {
158: register int hashval;
159:
160: for (hashval = 0; *s != '\0'; s++)
161: hashval = (*s + 31 * hashval) % MAXSYM;
162: return hashval;
163: }
164:
165: Cell *lookup(s, tab) /* look for s in tab */
166: register char *s;
167: Cell **tab;
168: {
169: register Cell *p, *prev = NULL;
170: int h;
171: extern int indepth;
172:
173: h = hash(s);
174: for (p = tab[h]; p != NULL; prev = p, p = p->cnext) {
175: if (strcmp(s, p->nval) == 0) {
176: if (prev != NULL && indepth == 0) {
177: prev->cnext = p->cnext;
178: p->cnext = tab[h];
179: tab[h] = p;
180: }
181: return(p); /* found it */
182: }
183: }
184: return(NULL); /* not found */
185: }
186:
187: Awkfloat setfval(vp, f)
188: register Cell *vp;
189: Awkfloat f;
190: {
191: if (vp->tval & ARR)
192: error(FATAL, "illegal reference to array %s", vp->nval);
193: if ((vp->tval & (NUM | STR)) == 0)
194: error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
195: vp, vp->nval, vp->sval, vp->fval, vp->tval);
196: if (vp->tval & FLD) {
197: donerec = 0; /* mark $0 invalid */
198: } else if (vp->tval & REC) {
199: donefld = 0; /* mark $1... invalid */
200: donerec = 1;
201: }
202: vp->tval &= ~STR; /* mark string invalid */
203: vp->tval |= NUM; /* mark number ok */
204: dprintf("setfval %o: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval);
205: return vp->fval = f;
206: }
207:
208: char *setsval(vp, s)
209: register Cell *vp;
210: char *s;
211: {
212: if (vp->tval & ARR)
213: error(FATAL, "illegal reference to array %s", vp->nval);
214: if ((vp->tval & (NUM | STR)) == 0)
215: error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
216: vp, vp->nval, vp->sval, vp->fval, vp->tval);
217: if (vp->tval & FLD) {
218: donerec = 0; /* mark $0 invalid */
219: } else if (vp->tval & REC) {
220: donefld = 0; /* mark $1... invalid */
221: donerec = 1;
222: }
223: vp->tval &= ~NUM;
224: vp->tval |= STR;
225: if (!(vp->tval&DONTFREE))
226: xfree(vp->sval);
227: vp->tval &= ~DONTFREE;
228: dprintf("setsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval);
229: return(vp->sval = tostring(s));
230: }
231:
232: Awkfloat real_getfval(vp)
233: register Cell *vp;
234: {
235: if (vp->tval & ARR)
236: error(FATAL, "illegal reference to array %s", vp->nval);
237: if ((vp->tval & (NUM | STR)) == 0)
238: error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
239: vp, vp->nval, vp->sval, vp->fval, vp->tval);
240: if ((vp->tval & FLD) && donefld == 0)
241: fldbld();
242: else if ((vp->tval & REC) && donerec == 0)
243: recbld();
244: if (!isnum(vp)) { /* not a number */
245: vp->fval = atof(vp->sval); /* best guess */
246: if (isnumber(vp->sval) && !(vp->tval&CON))
247: vp->tval |= NUM; /* make NUM only sparingly */
248: }
249: dprintf("getfval %o: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval);
250: return(vp->fval);
251: }
252:
253: char *real_getsval(vp)
254: register Cell *vp;
255: {
256: char s[100];
257:
258: if (vp->tval & ARR)
259: error(FATAL, "illegal reference to array %s", vp->nval);
260: if ((vp->tval & (NUM | STR)) == 0)
261: error(FATAL, "funny variable %o: n=%s s=\"%s\" f=%g t=%o",
262: vp, vp->nval, vp->sval, vp->fval, vp->tval);
263: if ((vp->tval & FLD) && donefld == 0)
264: fldbld();
265: else if ((vp->tval & REC) && donerec == 0)
266: recbld();
267: if ((vp->tval & STR) == 0) {
268: if (!(vp->tval&DONTFREE))
269: xfree(vp->sval);
270: if ((long)vp->fval == vp->fval)
271: sprintf(s, "%.20g", vp->fval);
272: else
273: sprintf(s, *OFMT, vp->fval);
274: vp->sval = tostring(s);
275: vp->tval &= ~DONTFREE;
276: vp->tval |= STR;
277: }
278: dprintf("getsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, vp->sval, vp->tval);
279: return(vp->sval);
280: }
281:
282: char *tostring(s)
283: register char *s;
284: {
285: register char *p;
286:
287: p = Malloc(strlen(s)+1);
288: if (p == NULL)
289: error(FATAL, "out of space in tostring on %s", s);
290: strcpy(p, s);
291: return(p);
292: }
293:
294: #ifdef MYALLOC
295:
296: char *Malloc(n)
297: int n;
298: {
299: fprintf(stderr, "m %d\n", n);
300: return malloc(n);
301: }
302:
303: char *Calloc(n, sz)
304: int n, sz;
305: {
306: fprintf(stderr, "c %d (%d %d)\n", n*sz, n, sz);
307: return calloc(n, sz);
308: }
309:
310: Free(p)
311: char *p;
312: {
313: free(p);
314: }
315:
316: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.