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