Annotation of researchv10no/ncurses/screen/doscan.c, revision 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.