home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * SFMT.C *scanf()
- *
- * (c)Copyright 1990, Matthew Dillon, All Rights Reserved
- *
- * func format same as fgetc: func(desc)
- * unfunc format same as ungetc: func(c,desc)
- */
-
- #include <stdarg.h>
- #include <stdio.h>
-
- #define F_SPAC 1
- #define F_PLUS 2
- #define F_MINUS 4
- #define F_HASH 8
- #define F_ZERO 16
-
- #define F_SHORT 32
- #define F_LONG 64
- #define F_DLONG 128
-
- int
- _sfmt(ctl, va, func, unfunc, desc, pcnt)
- unsigned char *ctl;
- va_list va;
- int (*func)();
- void (*unfunc)();
- int *pcnt;
- void *desc;
- {
- int error = 0;
- short flags;
- short v;
- short i1;
- void *stor;
-
- *pcnt = 0;
- v = (*func)(desc);
- for (;;) {
- while (*ctl && *ctl != '%') {
- if (*ctl == ' ') {
- if (v != ' ' && v != '\t' && v != '\n')
- goto done;
- while (v == ' ' || v == '\t' || v == '\n')
- v = (*func)(desc);
- while (*ctl == ' ')
- ++ctl;
- } else {
- if (v != *ctl)
- goto done;
- v = (*func)(desc);
- ++ctl;
- }
- if (v == 0)
- goto done;
- }
- if (*ctl++ == 0)
- goto done;
- if (*ctl == '%') { /* match a % */
- if (v != '%')
- goto done;
- v = (*func)(desc);
- ++ctl;
- continue;
- }
-
- /*
- * %[flags][width]c
- */
-
- if (*ctl == '*') {
- stor = NULL;
- ++ctl;
- } else {
- stor = va_arg(va, void *);
- }
- i1 = -1;
- if (*ctl >= '0' && *ctl <= '9') {
- char c = *ctl;
- i1 = 0;
- while (c >= '0' && c <= '9') {
- i1 = i1 * 10 + (c - '0');
- c = *++ctl;
- }
- }
- flags = 0;
- for (;;) {
- char c = *ctl;
- if (c == 'h') {
- ++ctl;
- flags |= F_SHORT; /* only if sizeof(int) != 4 */
- continue;
- }
- if (c == 'l') {
- ++ctl;
- flags |= F_LONG;
- continue;
- }
- if (c == 'L') {
- ++ctl;
- flags |= F_DLONG;
- continue;
- }
- break;
- }
- error = _sfmtone(*ctl++, &v, stor, func, desc, flags, i1);
- if (error)
- break;
- ++*pcnt;
- }
- done:
- if (v != EOF)
- (*unfunc)(v, desc);
-
- if (error && *pcnt == 0)
- return(EOF);
- return(0);
- }
-
- _sfmtone(c, pv, stor, func, desc, flags, i1)
- char c; /* conversion specifier */
- short *pv; /* last read value */
- void *stor; /* pointer into storage */
- int (*func)(); /* fgetc type function */
- void *desc; /* stdio/custom descriptor */
- short flags; /* conversion flags */
- short i1; /* maximum field width */
- {
- short v = *pv;
- int len = 0;
- char buf[32];
- char *ptr = buf;
-
- while (v == ' ' || v == '\t' || v == '\n')
- v = (*func)(desc);
-
- if (i1 == 0)
- return(0);
- if (v == 0 || v == EOF)
- return(EOF);
-
- switch(c) {
- case 'c':
- if (i1 == -1)
- i1 = 1;
- while (v != EOF && v != '\n' && i1) {
- if (stor)
- *(char *)stor = v;
- v = (*func)(desc);
- if (stor)
- stor = (void *)((char *)stor + 1);
- --i1;
- }
- break;
- case 'd':
- case 'u':
- {
- long n = 0;
- short neg = 0;
-
- if (v != '-' && (v < '0' || v > '9'))
- return(EOF);
-
- if (v == '-') {
- neg = 1;
- v = (*func)(desc);
- --i1;
- }
- while (i1 && v >= '0' && v <= '9') {
- n = n * 10 + v - '0';
- v = (*func)(desc);
- --i1;
- }
- if (neg)
- n = -n;
- if (stor)
- *(int *)stor = n;
- }
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- case 'i':
- case 'n':
- break;
- case 'o':
- {
- long n = 0;
- short neg = 0;
-
- if (v != '-' && (v < '0' || v > '7'))
- return(EOF);
- if (v == '-') {
- neg = 1;
- v = (*func)(desc);
- --i1;
- }
- while (i1 && v >= '0' && v <= '7') {
- n = (n << 3) + v - '0';
- v = (*func)(desc);
- --i1;
- }
- if (neg)
- n = -n;
- if (stor)
- *(int *)stor = n;
- }
- break;
- case 'p':
- break;
- case 's':
- while (i1 && v != ' ' && v != '\t' && v != '\n' && v != EOF) {
- if (stor)
- *(char *)stor = v;
- v = (*func)(desc);
- if (stor)
- stor = (void *)((char *)stor + 1);
- --i1;
- }
- if (stor)
- *(char *)stor = 0;
- break;
- case 'x':
- case 'X':
- {
- long n = 0;
- short neg = 0;
- long oldi1 = i1;
-
- if (v == '-') {
- neg = 1;
- v = (*func)(desc);
- --i1;
- }
- while (i1) {
- if (v >= '0' && v <= '9') {
- n = (n << 4) + v - '0';
- } else if (v >= 'a' && v <= 'f') {
- n = (n << 4) + v - 'a' + 10;
- } else if (v >= 'A' && v <= 'F') {
- n = (n << 4) + v - 'A' + 10;
- } else {
- break;
- }
- v = (*func)(desc);
- --i1;
- }
- if (i1 == oldi1) /* nada */
- return(EOF);
- if (neg)
- n = -n;
- if (stor)
- *(int *)stor = n;
- }
- break;
- default:
- return(-2);
- }
- *pv = v;
- return(0);
- }
-
-