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