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