Bell 32V development
[unix-history] / usr / src / cmd / awk / tran.c
CommitLineData
d1e7adee
TL
1#include "stdio.h"
2#include "awk.def"
3#include "awk.h"
4
5cell *symtab[MAXSYM]; /* symbol table pointers */
6
7char **FS; /* initial field sep */
8char **RS; /* initial record sep */
9char **OFS; /* output field sep */
10char **ORS; /* output record sep */
11char **OFMT; /*output format for numbers*/
12awkfloat *NF; /* number of fields in current record */
13awkfloat *NR; /* number of current record */
14char **FILENAME; /* current filename argument */
15
16cell *recloc; /* location of record */
17cell *nrloc; /* NR */
18cell *nfloc; /* NF */
19
20syminit()
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
37cell **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
50freesymtab(ap) /* free symbol table */
51cell *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
69cell *setsymtab(n, s, f, t, tab)
70char *n, *s;
71awkfloat f;
72unsigned t;
73cell **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
100hash(s) /* form hash value for string s */
101register char *s;
102{
103 register int hashval;
104
105 for (hashval = 0; *s != '\0'; )
106 hashval += *s++;
107 return(hashval % MAXSYM);
108}
109
110cell *lookup(s, tab) /* look for s in tab */
111register char *s;
112cell **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
122awkfloat setfval(vp, f)
123register cell *vp;
124awkfloat 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
137char *setsval(vp, s)
138register cell *vp;
139char *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
155awkfloat getfval(vp)
156register 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
177char *getsval(vp)
178register 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
201checkval(vp)
202register 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
211char *tostring(s)
212register 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
223yfree(a) char *a;
224{
225 printf("%o\n", a);
226 free(a);
227}
228#endif
229#ifdef malloc
230#undef malloc
231char *ymalloc(u) unsigned u;
232{ char *p;
233 p = malloc(u);
234 printf("%o %o\n", u, p);
235 return(p);
236}
237#endif