Commit | Line | Data |
---|---|---|
e804469b | 1 | static 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 | ||
16 | char *_getccl(); | |
17 | ||
18 | char _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) | |
30 | FILE *iop; | |
31 | register char *fmt; | |
32 | register 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) | |
101 | int **ptr, *eofptr; | |
102 | struct _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) | |
209 | register char *ptr; | |
210 | register struct _iobuf *iop; | |
211 | int *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 | ||
253 | char * | |
254 | _getccl(s) | |
255 | register 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 | } |