BSD 4_1c_2 release
[unix-history] / usr / src / lib / libc / stdio / doscan.c
CommitLineData
e804469b 1static char sccsid[] = "@(#)doscan.c 4.2 (Berkeley) 82/12/03";
87bdee5f
KM
2
3/* @(#)doscan.c 4.1 (Berkeley) 12/21/80 */
4#include <stdio.h>
5#include <ctype.h>
6
7#define SPC 01
8#define STP 02
9
10#define SHORT 0
11#define REGULAR 1
12#define LONG 2
13#define INT 0
14#define FLOAT 1
15
16char *_getccl();
17
18char _sctab[128] = {
19 0,0,0,0,0,0,0,0,
20 0,SPC,SPC,0,0,0,0,0,
21 0,0,0,0,0,0,0,0,
22 0,0,0,0,0,0,0,0,
23 SPC,0,0,0,0,0,0,0,
24 0,0,0,0,0,0,0,0,
25 0,0,0,0,0,0,0,0,
26 0,0,0,0,0,0,0,0,
27};
28
29_doscan(iop, fmt, argp)
30FILE *iop;
31register char *fmt;
32register int **argp;
33{
34 register int ch;
35 int nmatch, len, ch1;
36 int **ptr, fileended, size;
37
38 nmatch = 0;
39 fileended = 0;
40 for (;;) switch (ch = *fmt++) {
41 case '\0':
42 return (nmatch);
43 case '%':
44 if ((ch = *fmt++) == '%')
45 goto def;
46 ptr = 0;
47 if (ch != '*')
48 ptr = argp++;
49 else
50 ch = *fmt++;
51 len = 0;
52 size = REGULAR;
53 while (isdigit(ch)) {
54 len = len*10 + ch - '0';
55 ch = *fmt++;
56 }
57 if (len == 0)
58 len = 30000;
59 if (ch=='l') {
60 size = LONG;
61 ch = *fmt++;
62 } else if (ch=='h') {
63 size = SHORT;
64 ch = *fmt++;
65 } else if (ch=='[')
66 fmt = _getccl(fmt);
67 if (isupper(ch)) {
68 ch = tolower(ch);
69 size = LONG;
70 }
71 if (ch == '\0')
72 return(-1);
73 if (_innum(ptr, ch, len, size, iop, &fileended) && ptr)
74 nmatch++;
75 if (fileended)
76 return(nmatch? nmatch: -1);
77 break;
78
79 case ' ':
80 case '\n':
81 case '\t':
82 while ((ch1 = getc(iop))==' ' || ch1=='\t' || ch1=='\n')
83 ;
84 if (ch1 != EOF)
85 ungetc(ch1, iop);
86 break;
87
88 default:
89 def:
90 ch1 = getc(iop);
91 if (ch1 != ch) {
92 if (ch1==EOF)
93 return(-1);
94 ungetc(ch1, iop);
95 return(nmatch);
96 }
97 }
98}
99
100_innum(ptr, type, len, size, iop, eofptr)
101int **ptr, *eofptr;
102struct _iobuf *iop;
103{
104 extern double atof();
105 register char *np;
106 char numbuf[64];
107 register c, base;
108 int expseen, scale, negflg, c1, ndigit;
109 long lcval;
110
111 if (type=='c' || type=='s' || type=='[')
112 return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr));
113 lcval = 0;
114 ndigit = 0;
115 scale = INT;
116 if (type=='e'||type=='f')
117 scale = FLOAT;
118 base = 10;
119 if (type=='o')
120 base = 8;
121 else if (type=='x')
122 base = 16;
123 np = numbuf;
124 expseen = 0;
125 negflg = 0;
126 while ((c = getc(iop))==' ' || c=='\t' || c=='\n');
127 if (c=='-') {
128 negflg++;
129 *np++ = c;
130 c = getc(iop);
131 len--;
132 } else if (c=='+') {
133 len--;
134 c = getc(iop);
135 }
136 for ( ; --len>=0; *np++ = c, c = getc(iop)) {
137 if (isdigit(c)
138 || base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) {
139 ndigit++;
140 if (base==8)
141 lcval <<=3;
142 else if (base==10)
143 lcval = ((lcval<<2) + lcval)<<1;
144 else
145 lcval <<= 4;
146 c1 = c;
147 if (isdigit(c))
148 c -= '0';
149 else if ('a'<=c && c<='f')
150 c -= 'a'-10;
151 else
152 c -= 'A'-10;
153 lcval += c;
154 c = c1;
155 continue;
156 } else if (c=='.') {
157 if (base!=10 || scale==INT)
158 break;
159 ndigit++;
160 continue;
161 } else if ((c=='e'||c=='E') && expseen==0) {
162 if (base!=10 || scale==INT || ndigit==0)
163 break;
164 expseen++;
165 *np++ = c;
166 c = getc(iop);
167 if (c!='+'&&c!='-'&&('0'>c||c>'9'))
168 break;
169 } else
170 break;
171 }
172 if (negflg)
173 lcval = -lcval;
174 if (c != EOF) {
175 ungetc(c, iop);
176 *eofptr = 0;
177 } else
178 *eofptr = 1;
8ed00122 179 if (ptr==NULL || np==numbuf || (negflg && np==numbuf+1) )/* gene dykes*/
87bdee5f
KM
180 return(0);
181 *np++ = 0;
182 switch((scale<<4) | size) {
183
184 case (FLOAT<<4) | SHORT:
185 case (FLOAT<<4) | REGULAR:
186 **(float **)ptr = atof(numbuf);
187 break;
188
189 case (FLOAT<<4) | LONG:
190 **(double **)ptr = atof(numbuf);
191 break;
192
193 case (INT<<4) | SHORT:
194 **(short **)ptr = lcval;
195 break;
196
197 case (INT<<4) | REGULAR:
198 **(int **)ptr = lcval;
199 break;
200
201 case (INT<<4) | LONG:
202 **(long **)ptr = lcval;
203 break;
204 }
205 return(1);
206}
207
208_instr(ptr, type, len, iop, eofptr)
209register char *ptr;
210register struct _iobuf *iop;
211int *eofptr;
212{
213 register ch;
214 register char *optr;
215 int ignstp;
216
217 *eofptr = 0;
218 optr = ptr;
219 if (type=='c' && len==30000)
220 len = 1;
221 ignstp = 0;
222 if (type=='s')
223 ignstp = SPC;
224 while (_sctab[ch = getc(iop)] & ignstp)
225 if (ch==EOF)
226 break;
227 ignstp = SPC;
228 if (type=='c')
229 ignstp = 0;
230 else if (type=='[')
231 ignstp = STP;
232 while (ch!=EOF && (_sctab[ch]&ignstp)==0) {
233 if (ptr)
234 *ptr++ = ch;
235 if (--len <= 0)
236 break;
237 ch = getc(iop);
238 }
239 if (ch != EOF) {
240 if (len > 0)
241 ungetc(ch, iop);
242 *eofptr = 0;
243 } else
244 *eofptr = 1;
245 if (ptr && ptr!=optr) {
246 if (type!='c')
247 *ptr++ = '\0';
248 return(1);
249 }
250 return(0);
251}
252
253char *
254_getccl(s)
255register char *s;
256{
257 register c, t;
258
259 t = 0;
260 if (*s == '^') {
261 t++;
262 s++;
263 }
264 for (c = 0; c < 128; c++)
265 if (t)
266 _sctab[c] &= ~STP;
267 else
268 _sctab[c] |= STP;
269 while (((c = *s++)&0177) != ']') {
270 if (t)
271 _sctab[c++] |= STP;
272 else
273 _sctab[c++] &= ~STP;
274 if (c==0)
275 return(--s);
276 }
277 return(s);
278}