|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.