Annotation of researchv10no/ncurses/screen/doscan.c, revision 1.1.1.1

1.1       root        1: 
                      2: /*
                      3:  * Alas, doscan is not documented, so people feel they have license to
                      4:  * change the parameters.  The 3B implementation does not even look
                      5:  * callable from C, and without documentation is not comprehensible.
                      6:  * Since many systems have their own doprnt which is written in assembly
                      7:  * language, and thus faster, but callable from C, we try to use the
                      8:  * standard system version where possible.  The ifdefs below attempt
                      9:  * to decide where it is possible - it may need to be updated later.
                     10:  */
                     11: 
                     12: #ifdef u3b
                     13: #define NEEDDOSCAN
                     14: #endif
                     15: 
                     16: #ifdef NEEDDOSCAN
                     17: /*     @(#) doscan.c: 1.1 10/15/83     (1.2    9/29/82)        */
                     18: /*     @(#)doscan.c    2.5     */
                     19: /*LINTLIBRARY*/
                     20: #include <stdio.h>
                     21: #include <ctype.h>
                     22: #include <varargs.h>
                     23: #include <values.h>
                     24: 
                     25: #define NCHARS (1 << BITSPERBYTE)
                     26: 
                     27: extern double atof();
                     28: extern char *memset();
                     29: extern int ungetc();
                     30: 
                     31: int
                     32: _doscan(iop, fmt, va_alist)
                     33: register FILE *iop;
                     34: register unsigned char *fmt;
                     35: va_list va_alist;
                     36: {
                     37:        extern unsigned char *setup();
                     38:        char tab[NCHARS];
                     39:        register int ch;
                     40:        int nmatch = 0, len, inchar, stow, size;
                     41: 
                     42:        /*******************************************************
                     43:         * Main loop: reads format to determine a pattern,
                     44:         *              and then goes to read input stream
                     45:         *              in attempt to match the pattern.
                     46:         *******************************************************/
                     47:        for( ; ; ) {
                     48:                if((ch = *fmt++) == '\0')
                     49:                        return(nmatch); /* end of format */
                     50:                if(isspace(ch)) {
                     51:                        while(isspace(inchar = getc(iop)))
                     52:                                ;
                     53:                        if(ungetc(inchar, iop) != EOF)
                     54:                                continue;
                     55:                        break;
                     56:                }
                     57:                if(ch != '%' || (ch = *fmt++) == '%') {
                     58:                        if((inchar = getc(iop)) == ch)
                     59:                                continue;
                     60:                        if(ungetc(inchar, iop) != EOF)
                     61:                                return(nmatch); /* failed to match input */
                     62:                        break;
                     63:                }
                     64:                if(ch == '*') {
                     65:                        stow = 0;
                     66:                        ch = *fmt++;
                     67:                } else
                     68:                        stow = 1;
                     69: 
                     70:                for(len = 0; isdigit(ch); ch = *fmt++)
                     71:                        len = len * 10 + ch - '0';
                     72:                if(len == 0)
                     73:                        len = MAXINT;
                     74: 
                     75:                if((size = ch) == 'l' || size == 'h')
                     76:                        ch = *fmt++;
                     77:                if(ch == '\0' ||
                     78:                    ch == '[' && (fmt = setup(fmt, tab)) == NULL)
                     79:                        return(EOF); /* unexpected end of format */
                     80:                if(isupper(ch)) { /* no longer documented */
                     81:                        size = 'l';
                     82:                        ch = _tolower(ch);
                     83:                }
                     84:                if(ch != 'c' && ch != '[') {
                     85:                        while(isspace(inchar = getc(iop)))
                     86:                                ;
                     87:                        if(ungetc(inchar, iop) == EOF)
                     88:                                break;
                     89:                }
                     90:                if((size = (ch == 'c' || ch == 's' || ch == '[') ?
                     91:                    string(stow, ch, len, tab, iop, &va_alist) :
                     92:                    number(stow, ch, len, size, iop, &va_alist)) != 0)
                     93:                        nmatch += stow;
                     94:                if(va_alist == NULL) /* end of input */
                     95:                        break;
                     96:                if(size == 0)
                     97:                        return(nmatch); /* failed to match input */
                     98:        }
                     99:        return(nmatch != 0 ? nmatch : EOF); /* end of input */
                    100: }
                    101: 
                    102: /***************************************************************
                    103:  * Functions to read the input stream in an attempt to match incoming
                    104:  * data to the current pattern from the main loop of _doscan().
                    105:  ***************************************************************/
                    106: static int
                    107: number(stow, type, len, size, iop, listp)
                    108: int stow, type, len, size;
                    109: register FILE *iop;
                    110: va_list *listp;
                    111: {
                    112:        char numbuf[64];
                    113:        register char *np = numbuf;
                    114:        register int c, base;
                    115:        int digitseen = 0, dotseen = 0, expseen = 0, floater = 0, negflg = 0;
                    116:        long lcval = 0;
                    117: 
                    118:        switch(type) {
                    119:        case 'e':
                    120:        case 'f':
                    121:        case 'g':
                    122:                floater++;
                    123:        case 'd':
                    124:        case 'u':
                    125:                base = 10;
                    126:                break;
                    127:        case 'o':
                    128:                base = 8;
                    129:                break;
                    130:        case 'x':
                    131:                base = 16;
                    132:                break;
                    133:        default:
                    134:                return(0); /* unrecognized conversion character */
                    135:        }
                    136:        switch(c = getc(iop)) {
                    137:        case '-':
                    138:                negflg++;
                    139:        case '+': /* fall-through */
                    140:                len--;
                    141:                c = getc(iop);
                    142:        }
                    143:        for( ; --len >= 0; *np++ = c, c = getc(iop)) {
                    144:                if(isdigit(c) || base == 16 && isxdigit(c)) {
                    145:                        int digit = c - (isdigit(c) ? '0' :
                    146:                            isupper(c) ? 'A' - 10 : 'a' - 10);
                    147:                        if(digit >= base)
                    148:                                break;
                    149:                        if(stow && !floater)
                    150:                                lcval = base * lcval + digit;
                    151:                        digitseen++;
                    152:                        continue;
                    153:                }
                    154:                if(!floater)
                    155:                        break;
                    156:                if(c == '.' && !dotseen++)
                    157:                        continue;
                    158:                if((c == 'e' || c == 'E') && digitseen && !expseen++) {
                    159:                        *np++ = c;
                    160:                        c = getc(iop);
                    161:                        if(isdigit(c) || c == '+' || c == '-')
                    162:                                continue;
                    163:                }
                    164:                break;
                    165:        }
                    166:        if(stow && digitseen)
                    167:                if(floater) {
                    168:                        register double dval;
                    169:        
                    170:                        *np = '\0';
                    171:                        dval = atof(numbuf);
                    172:                        if(negflg)
                    173:                                dval = -dval;
                    174:                        if(size == 'l')
                    175:                                *va_arg(*listp, double *) = dval;
                    176:                        else
                    177:                                *va_arg(*listp, float *) = (float)dval;
                    178:                } else {
                    179:                        /* suppress possible overflow on 2's-comp negation */
                    180:                        if(negflg && lcval != HIBITL)
                    181:                                lcval = -lcval;
                    182:                        if(size == 'l')
                    183:                                *va_arg(*listp, long *) = lcval;
                    184:                        else if(size == 'h')
                    185:                                *va_arg(*listp, short *) = (short)lcval;
                    186:                        else
                    187:                                *va_arg(*listp, int *) = (int)lcval;
                    188:                }
                    189:        if(ungetc(c, iop) == EOF)
                    190:                *listp = NULL; /* end of input */
                    191:        return(digitseen); /* successful match if non-zero */
                    192: }
                    193: 
                    194: static int
                    195: string(stow, type, len, tab, iop, listp)
                    196: register int stow, type, len;
                    197: register char *tab;
                    198: register FILE *iop;
                    199: va_list *listp;
                    200: {
                    201:        register int ch;
                    202:        register char *ptr;
                    203:        char *start;
                    204: 
                    205:        start = ptr = stow ? va_arg(*listp, char *) : NULL;
                    206:        if(type == 'c' && len == MAXINT)
                    207:                len = 1;
                    208:        while((ch = getc(iop)) != EOF &&
                    209:            !(type == 's' && isspace(ch) || type == '[' && tab[ch])) {
                    210:                if(stow)
                    211:                        *ptr = ch;
                    212:                ptr++;
                    213:                if(--len <= 0)
                    214:                        break;
                    215:        }
                    216:        if(ch == EOF || len > 0 && ungetc(ch, iop) == EOF)
                    217:                *listp = NULL; /* end of input */
                    218:        if(ptr == start)
                    219:                return(0); /* no match */
                    220:        if(stow && type != 'c')
                    221:                *ptr = '\0';
                    222:        return(1); /* successful match */
                    223: }
                    224: 
                    225: static unsigned char *
                    226: setup(fmt, tab)
                    227: register unsigned char *fmt;
                    228: register char *tab;
                    229: {
                    230:        register int b, c, d, t = 0;
                    231: 
                    232:        if(*fmt == '^') {
                    233:                t++;
                    234:                fmt++;
                    235:        }
                    236:        (void)memset(tab, !t, NCHARS);
                    237:        if((c = *fmt) == ']' || c == '-') { /* first char is special */
                    238:                tab[c] = t;
                    239:                fmt++;
                    240:        }
                    241:        while((c = *fmt++) != ']') {
                    242:                if(c == '\0')
                    243:                        return(NULL); /* unexpected end of format */
                    244:                if(c == '-' && (d = *fmt) != ']' && (b = fmt[-2]) < d) {
                    245:                        (void)memset(&tab[b], t, d - b);
                    246:                        fmt++;
                    247:                } else
                    248:                        tab[c] = t;
                    249:        }
                    250:        return(fmt);
                    251: }
                    252: #else
                    253: /* This is just to keep from getting a diagnostic from ranlib. */
                    254: __dsdummy__()
                    255: {
                    256: }
                    257: #endif NEEDDOSCAN

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.