Annotation of 42BSD/bin/as/asscan4.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     Copyright (c) 1982 Regents of the University of California
        !             3:  */
        !             4: #ifndef lint
        !             5: static char sccsid[] = "@(#)asscan4.c 4.4 6/30/83";
        !             6: #endif not lint
        !             7: 
        !             8: #include "asscanl.h"
        !             9: 
        !            10: #define        reg     register
        !            11: #define        NUMSIZE 128     /* how many characters long a number can be */
        !            12: #define        FLTCHAR(x)      (INCHARSET((x),(DIGIT|SIGN|FLOATEXP|POINT)))
        !            13: 
        !            14: static char    numbuf[NUMSIZE];
        !            15: 
        !            16: #define        BACK(backval)   intval = backval; goto stuffback;
        !            17: 
        !            18: int number(ch)
        !            19:        reg     int     ch;
        !            20: {
        !            21:                int     radix;
        !            22:                int     digit;          /* part of number being constructed */
        !            23:        reg     int     intval;         /* number being constructed */
        !            24:        reg     char    *cp;
        !            25:        reg     char    *inbufptr;
        !            26:        reg     int     inbufcnt;
        !            27:                char    ch1;
        !            28:                Bignum  floatnumber();
        !            29:                Ovf     overflow;       /* overflow flag */
        !            30:                int     maxstrlg;
        !            31: 
        !            32:        MEMTOREGBUF;
        !            33:        cp = numbuf;
        !            34:        radix = 10;
        !            35: 
        !            36:        switch(ch){
        !            37:        case '0':
        !            38:                switch(ch = getchar()){
        !            39:                case 'b':
        !            40:                        yylval = -1;
        !            41:                        BACK(BFINT);
        !            42:                case 'f':
        !            43:                        /*
        !            44:                         * Check if it is a local label by peeking ahead
        !            45:                         */
        !            46:                        ch1 = getchar();
        !            47:                        ungetc(ch1);
        !            48:                        if (!FLTCHAR(ch1)){
        !            49:                                yylval = 1;
        !            50:                                BACK(BFINT);
        !            51:                        }
        !            52:                        /*FALLTHROUGH*/
        !            53:                case 'F': ch = 'f';     goto floatnum;
        !            54:                case 'd':
        !            55:                case 'D': ch = 'd';     goto floatnum;
        !            56:                case 'h':
        !            57:                case 'H': ch = 'h';     goto floatnum;
        !            58:                case 'g':
        !            59:                case 'G': ch = 'g';     goto floatnum;
        !            60: 
        !            61:                case 'x':
        !            62:                case 'X':
        !            63:                        ch = '0';
        !            64:                        radix = 16;
        !            65:                        break;
        !            66:                case '0':
        !            67:                case '1': case '2': case '3': case '4':
        !            68:                case '5': case '6': case '7': case '8':
        !            69:                case '9':
        !            70:                        radix = 8;
        !            71:                        break;
        !            72:                default:        /* single 0 */
        !            73:                        ungetc(ch);
        !            74:                        intval = 0;
        !            75:                        goto smallnum;
        !            76:                }
        !            77:                break;
        !            78: 
        !            79:        case '1': case '2': case '3': case '4':
        !            80:        case '5': case '6': case '7': case '8':
        !            81:        case '9':
        !            82:                switch(ch1 = getchar()){
        !            83:                case 'f':
        !            84:                        yylval = ((ch - '0') + 1);
        !            85:                        BACK(BFINT);
        !            86:                case 'b':
        !            87:                        yylval = -((ch - '0') + 1);
        !            88:                        BACK(BFINT);
        !            89:                default:
        !            90:                        ungetc(ch1);    /* put back non zero */
        !            91:                }
        !            92:                radix = 10;
        !            93:                break;
        !            94:        }
        !            95:        intval = 0;
        !            96:        /*
        !            97:         *      There is a character in ch that must be used to
        !            98:         *      cons up the number; we can't ungetc it
        !            99:         */
        !           100:        do{
        !           101:                digit = ch - '0';
        !           102:                switch(radix){
        !           103:                case 8:
        !           104:                        intval <<= 3;
        !           105:                        break;
        !           106:                case 10:
        !           107:                        intval *= 10;
        !           108:                        break;
        !           109:                case 16:
        !           110:                        intval <<= 4;
        !           111:                        if (INCHARSET(ch, HEXLDIGIT)){
        !           112:                                digit = (ch - 'a') + 10;
        !           113:                                break;
        !           114:                        }
        !           115:                        if (INCHARSET(ch, HEXUDIGIT)){
        !           116:                                digit = (ch - 'A') + 10;
        !           117:                                break;
        !           118:                        }
        !           119:                }
        !           120:                *cp++ = ch;
        !           121:                /*
        !           122:                 *      Build a negative number, then negate it
        !           123:                 */
        !           124:                intval -= digit;
        !           125: 
        !           126:                ch = getchar();
        !           127:                if(!INCHARSET(ch, DIGIT)){
        !           128:                        if (radix != 16)
        !           129:                                break;
        !           130:                        if(!INCHARSET(ch, (HEXLDIGIT|HEXUDIGIT)))
        !           131:                                break;
        !           132:                }
        !           133:        } while (1);
        !           134:        ungetc(ch);
        !           135:        *cp = 0;
        !           136:        maxstrlg = cp - numbuf;
        !           137:        /*
        !           138:         *      See if the number is too large for our previous calculation
        !           139:         */
        !           140:        switch(radix){
        !           141:        case 16:
        !           142:                if (maxstrlg > 8)
        !           143:                        goto bignum;
        !           144:                break;
        !           145:        case 10:
        !           146:                if (maxstrlg >= 10)
        !           147:                        goto bignum;
        !           148:                break;
        !           149:        case 8:
        !           150:                if (maxstrlg > 11)
        !           151:                        goto bignum;
        !           152:                if (maxstrlg == 11 && numbuf[0] > 3)
        !           153:                        goto bignum;
        !           154:                break;
        !           155:        }
        !           156:        /*
        !           157:         *      Negate the number
        !           158:         */
        !           159:   smallnum: ;
        !           160:        yylval = -intval;
        !           161:        BACK(INT);
        !           162:   bignum: ;
        !           163:        yybignum = as_atoi(numbuf, radix, &overflow);
        !           164:        BACK(BIGNUM);
        !           165:   floatnum: ;
        !           166:        REGTOMEMBUF;
        !           167:        yybignum = floatnumber(ch);
        !           168:        return(BIGNUM);
        !           169:  stuffback: ;
        !           170:        REGTOMEMBUF;
        !           171:        return(intval);
        !           172: }
        !           173: 
        !           174: #define        TOOLONG \
        !           175:        if (cp == &numbuf[NUMSIZE]){ \
        !           176:                if (passno == 2) \
        !           177:                        yywarning(toolong); \
        !           178:                        goto process; \
        !           179:        }
        !           180: #define        scanit(sign) \
        !           181:        REGTOMEMBUF; \
        !           182:        error |= scanint(sign, &cp); \
        !           183:        MEMTOREGBUF; \
        !           184:        ch = getchar(); \
        !           185:        TOOLONG;
        !           186: 
        !           187: Bignum floatnumber(fltradix)
        !           188:        int     fltradix;
        !           189: {
        !           190:                char    *cp;
        !           191:                int     ch;
        !           192:                char    *toolong = "Floating number too long.";
        !           193:                char    *prologue =
        !           194:                        "Floating 0%c conflicts with exponent %c; choose %c";
        !           195:                /*
        !           196:                 *      This is not implemented yet:
        !           197:                 *      overflow is set on floating overflow.
        !           198:                 */
        !           199:                Ovf     overflow;
        !           200:                int     error;
        !           201:                int     fractOK;
        !           202:        reg     char    *inbufptr;
        !           203:        reg     int     inbufcnt;
        !           204: 
        !           205:        MEMTOREGBUF;
        !           206:        cp = numbuf;
        !           207:        error = 0;
        !           208:        fractOK = 0;
        !           209: 
        !           210:        scanit(1);
        !           211:        if(INCHARSET(ch, POINT)){
        !           212:                fractOK++;
        !           213:                *cp++ = '.';
        !           214:                scanit(0);
        !           215:        }
        !           216:        if(INCHARSET(ch, FLOATEXP)){
        !           217:                fractOK++;
        !           218:                if(ch != fltradix){
        !           219:                        if (passno == 2)
        !           220:                                yywarning(prologue, fltradix, ch, fltradix);
        !           221:                }
        !           222:                switch(fltradix){
        !           223:                case 'd':
        !           224:                case 'f':
        !           225:                        *cp++ = 'e';            /* will be read by atof() */
        !           226:                        break;
        !           227:                default:
        !           228:                        *cp++ = fltradix;       /* will be read by bigatof() */
        !           229:                        break;
        !           230:                }
        !           231:                scanit(1);
        !           232:        }
        !           233:        if (error || fractOK == 0){
        !           234:                yyerror("Badly formatted floating point number.");
        !           235:        }
        !           236:        ungetc(ch);
        !           237:        *cp++ = 0;
        !           238: 
        !           239:   process: ;
        !           240:        switch(fltradix){
        !           241:        case 'f':       fltradix = TYPF;        break;
        !           242:        case 'd':       fltradix = TYPD;        break;
        !           243:        case 'g':       fltradix = TYPG;        nGHnumbers++; break;
        !           244:        case 'h':       fltradix = TYPH;        nGHnumbers++; break;
        !           245:        }
        !           246:        REGTOMEMBUF;
        !           247:        /*
        !           248:         *      The overflow value is lost in the call to as_atof
        !           249:         */
        !           250:        return(as_atof(numbuf, fltradix, &overflow));
        !           251: }
        !           252: /*
        !           253:  *     Scan an optionally signed integer, putting back the lookahead
        !           254:  *     character when finished scanning.
        !           255:  */
        !           256: int scanint(signOK, dstcpp)
        !           257:        int     signOK;
        !           258:        char    **dstcpp;
        !           259: {
        !           260:                int     ch;
        !           261:                int     back = 0;
        !           262:        reg     char    *inbufptr;
        !           263:        reg     int     inbufcnt;
        !           264: 
        !           265:        MEMTOREGBUF;
        !           266:        ch = getchar();
        !           267:        while (INCHARSET(ch, SIGN)){
        !           268:                if (signOK && !back)
        !           269:                        *((*dstcpp)++) = ch;
        !           270:                else
        !           271:                        back = 1;
        !           272:                ch = getchar();
        !           273:        }
        !           274:        while (INCHARSET(ch, DIGIT)){
        !           275:                *((*dstcpp)++) = ch;
        !           276:                ch = getchar();
        !           277:        }
        !           278:        ungetc(ch);
        !           279:        REGTOMEMBUF;
        !           280:        return(back);
        !           281: }

unix.superglobalmegacorp.com

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