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: }
Defined functions
Defined variables
sccsid
defined in line
8;
never used
Defined macros
BACK
defined in line
19; used 6 times
reg
defined in line
13; used 9 times