00001
00007
00008
00009
00010
00011 #include <ctype.h>
00012
00013 #define EOF (-2)
00014 #define NULL 0
00015
00016 #define SPC 01
00017 #define STP 02
00018
00019 #define SHORT 0
00020 #define REGULAR 1
00021 #define LONG 2
00022
00023 int _innum(int **, int, int, int, int (*)(), int (*)(), int, int, int *);
00024 int _instr(register char *, int, int, int (*)(), int (*)(), int, int, int *);
00025 char *_getccl(char *);
00026
00027 char _sctab[128] = {
00028 0,0,0,0,0,0,0,0,
00029 0,SPC,SPC,0,0,0,0,0,
00030 0,0,0,0,0,0,0,0,
00031 0,0,0,0,0,0,0,0,
00032 SPC,0,0,0,0,0,0,0,
00033 0,0,0,0,0,0,0,0,
00034 0,0,0,0,0,0,0,0,
00035 0,0,0,0,0,0,0,0,
00036 };
00037
00047 int _doscan(register char *fmt, register int **argp, int (*getch)(), int (*ungetch)(), int arg1, int arg2)
00048 {
00049 register int ch;
00050 int nmatch, len, ch1;
00051 int **ptr, fileended, size;
00052
00053 nmatch = 0;
00054 fileended = 0;
00055 for (;;)
00056 {
00057 switch (ch = *fmt++)
00058 {
00059 case '\0':
00060 return (nmatch);
00061 case '%':
00062 if ((ch = *fmt++) == '%')
00063 { goto def; }
00064 ptr = 0;
00065 if (ch != '*')
00066 { ptr = argp++; }
00067 else
00068 { ch = *fmt++; }
00069 len = 0;
00070 size = REGULAR;
00071 while (isdigit(ch))
00072 {
00073 len = len*10 + ch - '0';
00074 ch = *fmt++;
00075 }
00076 if (len == 0)
00077 { len = 30000; }
00078 if (ch=='l')
00079 {
00080 ch = *fmt++;
00081 size = LONG;
00082 }
00083 else if (ch=='h')
00084 {
00085 size = SHORT;
00086 ch = *fmt++;
00087 }
00088 else if (ch=='[')
00089 { fmt = _getccl(fmt); }
00090 if (isupper(ch))
00091 {
00092 ch = tolower(ch);
00093 size = LONG;
00094 }
00095 if (ch == '\0')
00096 { return (-1); }
00097 if (_innum(ptr, ch, len, size, getch, ungetch, arg1, arg2, &fileended) && ptr)
00098 { nmatch++; }
00099 if (fileended)
00100 { return (nmatch? nmatch: -1); }
00101 break;
00102
00103 case ' ':
00104 case '\n':
00105 case '\t':
00106 while ((ch1 = (*getch)(arg1, arg2))==' ' || ch1=='\t' || ch1=='\n')
00107 { ; }
00108 if (ch1 != EOF)
00109 { (*ungetch)(arg1, arg2); }
00110 break;
00111
00112 default:
00113 def:
00114 ch1 = (*getch)(arg1, arg2);
00115 if (ch1 != ch)
00116 {
00117 if (ch1==EOF)
00118 { return (-1); }
00119 (*ungetch)(arg1, arg2);
00120 return nmatch;
00121 }
00122 }
00123 }
00124 }
00125
00126 int _innum(int **ptr, int type, int len, int size, int (*getch)(), int (*ungetch)(), int arg1, int arg2, int *eofptr)
00127 {
00128 extern double atof(char *p);
00129 register char *np;
00130 char numbuf[64];
00131 register char c, base;
00132 int expseen, negflg, c1, ndigit;
00133 long lcval;
00134
00135 if (type=='c' || type=='s' || type=='[')
00136 {
00137 return(_instr(ptr? *(char **)ptr: (char *)NULL, type,
00138 len, getch, ungetch, arg1, arg2, eofptr));
00139 }
00140 lcval = 0;
00141 ndigit = 0;
00142 base = 10;
00143 if (type=='o')
00144 { base = 8; }
00145 else if (type=='x')
00146 { base = 16; }
00147 np = numbuf;
00148 expseen = 0;
00149 negflg = 0;
00150 while ((c = (*getch)(arg1, arg2))==' ' || c=='\t' || c=='\n')
00151 { ; }
00152 if (c=='-')
00153 {
00154 negflg++;
00155 *np++ = c;
00156 c = (*getch)(arg1, arg2);
00157 len--;
00158 }
00159 else if (c=='+')
00160 {
00161 len--;
00162 c = (*getch)(arg1, arg2);
00163 }
00164
00165 for ( ; --len>=0; *np++ = c, c = (*getch)(arg1, arg2))
00166 {
00167 if (((isdigit(c)) || base==16) && (('a'<=c && c<='f') || ('A'<=c && c<='F')))
00168 {
00169 ndigit++;
00170 if (base==8)
00171 { lcval <<=3; }
00172 else if (base==10)
00173 { lcval = ((lcval<<2) + lcval)<<1; }
00174 else
00175 { lcval <<= 4; }
00176 c1 = c;
00177 if ('0'<=c && c<='9')
00178 { c -= '0'; }
00179 else if ('a'<=c && c<='f')
00180 { c -= 'a'-10; }
00181 else
00182 { c -= 'A'-10; }
00183 lcval += c;
00184 c = c1;
00185 continue;
00186 }
00187 else
00188 { break; }
00189 }
00190 if (negflg)
00191 { lcval = -lcval; }
00192 if (c != EOF)
00193 {
00194 (*ungetch)(arg1, arg2);
00195 *eofptr = 0;
00196 }
00197 else
00198 { *eofptr = 1; }
00199 if (ptr==NULL || np==numbuf)
00200 { return 0; }
00201 *np++ = 0;
00202 switch(size)
00203 {
00204 case SHORT:
00205 **(short **)ptr = lcval;
00206 break;
00207
00208 case REGULAR:
00209 **(int **)ptr = lcval;
00210 break;
00211
00212 case LONG:
00213 **(long **)ptr = lcval;
00214 break;
00215 }
00216 return 1;
00217 }
00218
00219 int _instr(register char *ptr, int type, int len, int (*getch)(), int (*ungetch)(), int arg1, int arg2, int *eofptr)
00220 {
00221 register unsigned int ch;
00222 register char *optr;
00223 int ignstp;
00224
00225 *eofptr = 0;
00226 optr = ptr;
00227 if (type=='c' && len==30000)
00228 { len = 1; }
00229 ignstp = 0;
00230 if (type=='s')
00231 { ignstp = SPC; }
00232 while (_sctab[ch = (*getch)(arg1, arg2)] & ignstp)
00233 {
00234 if (ch==EOF)
00235 { break; }
00236 }
00237 ignstp = SPC;
00238 if (type=='c')
00239 { ignstp = 0; }
00240 else if (type=='[')
00241 { ignstp = STP; }
00242 while (ch!=EOF && (_sctab[ch]&ignstp)==0)
00243 {
00244 if (ptr)
00245 { *ptr++ = ch; }
00246 if (--len <= 0)
00247 { break; }
00248 ch = (*getch)(arg1, arg2);
00249 }
00250 if (ch != EOF)
00251 {
00252 if (len > 0)
00253 { (*ungetch)(arg1, arg2); }
00254 *eofptr = 0;
00255 }
00256 else
00257 { *eofptr = 1; }
00258 if (ptr && ptr!=optr)
00259 {
00260 if (type!='c')
00261 { *ptr++ = '\0'; }
00262 return 1;
00263 }
00264 return 0;
00265 }
00266
00267 char *_getccl(char *s)
00268 {
00269 int c, t;
00270
00271 t = 0;
00272 if (*s == '^')
00273 {
00274 t++;
00275 s++;
00276 }
00277 for (c = 0; c < 128; c++)
00278 {
00279 if (t)
00280 { _sctab[c] &= ~STP; }
00281 else
00282 { _sctab[c] |= STP; }
00283 }
00284 while (((c = *s++)&0177) != ']')
00285 {
00286 if (t)
00287 { _sctab[c++] |= STP; }
00288 else
00289 { _sctab[c++] &= ~STP; }
00290 if (c==0)
00291 { return (--s); }
00292 }
00293 return s;
00294 }