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