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