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