1 static char sccsid[] = "@(#)vfscanf.c 4.2 (Berkeley) 82/12/03"; 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; 179 if (ptr==NULL || np==numbuf || (negflg && np==numbuf+1) )/* gene dykes*/ 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 } 279