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