ignore SIGTTOU while resetting on TSTP (else can stop before reset
[unix-history] / usr / src / old / awk / lib.c
CommitLineData
b803c326
SL
1#ifndef lint
2static char sccsid[] = "@(#)lib.c 4.3 %G%";
3#endif
b9bbf539
KM
4
5#include "stdio.h"
6#include "awk.def"
7#include "awk.h"
8#include "ctype.h"
9
10FILE *infile = NULL;
11char *file;
12#define RECSIZE (5 * 512)
13char record[RECSIZE];
14char fields[RECSIZE];
c48090b0 15char EMPTY[] = "";
b9bbf539
KM
16
17#define MAXFLD 100
18int donefld; /* 1 = implies rec broken into fields */
19int donerec; /* 1 = record is valid (no flds have changed) */
20int mustfld; /* 1 = NF seen, so always break*/
21
c48090b0 22#define FINIT {EMPTY, EMPTY, 0.0, FLD|STR}
b9bbf539
KM
23cell 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};
33int maxfld = 0; /* last used field */
34
35
36getrec()
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
98setclvar(s) /* set var=value from s */
99char *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
112fldbld()
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))
c48090b0 130 strfree(fldtab[i].sval);
b9bbf539
KM
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))
c48090b0 144 strfree(fldtab[i].sval);
b9bbf539
KM
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))
c48090b0 156 strfree(fldtab[j].sval);
b9bbf539 157 fldtab[j].tval = STR | FLD;
c48090b0 158 fldtab[j].sval = EMPTY;
b9bbf539
KM
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
173recbld()
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
196cell *fieldadr(n)
197{
198 if (n >= MAXFLD)
199 error(FATAL, "trying to access field %d", n);
200 return(&fldtab[n]);
201}
202
203int errorflag = 0;
204
205yyerror(s) char *s; {
206 fprintf(stderr, "awk: %s near line %d\n", s, lineno);
207 errorflag = 2;
208}
209
210error(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 > 0)
215 fprintf(stderr, " record number %g\n", *NR);
216 if (f)
217 exit(2);
218}
219
220PUTS(s) char *s; {
221 dprintf("%s\n", s, NULL, NULL);
222}
223
224#define MAXEXPON 38 /* maximum exponenet for fp number */
225
226isnumber(s)
227register char *s;
228{
229 register d1, d2;
230 int point;
231 char *es;
232
c48090b0
SL
233 if (s == NULL)
234 return (0);
b9bbf539
KM
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/*
287isnumber(s) char *s; {return(0);}
288*/