|
|
1.1 root 1: #include "stdio.h"
2: #include "awk.def"
3: #include "awk.h"
4:
5: cell *symtab[MAXSYM]; /* symbol table pointers */
6:
7: char **FS; /* initial field sep */
8: char **RS; /* initial record sep */
9: char **OFS; /* output field sep */
10: char **ORS; /* output record sep */
11: char **OFMT; /*output format for numbers*/
12: awkfloat *NF; /* number of fields in current record */
13: awkfloat *NR; /* number of current record */
14: char **FILENAME; /* current filename argument */
15:
16: cell *recloc; /* location of record */
17: cell *nrloc; /* NR */
18: cell *nfloc; /* NF */
19:
20: syminit()
21: {
22: setsymtab("0", tostring("0"), 0.0, NUM|STR|CON|FLD, symtab);
23: recloc = setsymtab("$record", record, 0.0, STR|FLD, symtab);
24: dprintf("recloc %o lookup %o\n", recloc, lookup("$record", symtab), NULL);
25: FS = &setsymtab("FS", tostring(" "), 0.0, STR|FLD, symtab)->sval;
26: RS = &setsymtab("RS", tostring("\n"), 0.0, STR|FLD, symtab)->sval;
27: OFS = &setsymtab("OFS", tostring(" "), 0.0, STR|FLD, symtab)->sval;
28: ORS = &setsymtab("ORS", tostring("\n"), 0.0, STR|FLD, symtab)->sval;
29: OFMT = &setsymtab("OFMT", tostring("%.6g"), 0.0, STR|FLD, symtab)->sval;
30: FILENAME = &setsymtab("FILENAME", NULL, 0.0, STR|FLD, symtab)->sval;
31: nfloc = setsymtab("NF", NULL, 0.0, NUM, symtab);
32: NF = &nfloc->fval;
33: nrloc = setsymtab("NR", NULL, 0.0, NUM, symtab);
34: NR = &nrloc->fval;
35: }
36:
37: cell **makesymtab()
38: {
39: int i;
40: cell **cp;
41:
42: cp = (char *) malloc(MAXSYM * sizeof(cell *));
43: if (cp == NULL)
44: error(FATAL, "out of space in makesymtab");
45: for (i = 0; i < MAXSYM; i++)
46: *((cell **) cp + i) = 0;
47: return(cp);
48: }
49:
50: freesymtab(ap) /* free symbol table */
51: cell *ap;
52: {
53: cell *cp, **tp;
54: int i;
55:
56: if (!(ap->tval & ARR))
57: return;
58: tp = (cell **) ap->sval;
59: for (i = 0; i < MAXSYM; i++) {
60: for (cp = tp[i]; cp != NULL; cp = cp->nextval) {
61: xfree(cp->nval);
62: xfree(cp->sval);
63: free(cp);
64: }
65: }
66: xfree(tp);
67: }
68:
69: cell *setsymtab(n, s, f, t, tab)
70: char *n, *s;
71: awkfloat f;
72: unsigned t;
73: cell **tab;
74: {
75: register h;
76: register cell *p;
77: cell *lookup();
78:
79: if (n != NULL && *n != '\0' && (p = lookup(n, tab)) != NULL) {
80: xfree(s);
81: dprintf("setsymtab found %o: %s", p, p->nval, NULL);
82: dprintf(" %s %g %o\n", p->sval, p->fval, p->tval);
83: return(p);
84: }
85: p = (cell *) malloc(sizeof(cell));
86: if (p == NULL)
87: error(FATAL, "symbol table overflow at %s", n);
88: p->nval = tostring(n);
89: p->sval = s;
90: p->fval = f;
91: p->tval = t;
92: h = hash(n);
93: p->nextval = tab[h];
94: tab[h] = p;
95: dprintf("setsymtab set %o: %s", p, p->nval, NULL);
96: dprintf(" %s %g %o\n", p->sval, p->fval, p->tval);
97: return(p);
98: }
99:
100: hash(s) /* form hash value for string s */
101: register char *s;
102: {
103: register int hashval;
104:
105: for (hashval = 0; *s != '\0'; )
106: hashval += *s++;
107: return(hashval % MAXSYM);
108: }
109:
110: cell *lookup(s, tab) /* look for s in tab */
111: register char *s;
112: cell **tab;
113: {
114: register cell *p;
115:
116: for (p = tab[hash(s)]; p != NULL; p = p->nextval)
117: if (strcmp(s, p->nval) == 0)
118: return(p); /* found it */
119: return(NULL); /* not found */
120: }
121:
122: awkfloat setfval(vp, f)
123: register cell *vp;
124: awkfloat f;
125: {
126: dprintf("setfval: %o %g\n", vp, f, NULL);
127: checkval(vp);
128: if (vp == recloc)
129: error(FATAL, "can't set $0");
130: vp->tval &= ~STR; /* mark string invalid */
131: vp->tval |= NUM; /* mark number ok */
132: if ((vp->tval & FLD) && vp->nval == 0)
133: donerec = 0;
134: return(vp->fval = f);
135: }
136:
137: char *setsval(vp, s)
138: register cell *vp;
139: char *s;
140: {
141: dprintf("setsval: %o %s\n", vp, s, NULL);
142: checkval(vp);
143: if (vp == recloc)
144: error(FATAL, "can't set $0");
145: vp->tval &= ~NUM;
146: vp->tval |= STR;
147: if ((vp->tval & FLD) && vp->nval == 0)
148: donerec = 0;
149: if (!(vp->tval&FLD))
150: xfree(vp->sval);
151: vp->tval &= ~FLD;
152: return(vp->sval = tostring(s));
153: }
154:
155: awkfloat getfval(vp)
156: register cell *vp;
157: {
158: awkfloat atof();
159:
160: if (vp->sval == record && donerec == 0)
161: recbld();
162: dprintf("getfval: %o", vp, NULL, NULL);
163: checkval(vp);
164: if ((vp->tval & NUM) == 0) {
165: vp->fval = atof(vp->sval);
166: vp->tval |= NUM;
167: if (*vp->sval == '\0') { /* "" is not equal to "0" */
168: vp->tval &= ~STR;
169: if (!(vp->tval&FLD))
170: xfree(vp->sval);
171: }
172: }
173: dprintf(" %g\n", vp->fval, NULL, NULL);
174: return(vp->fval);
175: }
176:
177: char *getsval(vp)
178: register cell *vp;
179: {
180: char s[100];
181:
182: if (vp->sval == record && donerec == 0)
183: recbld();
184: dprintf("getsval: %o", vp, NULL, NULL);
185: checkval(vp);
186: if ((vp->tval & STR) == 0) {
187: if (!(vp->tval&FLD))
188: xfree(vp->sval);
189: if ((long)vp->fval==vp->fval)
190: sprintf(s, "%.20g", vp->fval);
191: else
192: sprintf(s, *OFMT, vp->fval);
193: vp->sval = tostring(s);
194: vp->tval &= ~FLD;
195: vp->tval |= STR;
196: }
197: dprintf(" %s\n", vp->sval, NULL, NULL);
198: return(vp->sval);
199: }
200:
201: checkval(vp)
202: register cell *vp;
203: {
204: if (vp->tval & ARR)
205: error(FATAL, "illegal reference to array %s", vp->nval);
206: if ((vp->tval & (NUM | STR)) == 0)
207: error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval,
208: vp->sval, vp->fval, vp->tval);
209: }
210:
211: char *tostring(s)
212: register char *s;
213: {
214: register char *p;
215:
216: p = malloc(strlen(s)+1);
217: if (p == NULL)
218: error(FATAL, "out of space in tostring on %s", s);
219: strcpy(p, s);
220: return(p);
221: }
222: #ifndef yfree
223: yfree(a) char *a;
224: {
225: printf("%o\n", a);
226: free(a);
227: }
228: #endif
229: #ifdef malloc
230: #undef malloc
231: char *ymalloc(u) unsigned u;
232: { char *p;
233: p = malloc(u);
234: printf("%o %o\n", u, p);
235: return(p);
236: }
237: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.