Annotation of 43BSD/bin/as/asscan4.c, revision 1.1.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.