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