|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)tran.c 4.5 10/22/87";
3: #endif
4:
5: #include "stdio.h"
6: #include "awk.def"
7: #include "awk.h"
8:
9: cell *symtab[MAXSYM]; /* symbol table pointers */
10:
11: char **FS; /* initial field sep */
12: char **RS; /* initial record sep */
13: char **OFS; /* output field sep */
14: char **ORS; /* output record sep */
15: char **OFMT; /*output format for numbers*/
16: awkfloat *NF; /* number of fields in current record */
17: awkfloat *NR; /* number of current record */
18: char **FILENAME; /* current filename argument */
19:
20: cell *recloc; /* location of record */
21: cell *nrloc; /* NR */
22: cell *nfloc; /* NF */
23:
24: syminit()
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;
36: FILENAME = &setsymtab("FILENAME", EMPTY, 0.0, STR|FLD, symtab)->sval;
37: nfloc = setsymtab("NF", EMPTY, 0.0, NUM, symtab);
38: NF = &nfloc->fval;
39: nrloc = setsymtab("NR", EMPTY, 0.0, NUM, symtab);
40: NR = &nrloc->fval;
41: }
42:
43: cell **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:
56: freesymtab(ap) /* free symbol table */
57: cell *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) {
67: strfree(cp->nval);
68: strfree(cp->sval);
69: free(cp);
70: }
71: }
72: xfree(tp);
73: }
74:
75: cell *setsymtab(n, s, f, t, tab)
76: char *n, *s;
77: awkfloat f;
78: unsigned t;
79: cell **tab;
80: {
81: register h;
82: register cell *p;
83: cell *lookup();
84:
85: if (n != NULL && (p = lookup(n, tab, 0)) != NULL) {
86: if (s != EMPTY ) xfree(s); /* careful here */
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:
106: hash(s) /* form hash value for string s */
107: register unsigned char *s;
108: {
109: register int hashval;
110:
111: for (hashval = 0; *s != '\0'; )
112: hashval += *s++;
113: return(hashval % MAXSYM);
114: }
115:
116: cell *lookup(s, tab, flag) /* look for s in tab, flag must match*/
117: register char *s;
118: cell **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:
129: awkfloat setfval(vp, f)
130: register cell *vp;
131: awkfloat 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 */
139: if ((vp->tval & FLD) && isnull(vp->nval))
140: donerec = 0;
141: return(vp->fval = f);
142: }
143:
144: char *setsval(vp, s)
145: register cell *vp;
146: char *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;
154: if ((vp->tval & FLD) && isnull(vp->nval))
155: donerec = 0;
156: if (!(vp->tval&FLD))
157: strfree(vp->sval);
158: vp->tval &= ~FLD;
159: return(vp->sval = tostring(s));
160: }
161:
162: awkfloat getfval(vp)
163: register 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:
187: char *getsval(vp)
188: register 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))
198: strfree(vp->sval);
199: if ((long)vp->fval==vp->fval)
200: (void)sprintf(s, "%.20g", vp->fval);
201: else
202: (void)sprintf(s, *OFMT, vp->fval);
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:
211: checkval(vp)
212: register 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:
221: char *tostring(s)
222: register char *s;
223: {
224: register char *p;
225:
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: }
237: return(p);
238: }
239: #ifndef yfree
240: yfree(a) char *a;
241: {
242: printf("%o\n", a);
243: free(a);
244: }
245: #endif
246: #ifdef malloc
247: #undef malloc
248: char *ymalloc(u) unsigned u;
249: { char *p;
250: p = malloc(u);
251: printf("%o %o\n", u, p);
252: return(p);
253: }
254: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.