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