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