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