make sleep spin-wait during autoconfiguration
[unix-history] / usr / src / old / as.vax / asscan4.c
CommitLineData
ad576865 1/*
bcf1365c
DF
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.
ad576865 5 */
bcf1365c 6
ad576865 7#ifndef lint
bcf1365c 8static char sccsid[] = "@(#)asscan4.c 5.1 (Berkeley) %G%";
ad576865
RH
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
17static char numbuf[NUMSIZE];
18
12044a7d
RH
19#define BACK(backval) intval = backval; goto stuffback;
20
21int number(ch)
ad576865 22 reg int ch;
ad576865
RH
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;
12044a7d 29 reg int inbufcnt;
ad576865
RH
30 char ch1;
31 Bignum floatnumber();
32 Ovf overflow; /* overflow flag */
33 int maxstrlg;
34
12044a7d 35 MEMTOREGBUF;
ad576865
RH
36 cp = numbuf;
37 radix = 10;
38
39 switch(ch){
40 case '0':
41 switch(ch = getchar()){
42 case 'b':
43 yylval = -1;
12044a7d 44 BACK(BFINT);
ad576865
RH
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;
12044a7d 53 BACK(BFINT);
ad576865
RH
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);
12044a7d 88 BACK(BFINT);
ad576865
RH
89 case 'b':
90 yylval = -((ch - '0') + 1);
12044a7d 91 BACK(BFINT);
ad576865
RH
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;
12044a7d 164 BACK(INT);
ad576865
RH
165 bignum: ;
166 yybignum = as_atoi(numbuf, radix, &overflow);
12044a7d 167 BACK(BIGNUM);
ad576865 168 floatnum: ;
12044a7d
RH
169 REGTOMEMBUF;
170 yybignum = floatnumber(ch);
ad576865 171 return(BIGNUM);
12044a7d
RH
172 stuffback: ;
173 REGTOMEMBUF;
174 return(intval);
ad576865
RH
175}
176
12044a7d
RH
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;
ad576865 189
12044a7d 190Bignum floatnumber(fltradix)
ad576865 191 int fltradix;
ad576865
RH
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;
12044a7d 206 reg int inbufcnt;
ad576865 207
12044a7d 208 MEMTOREGBUF;
ad576865
RH
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 }
12044a7d 249 REGTOMEMBUF;
ad576865
RH
250 /*
251 * The overflow value is lost in the call to as_atof
252 */
ad576865
RH
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 */
12044a7d 259int scanint(signOK, dstcpp)
ad576865
RH
260 int signOK;
261 char **dstcpp;
ad576865 262{
12044a7d
RH
263 int ch;
264 int back = 0;
265 reg char *inbufptr;
266 reg int inbufcnt;
ad576865 267
12044a7d 268 MEMTOREGBUF;
ad576865
RH
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);
12044a7d 282 REGTOMEMBUF;
ad576865
RH
283 return(back);
284}