|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)lib.c 4.7 (Berkeley) 6/25/90";
3: #endif
4:
5: #include "stdio.h"
6: #include "awk.def"
7: #include "awk.h"
8: #include "ctype.h"
9:
10: extern FILE *yyin; /* lex input file */
11: extern char *lexprog; /* points to program argument if it exists */
12: FILE *infile = NULL;
13: char *file;
14: #define RECSIZE (5 * 512)
15: char record[RECSIZE];
16: char fields[RECSIZE];
17: char EMPTY[] = "";
18:
19: #define MAXFLD 100
20: int donefld; /* 1 = implies rec broken into fields */
21: int donerec; /* 1 = record is valid (no flds have changed) */
22: int mustfld; /* 1 = NF seen, so always break*/
23:
24: #define FINIT {EMPTY, EMPTY, 0.0, FLD|STR}
25: cell fldtab[MAXFLD] = { /*room for fields */
26: { "$record", record, 0.0, STR|FLD},
27: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
28: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
29: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
30: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
31: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
32: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
33: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
34: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
35: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
36: };
37: int maxfld = 0; /* last used field */
38:
39:
40: getrec()
41: {
42: register char *rr;
43: extern int svargc;
44: extern char **svargv;
45: register c, sep;
46:
47: dprintf("**RS=%o, **FS=%o\n", **RS, **FS, NULL);
48: donefld = 0;
49: donerec = 1;
50: record[0] = 0;
51: while (svargc > 0) {
52: dprintf("svargc=%d, *svargv=%s\n", svargc, *svargv, NULL);
53: if (infile == NULL) { /* have to open a new file */
54: if (member('=', *svargv)) { /* it's a var=value argument */
55: setclvar(*svargv);
56: svargv++;
57: svargc--;
58: continue;
59: }
60: *FILENAME = file = *svargv;
61: dprintf("opening file %s\n", file, NULL, NULL);
62: if (*file == '-') {
63: if (yyin == stdin && ! lexprog)
64: error(FATAL, "standard input already used for reading commands");
65: else
66: infile = stdin;
67: }
68: else if ((infile = fopen(file, "r")) == NULL)
69: error(FATAL, "can't open %s", file);
70: }
71: if ((sep = **RS) == 0)
72: sep = '\n';
73: for (rr = record; ; ) {
74: for (; (c=getc(infile)) != sep && c != EOF; *rr++ = c)
75: ;
76: if (**RS == sep || c == EOF)
77: break;
78: if ((c = getc(infile)) == '\n' || c == EOF) /* 2 in a row */
79: break;
80: *rr++ = '\n';
81: *rr++ = c;
82: }
83: if (rr > record+RECSIZE)
84: error(FATAL, "record `%.20s...' too long", record);
85: *rr = 0;
86: if (mustfld)
87: fldbld();
88: if (c != EOF || rr > record) { /* normal record */
89: recloc->tval &= ~NUM;
90: recloc->tval |= STR;
91: ++nrloc->fval;
92: nrloc->tval &= ~STR;
93: nrloc->tval |= NUM;
94: return(1);
95: }
96: /* EOF arrived on this file; set up next */
97: if (infile != stdin)
98: fclose(infile);
99: infile = NULL;
100: svargc--;
101: svargv++;
102: }
103: return(0); /* true end of file */
104: }
105:
106: setclvar(s) /* set var=value from s */
107: char *s;
108: {
109: char *p;
110: cell *q;
111:
112: for (p=s; *p != '='; p++)
113: ;
114: *p++ = 0;
115: q = setsymtab(s, tostring(p), 0.0, STR, symtab);
116: setsval(q, p);
117: dprintf("command line set %s to |%s|\n", s, p, NULL);
118: }
119:
120: fldbld()
121: {
122: register char *r, *fr, sep;
123: int i, j;
124:
125: r = record;
126: fr = fields;
127: i = 0; /* number of fields accumulated here */
128: if ((sep = **FS) == ' ')
129: for (i = 0; ; ) {
130: while (*r == ' ' || *r == '\t' || *r == '\n')
131: r++;
132: if (*r == 0)
133: break;
134: i++;
135: if (i >= MAXFLD)
136: error(FATAL, "record `%.20s...' has too many fields", record);
137: if (!(fldtab[i].tval&FLD))
138: strfree(fldtab[i].sval);
139: fldtab[i].sval = fr;
140: fldtab[i].tval = FLD | STR;
141: do
142: *fr++ = *r++;
143: while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0');
144: *fr++ = 0;
145: }
146: else if (*r != 0) /* if 0, it's a null field */
147: for (;;) {
148: i++;
149: if (i >= MAXFLD)
150: error(FATAL, "record `%.20s...' has too many fields", record);
151: if (!(fldtab[i].tval&FLD))
152: strfree(fldtab[i].sval);
153: fldtab[i].sval = fr;
154: fldtab[i].tval = FLD | STR;
155: while (*r != sep && *r != '\n' && *r != '\0') /* \n always a separator */
156: *fr++ = *r++;
157: *fr++ = 0;
158: if (*r++ == 0)
159: break;
160: }
161: *fr = 0;
162: for (j=MAXFLD-1; j>i; j--) { /* clean out junk from previous record */
163: if (!(fldtab[j].tval&FLD))
164: strfree(fldtab[j].sval);
165: fldtab[j].tval = STR | FLD;
166: fldtab[j].sval = EMPTY;
167: }
168: maxfld = i;
169: donefld = 1;
170: for(i=1; i<=maxfld; i++)
171: if(isnumber(fldtab[i].sval)) {
172: fldtab[i].fval = atof(fldtab[i].sval);
173: fldtab[i].tval |= NUM;
174: }
175: setfval(lookup("NF", symtab, 0), (awkfloat) maxfld);
176: if (dbg)
177: for (i = 0; i <= maxfld; i++)
178: printf("field %d: |%s|\n", i, fldtab[i].sval);
179: }
180:
181: recbld()
182: {
183: int i;
184: register char *r, *p;
185:
186: if (donefld == 0 || donerec == 1)
187: return;
188: r = record;
189: for (i = 1; i <= *NF; i++) {
190: p = getsval(&fldtab[i]);
191: while (*r++ = *p++)
192: ;
193: *(r-1) = **OFS;
194: }
195: *(r-1) = '\0';
196: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
197: recloc->tval = STR | FLD;
198: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
199: if (r > record+RECSIZE)
200: error(FATAL, "built giant record `%.20s...'", record);
201: dprintf("recbld = |%s|\n", record, NULL, NULL);
202: }
203:
204: cell *fieldadr(n)
205: {
206: if (n >= MAXFLD)
207: error(FATAL, "trying to access field %d", n);
208: return(&fldtab[n]);
209: }
210:
211: int errorflag = 0;
212:
213: yyerror(s) char *s; {
214: fprintf(stderr, "awk: %s near line %d\n", s, lineno);
215: errorflag = 2;
216: }
217:
218: error(f, s, a1, a2, a3, a4, a5, a6, a7) {
219: fprintf(stderr, "awk: ");
220: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
221: fprintf(stderr, "\n");
222: if (NR && *NR > 0)
223: fprintf(stderr, " record number %g\n", *NR);
224: if (f)
225: exit(2);
226: }
227:
228: PUTS(s) char *s; {
229: dprintf("%s\n", s, NULL, NULL);
230: }
231:
232: #define MAXEXPON 38 /* maximum exponenet for fp number */
233:
234: isnumber(s)
235: register char *s;
236: {
237: register d1, d2;
238: int point;
239: char *es;
240:
241: if (s == NULL)
242: return (0);
243: d1 = d2 = point = 0;
244: while (*s == ' ' || *s == '\t' || *s == '\n')
245: s++;
246: if (*s == '\0')
247: return(0); /* empty stuff isn't number */
248: if (*s == '+' || *s == '-')
249: s++;
250: if (!isdigit(*s) && *s != '.')
251: return(0);
252: if (isdigit(*s)) {
253: do {
254: d1++;
255: s++;
256: } while (isdigit(*s));
257: }
258: if(d1 >= MAXEXPON)
259: return(0); /* too many digits to convert */
260: if (*s == '.') {
261: point++;
262: s++;
263: }
264: if (isdigit(*s)) {
265: d2++;
266: do {
267: s++;
268: } while (isdigit(*s));
269: }
270: if (!(d1 || point && d2))
271: return(0);
272: if (*s == 'e' || *s == 'E') {
273: s++;
274: if (*s == '+' || *s == '-')
275: s++;
276: if (!isdigit(*s))
277: return(0);
278: es = s;
279: do {
280: s++;
281: } while (isdigit(*s));
282: if (s - es > 2)
283: return(0);
284: else if (s - es == 2 && 10 * (*es-'0') + *(es+1)-'0' >= MAXEXPON)
285: return(0);
286: }
287: while (*s == ' ' || *s == '\t' || *s == '\n')
288: s++;
289: if (*s == '\0')
290: return(1);
291: else
292: return(0);
293: }
294: /*
295: isnumber(s) char *s; {return(0);}
296: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.