Annotation of 43BSDReno/pgrm/as.tahoe/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: 
                     57:                case 'x':
                     58:                case 'X':
                     59:                        ch = '0';
                     60:                        radix = 16;
                     61:                        break;
                     62:                case '0':
                     63:                case '1': case '2': case '3': case '4':
                     64:                case '5': case '6': case '7': case '8':
                     65:                case '9':
                     66:                        radix = 8;
                     67:                        break;
                     68:                default:        /* single 0 */
                     69:                        ungetc(ch);
                     70:                        intval = 0;
                     71:                        goto smallnum;
                     72:                }
                     73:                break;
                     74: 
                     75:        case '1': case '2': case '3': case '4':
                     76:        case '5': case '6': case '7': case '8':
                     77:        case '9':
                     78:                switch(ch1 = getchar()){
                     79:                case 'f':
                     80:                        yylval = ((ch - '0') + 1);
                     81:                        BACK(BFINT);
                     82:                case 'b':
                     83:                        yylval = -((ch - '0') + 1);
                     84:                        BACK(BFINT);
                     85:                default:
                     86:                        ungetc(ch1);    /* put back non zero */
                     87:                }
                     88:                radix = 10;
                     89:                break;
                     90:        }
                     91:        intval = 0;
                     92:        /*
                     93:         *      There is a character in ch that must be used to
                     94:         *      cons up the number; we can't ungetc it
                     95:         */
                     96:        do{
                     97:                digit = ch - '0';
                     98:                switch(radix){
                     99:                case 8:
                    100:                        intval <<= 3;
                    101:                        break;
                    102:                case 10:
                    103:                        intval *= 10;
                    104:                        break;
                    105:                case 16:
                    106:                        intval <<= 4;
                    107:                        if (INCHARSET(ch, HEXLDIGIT)){
                    108:                                digit = (ch - 'a') + 10;
                    109:                                break;
                    110:                        }
                    111:                        if (INCHARSET(ch, HEXUDIGIT)){
                    112:                                digit = (ch - 'A') + 10;
                    113:                                break;
                    114:                        }
                    115:                }
                    116:                *cp++ = ch;
                    117:                /*
                    118:                 *      Build a negative number, then negate it
                    119:                 */
                    120:                intval -= digit;
                    121: 
                    122:                ch = getchar();
                    123:                if(!INCHARSET(ch, DIGIT)){
                    124:                        if (radix != 16)
                    125:                                break;
                    126:                        if(!INCHARSET(ch, (HEXLDIGIT|HEXUDIGIT)))
                    127:                                break;
                    128:                }
                    129:        } while (1);
                    130:        ungetc(ch);
                    131:        *cp = 0;
                    132:        maxstrlg = cp - numbuf;
                    133:        /*
                    134:         *      See if the number is too large for our previous calculation
                    135:         */
                    136:        switch(radix){
                    137:        case 16:
                    138:                if (maxstrlg > 8)
                    139:                        goto bignum;
                    140:                break;
                    141:        case 10:
                    142:                if (maxstrlg >= 10)
                    143:                        goto bignum;
                    144:                break;
                    145:        case 8:
                    146:                if (maxstrlg > 11)
                    147:                        goto bignum;
                    148:                if (maxstrlg == 11 && numbuf[0] > 3)
                    149:                        goto bignum;
                    150:                break;
                    151:        }
                    152:        /*
                    153:         *      Negate the number
                    154:         */
                    155:   smallnum: ;
                    156:        yylval = -intval;
                    157:        BACK(INT);
                    158:   bignum: ;
                    159:        yybignum = as_atoi(numbuf, radix, &overflow);
                    160:        BACK(BIGNUM);
                    161:   floatnum: ;
                    162:        REGTOMEMBUF;
                    163:        yybignum = floatnumber(ch);
                    164:        return(BIGNUM);
                    165:  stuffback: ;
                    166:        REGTOMEMBUF;
                    167:        return(intval);
                    168: }
                    169: 
                    170: #define        TOOLONG \
                    171:        if (cp == &numbuf[NUMSIZE]){ \
                    172:                if (passno == 2) \
                    173:                        yywarning(toolong); \
                    174:                        goto process; \
                    175:        }
                    176: #define        scanit(sign) \
                    177:        REGTOMEMBUF; \
                    178:        error |= scanint(sign, &cp); \
                    179:        MEMTOREGBUF; \
                    180:        ch = getchar(); \
                    181:        TOOLONG;
                    182: 
                    183: Bignum floatnumber(fltradix)
                    184:        int     fltradix;
                    185: {
                    186:                int     tag;
                    187:                char    *cp;
                    188:                int     ch;
                    189:                char    *toolong = "Floating number too long.";
                    190:                char    *prologue =
                    191:                        "Floating 0%c conflicts with exponent %c; choose %c";
                    192:                /*
                    193:                 *      This is not implemented yet:
                    194:                 *      overflow is set on floating overflow.
                    195:                 */
                    196:                Ovf     overflow;
                    197:                int     error;
                    198:                int     fractOK;
                    199:        reg     char    *inbufptr;
                    200:        reg     int     inbufcnt;
                    201: 
                    202:        MEMTOREGBUF;
                    203:        cp = numbuf;
                    204:        error = 0;
                    205:        fractOK = 0;
                    206: 
                    207:        scanit(1);
                    208:        if(INCHARSET(ch, POINT)){
                    209:                fractOK++;
                    210:                *cp++ = '.';
                    211:                scanit(0);
                    212:        }
                    213:        if(INCHARSET(ch, FLOATEXP)){
                    214:                fractOK++;
                    215:                if(ch != fltradix){
                    216:                        if (passno == 2)
                    217:                                yywarning(prologue, fltradix, ch, fltradix);
                    218:                }
                    219:                switch(fltradix){
                    220:                case 'd':
                    221:                        tag = TYPD;
                    222:                        *cp++ = 'e';            /* will be read by atof() */
                    223:                        break;
                    224:                case 'f':
                    225:                        tag = TYPF;
                    226:                        *cp++ = 'e';            /* will be read by atof() */
                    227:                        break;
                    228:                default:
                    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:        REGTOMEMBUF;
                    241:        return(as_atof(numbuf, tag));
                    242: }
                    243: /*
                    244:  *     Scan an optionally signed integer, putting back the lookahead
                    245:  *     character when finished scanning.
                    246:  */
                    247: int scanint(signOK, dstcpp)
                    248:        int     signOK;
                    249:        char    **dstcpp;
                    250: {
                    251:                int     ch;
                    252:                int     back = 0;
                    253:        reg     char    *inbufptr;
                    254:        reg     int     inbufcnt;
                    255: 
                    256:        MEMTOREGBUF;
                    257:        ch = getchar();
                    258:        while (INCHARSET(ch, SIGN)){
                    259:                if (signOK && !back)
                    260:                        *((*dstcpp)++) = ch;
                    261:                else
                    262:                        back = 1;
                    263:                ch = getchar();
                    264:        }
                    265:        while (INCHARSET(ch, DIGIT)){
                    266:                *((*dstcpp)++) = ch;
                    267:                ch = getchar();
                    268:        }
                    269:        ungetc(ch);
                    270:        REGTOMEMBUF;
                    271:        return(back);
                    272: }

unix.superglobalmegacorp.com

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