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