Commit | Line | Data |
---|---|---|
d1e7adee TL |
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 |