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

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

unix.superglobalmegacorp.com

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