diff options
Diffstat (limited to 'apps/plugins/puzzles/rbwrappers.c')
-rw-r--r-- | apps/plugins/puzzles/rbwrappers.c | 2378 |
1 files changed, 2378 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/rbwrappers.c b/apps/plugins/puzzles/rbwrappers.c new file mode 100644 index 0000000000..8eca1909c3 --- /dev/null +++ b/apps/plugins/puzzles/rbwrappers.c | |||
@@ -0,0 +1,2378 @@ | |||
1 | #include <puzzles.h> | ||
2 | #include "fixedpoint.h" | ||
3 | |||
4 | int sprintf_wrapper(char *str, const char *fmt, ...) | ||
5 | { | ||
6 | va_list ap; | ||
7 | va_start(ap, fmt); | ||
8 | int ret = rb->vsnprintf(str, 9999, fmt, ap); | ||
9 | va_end(ap); | ||
10 | return ret; | ||
11 | } | ||
12 | |||
13 | char *getenv_wrapper(const char *c) | ||
14 | { | ||
15 | return NULL; | ||
16 | } | ||
17 | |||
18 | int puts_wrapper(const char *s) | ||
19 | { | ||
20 | LOGF("%s", s); | ||
21 | return 0; | ||
22 | } | ||
23 | |||
24 | /* fixed-point wrappers */ | ||
25 | double sin_wrapper(double rads) | ||
26 | { | ||
27 | int degs = rads * 180/PI; | ||
28 | long fixed = fp14_sin(degs); | ||
29 | return fixed / (16384.0); | ||
30 | } | ||
31 | |||
32 | double cos_wrapper(double rads) | ||
33 | { | ||
34 | int degs = rads * 180/PI; | ||
35 | long fixed = fp14_cos(degs); | ||
36 | return fixed / (16384.0); | ||
37 | } | ||
38 | |||
39 | int vsprintf_wrapper(char *s, const char *fmt, va_list ap) | ||
40 | { | ||
41 | return rb->vsnprintf(s, 9999, fmt, ap); | ||
42 | |||
43 | } | ||
44 | |||
45 | /* Absolute value, simple calculus */ | ||
46 | float fabs_wrapper(float x) | ||
47 | { | ||
48 | return (x < 0.0f) ? -x : x; | ||
49 | } | ||
50 | |||
51 | float floor_wrapper(float n) | ||
52 | { | ||
53 | if(n < 0.0f) | ||
54 | return ((int)n - 1); | ||
55 | else | ||
56 | return (int)n; | ||
57 | } | ||
58 | |||
59 | /* Natural logarithm. | ||
60 | Taken from glibc-2.8 */ | ||
61 | static const float | ||
62 | ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ | ||
63 | ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ | ||
64 | two25 = 3.355443200e+07, /* 0x4c000000 */ | ||
65 | Lg1 = 6.6666668653e-01, /* 3F2AAAAB */ | ||
66 | Lg2 = 4.0000000596e-01, /* 3ECCCCCD */ | ||
67 | Lg3 = 2.8571429849e-01, /* 3E924925 */ | ||
68 | Lg4 = 2.2222198546e-01, /* 3E638E29 */ | ||
69 | Lg5 = 1.8183572590e-01, /* 3E3A3325 */ | ||
70 | Lg6 = 1.5313838422e-01, /* 3E1CD04F */ | ||
71 | Lg7 = 1.4798198640e-01; /* 3E178897 */ | ||
72 | |||
73 | static const float zero = 0.0; | ||
74 | |||
75 | /* A union which permits us to convert between a float and a 32 bit | ||
76 | int. */ | ||
77 | |||
78 | typedef union | ||
79 | { | ||
80 | float value; | ||
81 | uint32_t word; | ||
82 | } ieee_float_shape_type; | ||
83 | |||
84 | /* Get a 32 bit int from a float. */ | ||
85 | |||
86 | #define GET_FLOAT_WORD(i,d) \ | ||
87 | do { \ | ||
88 | ieee_float_shape_type gf_u; \ | ||
89 | gf_u.value = (d); \ | ||
90 | (i) = gf_u.word; \ | ||
91 | } while (0) | ||
92 | |||
93 | /* Set a float from a 32 bit int. */ | ||
94 | |||
95 | #define SET_FLOAT_WORD(d,i) \ | ||
96 | do { \ | ||
97 | ieee_float_shape_type sf_u; \ | ||
98 | sf_u.word = (i); \ | ||
99 | (d) = sf_u.value; \ | ||
100 | } while (0) | ||
101 | |||
102 | #ifdef ROCKBOX_LITTLE_ENDIAN | ||
103 | #define __HI(x) *(1+(int*)&x) | ||
104 | #define __LO(x) *(int*)&x | ||
105 | #define __HIp(x) *(1+(int*)x) | ||
106 | #define __LOp(x) *(int*)x | ||
107 | #else | ||
108 | #define __HI(x) *(int*)&x | ||
109 | #define __LO(x) *(1+(int*)&x) | ||
110 | #define __HIp(x) *(int*)x | ||
111 | #define __LOp(x) *(1+(int*)x) | ||
112 | #endif | ||
113 | |||
114 | static float rb_log(float x) | ||
115 | { | ||
116 | float hfsq, f, s, z, R, w, t1, t2, dk; | ||
117 | int32_t k, ix, i, j; | ||
118 | |||
119 | GET_FLOAT_WORD(ix,x); | ||
120 | |||
121 | k=0; | ||
122 | if (ix < 0x00800000) { /* x < 2**-126 */ | ||
123 | if ((ix&0x7fffffff)==0) | ||
124 | return -two25/(x-x); /* log(+-0)=-inf */ | ||
125 | if (ix<0) return (x-x)/(x-x); /* log(-#) = NaN */ | ||
126 | k -= 25; x *= two25; /* subnormal number, scale up x */ | ||
127 | GET_FLOAT_WORD(ix,x); | ||
128 | } | ||
129 | if (ix >= 0x7f800000) return x+x; | ||
130 | k += (ix>>23)-127; | ||
131 | ix &= 0x007fffff; | ||
132 | i = (ix+(0x95f64<<3))&0x800000; | ||
133 | SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ | ||
134 | k += (i>>23); | ||
135 | f = x-(float)1.0; | ||
136 | if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ | ||
137 | if(f==zero) { | ||
138 | if(k==0) | ||
139 | return zero; | ||
140 | else | ||
141 | { | ||
142 | dk=(float)k; | ||
143 | return dk*ln2_hi+dk*ln2_lo; | ||
144 | } | ||
145 | } | ||
146 | R = f*f*((float)0.5-(float)0.33333333333333333*f); | ||
147 | if(k==0) | ||
148 | return f-R; | ||
149 | else | ||
150 | { | ||
151 | dk=(float)k; | ||
152 | return dk*ln2_hi-((R-dk*ln2_lo)-f); | ||
153 | } | ||
154 | } | ||
155 | s = f/((float)2.0+f); | ||
156 | dk = (float)k; | ||
157 | z = s*s; | ||
158 | i = ix-(0x6147a<<3); | ||
159 | w = z*z; | ||
160 | j = (0x6b851<<3)-ix; | ||
161 | t1= w*(Lg2+w*(Lg4+w*Lg6)); | ||
162 | t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); | ||
163 | i |= j; | ||
164 | R = t2+t1; | ||
165 | if(i>0) { | ||
166 | hfsq=(float)0.5*f*f; | ||
167 | if(k==0) | ||
168 | return f-(hfsq-s*(hfsq+R)); | ||
169 | else | ||
170 | return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); | ||
171 | } else { | ||
172 | if(k==0) | ||
173 | return f-s*(f-R); | ||
174 | else | ||
175 | return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | union ieee754_double | ||
180 | { | ||
181 | double d; | ||
182 | |||
183 | /* This is the IEEE 754 double-precision format. */ | ||
184 | struct | ||
185 | { | ||
186 | #ifdef ROCKBOX_BIG_ENDIAN | ||
187 | unsigned int negative:1; | ||
188 | unsigned int exponent:11; | ||
189 | /* Together these comprise the mantissa. */ | ||
190 | unsigned int mantissa0:20; | ||
191 | unsigned int mantissa1:32; | ||
192 | #else /* ROCKBOX_LITTLE_ENDIAN */ | ||
193 | /* Together these comprise the mantissa. */ | ||
194 | unsigned int mantissa1:32; | ||
195 | unsigned int mantissa0:20; | ||
196 | unsigned int exponent:11; | ||
197 | unsigned int negative:1; | ||
198 | #endif /* ROCKBOX_LITTLE_ENDIAN */ | ||
199 | } ieee; | ||
200 | |||
201 | /* This format makes it easier to see if a NaN is a signalling NaN. */ | ||
202 | struct | ||
203 | { | ||
204 | #ifdef ROCKBOX_BIG_ENDIAN | ||
205 | unsigned int negative:1; | ||
206 | unsigned int exponent:11; | ||
207 | unsigned int quiet_nan:1; | ||
208 | /* Together these comprise the mantissa. */ | ||
209 | unsigned int mantissa0:19; | ||
210 | unsigned int mantissa1:32; | ||
211 | #else /* ROCKBOX_LITTLE_ENDIAN */ | ||
212 | /* Together these comprise the mantissa. */ | ||
213 | unsigned int mantissa1:32; | ||
214 | unsigned int mantissa0:19; | ||
215 | unsigned int quiet_nan:1; | ||
216 | unsigned int exponent:11; | ||
217 | unsigned int negative:1; | ||
218 | #endif /* ROCKBOX_LITTLE_ENDIAN */ | ||
219 | } ieee_nan; | ||
220 | }; | ||
221 | |||
222 | static const volatile float TWOM100 = 7.88860905e-31; | ||
223 | static const volatile float TWO127 = 1.7014118346e+38; | ||
224 | |||
225 | /* Exponential function, | ||
226 | taken from glibc-2.8 | ||
227 | As it uses double values and udefines some symbols, | ||
228 | it was moved to the end of the source code */ | ||
229 | |||
230 | #define W52 (2.22044605e-16) | ||
231 | #define W55 (2.77555756e-17) | ||
232 | #define W58 (3.46944695e-18) | ||
233 | #define W59 (1.73472348e-18) | ||
234 | #define W60 (8.67361738e-19) | ||
235 | const float __exp_deltatable[178] = { | ||
236 | 0*W60, 16558714*W60, -10672149*W59, 1441652*W60, | ||
237 | -15787963*W55, 462888*W60, 7291806*W60, 1698880*W60, | ||
238 | -14375103*W58, -2021016*W60, 728829*W60, -3759654*W60, | ||
239 | 3202123*W60, -10916019*W58, -251570*W60, -1043086*W60, | ||
240 | 8207536*W60, -409964*W60, -5993931*W60, -475500*W60, | ||
241 | 2237522*W60, 324170*W60, -244117*W60, 32077*W60, | ||
242 | 123907*W60, -1019734*W60, -143*W60, 813077*W60, | ||
243 | 743345*W60, 462461*W60, 629794*W60, 2125066*W60, | ||
244 | -2339121*W60, -337951*W60, 9922067*W60, -648704*W60, | ||
245 | 149407*W60, -2687209*W60, -631608*W60, 2128280*W60, | ||
246 | -4882082*W60, 2001360*W60, 175074*W60, 2923216*W60, | ||
247 | -538947*W60, -1212193*W60, -1920926*W60, -1080577*W60, | ||
248 | 3690196*W60, 2643367*W60, 2911937*W60, 671455*W60, | ||
249 | -1128674*W60, 593282*W60, -5219347*W60, -1941490*W60, | ||
250 | 11007953*W60, 239609*W60, -2969658*W60, -1183650*W60, | ||
251 | 942998*W60, 699063*W60, 450569*W60, -329250*W60, | ||
252 | -7257875*W60, -312436*W60, 51626*W60, 555877*W60, | ||
253 | -641761*W60, 1565666*W60, 884327*W60, -10960035*W60, | ||
254 | -2004679*W60, -995793*W60, -2229051*W60, -146179*W60, | ||
255 | -510327*W60, 1453482*W60, -3778852*W60, -2238056*W60, | ||
256 | -4895983*W60, 3398883*W60, -252738*W60, 1230155*W60, | ||
257 | 346918*W60, 1109352*W60, 268941*W60, -2930483*W60, | ||
258 | -1036263*W60, -1159280*W60, 1328176*W60, 2937642*W60, | ||
259 | -9371420*W60, -6902650*W60, -1419134*W60, 1442904*W60, | ||
260 | -1319056*W60, -16369*W60, 696555*W60, -279987*W60, | ||
261 | -7919763*W60, 252741*W60, 459711*W60, -1709645*W60, | ||
262 | 354913*W60, 6025867*W60, -421460*W60, -853103*W60, | ||
263 | -338649*W60, 962151*W60, 955965*W60, 784419*W60, | ||
264 | -3633653*W60, 2277133*W60, -8847927*W52, 1223028*W60, | ||
265 | 5907079*W60, 623167*W60, 5142888*W60, 2599099*W60, | ||
266 | 1214280*W60, 4870359*W60, 593349*W60, -57705*W60, | ||
267 | 7761209*W60, -5564097*W60, 2051261*W60, 6216869*W60, | ||
268 | 4692163*W60, 601691*W60, -5264906*W60, 1077872*W60, | ||
269 | -3205949*W60, 1833082*W60, 2081746*W60, -987363*W60, | ||
270 | -1049535*W60, 2015244*W60, 874230*W60, 2168259*W60, | ||
271 | -1740124*W60, -10068269*W60, -18242*W60, -3013583*W60, | ||
272 | 580601*W60, -2547161*W60, -535689*W60, 2220815*W60, | ||
273 | 1285067*W60, 2806933*W60, -983086*W60, -1729097*W60, | ||
274 | -1162985*W60, -2561904*W60, 801988*W60, 244351*W60, | ||
275 | 1441893*W60, -7517981*W60, 271781*W60, -15021588*W60, | ||
276 | -2341588*W60, -919198*W60, 1642232*W60, 4771771*W60, | ||
277 | -1220099*W60, -3062372*W60, 628624*W60, 1278114*W60, | ||
278 | 13083513*W60, -10521925*W60, 3180310*W60, -1659307*W60, | ||
279 | 3543773*W60, 2501203*W60, 4151*W60, -340748*W60, | ||
280 | -2285625*W60, 2495202*W60 | ||
281 | }; | ||
282 | |||
283 | const double __exp_atable[355] /* __attribute__((mode(DF))) */ = { | ||
284 | 0.707722561055888932371, /* 0x0.b52d4e46605c27ffd */ | ||
285 | 0.709106182438804188967, /* 0x0.b587fb96f75097ffb */ | ||
286 | 0.710492508843861281234, /* 0x0.b5e2d649899167ffd */ | ||
287 | 0.711881545564593931623, /* 0x0.b63dde74d36bdfffe */ | ||
288 | 0.713273297897442870573, /* 0x0.b699142f945f87ffc */ | ||
289 | 0.714667771153751463236, /* 0x0.b6f477909c4ea0001 */ | ||
290 | 0.716064970655995725059, /* 0x0.b75008aec758f8004 */ | ||
291 | 0.717464901723956938193, /* 0x0.b7abc7a0eea7e0002 */ | ||
292 | 0.718867569715736398602, /* 0x0.b807b47e1586c7ff8 */ | ||
293 | 0.720272979947266023271, /* 0x0.b863cf5d10e380003 */ | ||
294 | 0.721681137825144314297, /* 0x0.b8c01855195c37ffb */ | ||
295 | 0.723092048691992950199, /* 0x0.b91c8f7d213740004 */ | ||
296 | 0.724505717938892290800, /* 0x0.b97934ec5002d0007 */ | ||
297 | 0.725922150953176470431, /* 0x0.b9d608b9c92ea7ffc */ | ||
298 | 0.727341353138962865022, /* 0x0.ba330afcc29e98003 */ | ||
299 | 0.728763329918453162104, /* 0x0.ba903bcc8618b7ffc */ | ||
300 | 0.730188086709957051568, /* 0x0.baed9b40591ba0000 */ | ||
301 | 0.731615628948127705309, /* 0x0.bb4b296f931e30002 */ | ||
302 | 0.733045962086486091436, /* 0x0.bba8e671a05617ff9 */ | ||
303 | 0.734479091556371366251, /* 0x0.bc06d25dd49568001 */ | ||
304 | 0.735915022857225542529, /* 0x0.bc64ed4bce8f6fff9 */ | ||
305 | 0.737353761441304711410, /* 0x0.bcc33752f915d7ff9 */ | ||
306 | 0.738795312814142124419, /* 0x0.bd21b08af98e78005 */ | ||
307 | 0.740239682467211168593, /* 0x0.bd80590b65e9a8000 */ | ||
308 | 0.741686875913991849885, /* 0x0.bddf30ebec4a10000 */ | ||
309 | 0.743136898669507939299, /* 0x0.be3e38443c84e0007 */ | ||
310 | 0.744589756269486091620, /* 0x0.be9d6f2c1d32a0002 */ | ||
311 | 0.746045454254026796384, /* 0x0.befcd5bb59baf8004 */ | ||
312 | 0.747503998175051087583, /* 0x0.bf5c6c09ca84c0003 */ | ||
313 | 0.748965393601880857739, /* 0x0.bfbc322f5b18b7ff8 */ | ||
314 | 0.750429646104262104698, /* 0x0.c01c2843f776fffff */ | ||
315 | 0.751896761271877989160, /* 0x0.c07c4e5fa18b88002 */ | ||
316 | 0.753366744698445112140, /* 0x0.c0dca49a5fb18fffd */ | ||
317 | 0.754839601988627206827, /* 0x0.c13d2b0c444db0005 */ | ||
318 | 0.756315338768691947122, /* 0x0.c19de1cd798578006 */ | ||
319 | 0.757793960659406629066, /* 0x0.c1fec8f623723fffd */ | ||
320 | 0.759275473314173443536, /* 0x0.c25fe09e8a0f47ff8 */ | ||
321 | 0.760759882363831851927, /* 0x0.c2c128dedc88f8000 */ | ||
322 | 0.762247193485956486805, /* 0x0.c322a1cf7d6e7fffa */ | ||
323 | 0.763737412354726363781, /* 0x0.c3844b88cb9347ffc */ | ||
324 | 0.765230544649828092739, /* 0x0.c3e626232bd8f7ffc */ | ||
325 | 0.766726596071518051729, /* 0x0.c44831b719bf18002 */ | ||
326 | 0.768225572321911687194, /* 0x0.c4aa6e5d12d078001 */ | ||
327 | 0.769727479119219348810, /* 0x0.c50cdc2da64a37ffb */ | ||
328 | 0.771232322196981678892, /* 0x0.c56f7b41744490001 */ | ||
329 | 0.772740107296721268087, /* 0x0.c5d24bb1259e70004 */ | ||
330 | 0.774250840160724651565, /* 0x0.c6354d95640dd0007 */ | ||
331 | 0.775764526565368872643, /* 0x0.c6988106fec447fff */ | ||
332 | 0.777281172269557396602, /* 0x0.c6fbe61eb1bd0ffff */ | ||
333 | 0.778800783068235302750, /* 0x0.c75f7cf560942fffc */ | ||
334 | 0.780323364758801041312, /* 0x0.c7c345a3f1983fffe */ | ||
335 | 0.781848923151573727006, /* 0x0.c8274043594cb0002 */ | ||
336 | 0.783377464064598849602, /* 0x0.c88b6cec94b3b7ff9 */ | ||
337 | 0.784908993312207869935, /* 0x0.c8efcbb89cba27ffe */ | ||
338 | 0.786443516765346961618, /* 0x0.c9545cc0a88c70003 */ | ||
339 | 0.787981040257604625744, /* 0x0.c9b9201dc643bfffa */ | ||
340 | 0.789521569657452682047, /* 0x0.ca1e15e92a5410007 */ | ||
341 | 0.791065110849462849192, /* 0x0.ca833e3c1ae510005 */ | ||
342 | 0.792611669712891875319, /* 0x0.cae8992fd84667ffd */ | ||
343 | 0.794161252150049179450, /* 0x0.cb4e26ddbc207fff8 */ | ||
344 | 0.795713864077794763584, /* 0x0.cbb3e75f301b60003 */ | ||
345 | 0.797269511407239561694, /* 0x0.cc19dacd978cd8002 */ | ||
346 | 0.798828200086368567220, /* 0x0.cc8001427e55d7ffb */ | ||
347 | 0.800389937624300440456, /* 0x0.cce65ade24d360006 */ | ||
348 | 0.801954725261124767840, /* 0x0.cd4ce7a5de839fffb */ | ||
349 | 0.803522573691593189330, /* 0x0.cdb3a7c79a678fffd */ | ||
350 | 0.805093487311204114563, /* 0x0.ce1a9b563965ffffc */ | ||
351 | 0.806667472122675088819, /* 0x0.ce81c26b838db8000 */ | ||
352 | 0.808244534127439906441, /* 0x0.cee91d213f8428002 */ | ||
353 | 0.809824679342317166307, /* 0x0.cf50ab9144d92fff9 */ | ||
354 | 0.811407913793616542005, /* 0x0.cfb86dd5758c2ffff */ | ||
355 | 0.812994243520784198882, /* 0x0.d0206407c20e20005 */ | ||
356 | 0.814583674571603966162, /* 0x0.d0888e4223facfff9 */ | ||
357 | 0.816176213022088536960, /* 0x0.d0f0ec9eb3f7c8002 */ | ||
358 | 0.817771864936188586101, /* 0x0.d1597f377d6768002 */ | ||
359 | 0.819370636400374108252, /* 0x0.d1c24626a46eafff8 */ | ||
360 | 0.820972533518165570298, /* 0x0.d22b41865ff1e7ff9 */ | ||
361 | 0.822577562404315121269, /* 0x0.d2947170f32ec7ff9 */ | ||
362 | 0.824185729164559344159, /* 0x0.d2fdd60097795fff8 */ | ||
363 | 0.825797039949601741075, /* 0x0.d3676f4fb796d0001 */ | ||
364 | 0.827411500902565544264, /* 0x0.d3d13d78b5f68fffb */ | ||
365 | 0.829029118181348834154, /* 0x0.d43b40960546d8001 */ | ||
366 | 0.830649897953322891022, /* 0x0.d4a578c222a058000 */ | ||
367 | 0.832273846408250750368, /* 0x0.d50fe617a3ba78005 */ | ||
368 | 0.833900969738858188772, /* 0x0.d57a88b1218e90002 */ | ||
369 | 0.835531274148056613016, /* 0x0.d5e560a94048f8006 */ | ||
370 | 0.837164765846411529371, /* 0x0.d6506e1aac8078003 */ | ||
371 | 0.838801451086016225394, /* 0x0.d6bbb1204074e0001 */ | ||
372 | 0.840441336100884561780, /* 0x0.d72729d4c28518004 */ | ||
373 | 0.842084427144139224814, /* 0x0.d792d8530e12b0001 */ | ||
374 | 0.843730730487052604790, /* 0x0.d7febcb61273e7fff */ | ||
375 | 0.845380252404570153833, /* 0x0.d86ad718c308dfff9 */ | ||
376 | 0.847032999194574087728, /* 0x0.d8d727962c69d7fff */ | ||
377 | 0.848688977161248581090, /* 0x0.d943ae49621ce7ffb */ | ||
378 | 0.850348192619261200615, /* 0x0.d9b06b4d832ef8005 */ | ||
379 | 0.852010651900976245816, /* 0x0.da1d5ebdc22220005 */ | ||
380 | 0.853676361342631029337, /* 0x0.da8a88b555baa0006 */ | ||
381 | 0.855345327311054837175, /* 0x0.daf7e94f965f98004 */ | ||
382 | 0.857017556155879489641, /* 0x0.db6580a7c98f7fff8 */ | ||
383 | 0.858693054267390953857, /* 0x0.dbd34ed9617befff8 */ | ||
384 | 0.860371828028939855647, /* 0x0.dc4153ffc8b65fff9 */ | ||
385 | 0.862053883854957292436, /* 0x0.dcaf90368bfca8004 */ | ||
386 | 0.863739228154875360306, /* 0x0.dd1e0399328d87ffe */ | ||
387 | 0.865427867361348468455, /* 0x0.dd8cae435d303fff9 */ | ||
388 | 0.867119807911702289458, /* 0x0.ddfb9050b1cee8006 */ | ||
389 | 0.868815056264353846599, /* 0x0.de6aa9dced8448001 */ | ||
390 | 0.870513618890481399881, /* 0x0.ded9fb03db7320006 */ | ||
391 | 0.872215502247877139094, /* 0x0.df4983e1380657ff8 */ | ||
392 | 0.873920712852848668986, /* 0x0.dfb94490ffff77ffd */ | ||
393 | 0.875629257204025623884, /* 0x0.e0293d2f1cb01fff9 */ | ||
394 | 0.877341141814212965880, /* 0x0.e0996dd786fff0007 */ | ||
395 | 0.879056373217612985183, /* 0x0.e109d6a64f5d57ffc */ | ||
396 | 0.880774957955916648615, /* 0x0.e17a77b78e72a7ffe */ | ||
397 | 0.882496902590150900078, /* 0x0.e1eb5127722cc7ff8 */ | ||
398 | 0.884222213673356738383, /* 0x0.e25c63121fb0c8006 */ | ||
399 | 0.885950897802399772740, /* 0x0.e2cdad93ec5340003 */ | ||
400 | 0.887682961567391237685, /* 0x0.e33f30c925fb97ffb */ | ||
401 | 0.889418411575228162725, /* 0x0.e3b0ecce2d05ffff9 */ | ||
402 | 0.891157254447957902797, /* 0x0.e422e1bf727718006 */ | ||
403 | 0.892899496816652704641, /* 0x0.e4950fb9713fc7ffe */ | ||
404 | 0.894645145323828439008, /* 0x0.e50776d8b0e60fff8 */ | ||
405 | 0.896394206626591749641, /* 0x0.e57a1739c8fadfffc */ | ||
406 | 0.898146687421414902124, /* 0x0.e5ecf0f97c5798007 */ | ||
407 | 0.899902594367530173098, /* 0x0.e660043464e378005 */ | ||
408 | 0.901661934163603406867, /* 0x0.e6d3510747e150006 */ | ||
409 | 0.903424713533971135418, /* 0x0.e746d78f06cd97ffd */ | ||
410 | 0.905190939194458810123, /* 0x0.e7ba97e879c91fffc */ | ||
411 | 0.906960617885092856864, /* 0x0.e82e92309390b0007 */ | ||
412 | 0.908733756358986566306, /* 0x0.e8a2c6845544afffa */ | ||
413 | 0.910510361377119825629, /* 0x0.e9173500c8abc7ff8 */ | ||
414 | 0.912290439722343249336, /* 0x0.e98bddc30f98b0002 */ | ||
415 | 0.914073998177417412765, /* 0x0.ea00c0e84bc4c7fff */ | ||
416 | 0.915861043547953501680, /* 0x0.ea75de8db8094fffe */ | ||
417 | 0.917651582652244779397, /* 0x0.eaeb36d09d3137ffe */ | ||
418 | 0.919445622318405764159, /* 0x0.eb60c9ce4ed3dffff */ | ||
419 | 0.921243169397334638073, /* 0x0.ebd697a43995b0007 */ | ||
420 | 0.923044230737526172328, /* 0x0.ec4ca06fc7768fffa */ | ||
421 | 0.924848813220121135342, /* 0x0.ecc2e44e865b6fffb */ | ||
422 | 0.926656923710931002014, /* 0x0.ed39635df34e70006 */ | ||
423 | 0.928468569126343790092, /* 0x0.edb01dbbc2f5b7ffa */ | ||
424 | 0.930283756368834757725, /* 0x0.ee2713859aab57ffa */ | ||
425 | 0.932102492359406786818, /* 0x0.ee9e44d9342870004 */ | ||
426 | 0.933924784042873379360, /* 0x0.ef15b1d4635438005 */ | ||
427 | 0.935750638358567643520, /* 0x0.ef8d5a94f60f50007 */ | ||
428 | 0.937580062297704630580, /* 0x0.f0053f38f345cffff */ | ||
429 | 0.939413062815381727516, /* 0x0.f07d5fde3a2d98001 */ | ||
430 | 0.941249646905368053689, /* 0x0.f0f5bca2d481a8004 */ | ||
431 | 0.943089821583810716806, /* 0x0.f16e55a4e497d7ffe */ | ||
432 | 0.944933593864477061592, /* 0x0.f1e72b028a2827ffb */ | ||
433 | 0.946780970781518460559, /* 0x0.f2603cd9fb5430001 */ | ||
434 | 0.948631959382661205081, /* 0x0.f2d98b497d2a87ff9 */ | ||
435 | 0.950486566729423554277, /* 0x0.f353166f63e3dffff */ | ||
436 | 0.952344799896018723290, /* 0x0.f3ccde6a11ae37ffe */ | ||
437 | 0.954206665969085765512, /* 0x0.f446e357f66120000 */ | ||
438 | 0.956072172053890279009, /* 0x0.f4c12557964f0fff9 */ | ||
439 | 0.957941325265908139014, /* 0x0.f53ba48781046fffb */ | ||
440 | 0.959814132734539637840, /* 0x0.f5b66106555d07ffa */ | ||
441 | 0.961690601603558903308, /* 0x0.f6315af2c2027fffc */ | ||
442 | 0.963570739036113010927, /* 0x0.f6ac926b8aeb80004 */ | ||
443 | 0.965454552202857141381, /* 0x0.f728078f7c5008002 */ | ||
444 | 0.967342048278315158608, /* 0x0.f7a3ba7d66a908001 */ | ||
445 | 0.969233234469444204768, /* 0x0.f81fab543e1897ffb */ | ||
446 | 0.971128118008140250896, /* 0x0.f89bda33122c78007 */ | ||
447 | 0.973026706099345495256, /* 0x0.f9184738d4cf97ff8 */ | ||
448 | 0.974929006031422851235, /* 0x0.f994f284d3a5c0008 */ | ||
449 | 0.976835024947348973265, /* 0x0.fa11dc35bc7820002 */ | ||
450 | 0.978744770239899142285, /* 0x0.fa8f046b4fb7f8007 */ | ||
451 | 0.980658249138918636210, /* 0x0.fb0c6b449ab1cfff9 */ | ||
452 | 0.982575468959622777535, /* 0x0.fb8a10e1088fb7ffa */ | ||
453 | 0.984496437054508843888, /* 0x0.fc07f5602d79afffc */ | ||
454 | 0.986421160608523028820, /* 0x0.fc8618e0e55e47ffb */ | ||
455 | 0.988349647107594098099, /* 0x0.fd047b83571b1fffa */ | ||
456 | 0.990281903873210800357, /* 0x0.fd831d66f4c018002 */ | ||
457 | 0.992217938695037382475, /* 0x0.fe01fead3320bfff8 */ | ||
458 | 0.994157757657894713987, /* 0x0.fe811f703491e8006 */ | ||
459 | 0.996101369488558541238, /* 0x0.ff007fd5744490005 */ | ||
460 | 0.998048781093141101932, /* 0x0.ff801ffa9b9280007 */ | ||
461 | 1.000000000000000000000, /* 0x1.00000000000000000 */ | ||
462 | 1.001955033605393285965, /* 0x1.0080200565d29ffff */ | ||
463 | 1.003913889319761887310, /* 0x1.0100802aa0e80fff0 */ | ||
464 | 1.005876574715736104818, /* 0x1.01812090377240007 */ | ||
465 | 1.007843096764807100351, /* 0x1.020201541aad7fff6 */ | ||
466 | 1.009813464316352327214, /* 0x1.0283229c4c9820007 */ | ||
467 | 1.011787683565730677817, /* 0x1.030484836910a000e */ | ||
468 | 1.013765762469146736174, /* 0x1.0386272b9c077fffe */ | ||
469 | 1.015747708536026694351, /* 0x1.04080ab526304fff0 */ | ||
470 | 1.017733529475172815584, /* 0x1.048a2f412375ffff0 */ | ||
471 | 1.019723232714418781378, /* 0x1.050c94ef7ad5e000a */ | ||
472 | 1.021716825883923762690, /* 0x1.058f3be0f1c2d0004 */ | ||
473 | 1.023714316605201180057, /* 0x1.06122436442e2000e */ | ||
474 | 1.025715712440059545995, /* 0x1.06954e0fec63afff2 */ | ||
475 | 1.027721021151397406936, /* 0x1.0718b98f41c92fff6 */ | ||
476 | 1.029730250269221158939, /* 0x1.079c66d49bb2ffff1 */ | ||
477 | 1.031743407506447551857, /* 0x1.082056011a9230009 */ | ||
478 | 1.033760500517691527387, /* 0x1.08a487359ebd50002 */ | ||
479 | 1.035781537016238873464, /* 0x1.0928fa93490d4fff3 */ | ||
480 | 1.037806524719013578963, /* 0x1.09adb03b3e5b3000d */ | ||
481 | 1.039835471338248051878, /* 0x1.0a32a84e9e5760004 */ | ||
482 | 1.041868384612101516848, /* 0x1.0ab7e2eea5340ffff */ | ||
483 | 1.043905272300907460835, /* 0x1.0b3d603ca784f0009 */ | ||
484 | 1.045946142174331239262, /* 0x1.0bc3205a042060000 */ | ||
485 | 1.047991002016745332165, /* 0x1.0c4923682a086fffe */ | ||
486 | 1.050039859627715177527, /* 0x1.0ccf698898f3a000d */ | ||
487 | 1.052092722826109660856, /* 0x1.0d55f2dce5d1dfffb */ | ||
488 | 1.054149599440827866881, /* 0x1.0ddcbf86b09a5fff6 */ | ||
489 | 1.056210497317612961855, /* 0x1.0e63cfa7abc97fffd */ | ||
490 | 1.058275424318780855142, /* 0x1.0eeb23619c146fffb */ | ||
491 | 1.060344388322010722446, /* 0x1.0f72bad65714bffff */ | ||
492 | 1.062417397220589476718, /* 0x1.0ffa9627c38d30004 */ | ||
493 | 1.064494458915699715017, /* 0x1.1082b577d0eef0003 */ | ||
494 | 1.066575581342167566880, /* 0x1.110b18e893a90000a */ | ||
495 | 1.068660772440545025953, /* 0x1.1193c09c267610006 */ | ||
496 | 1.070750040138235936705, /* 0x1.121cacb4959befff6 */ | ||
497 | 1.072843392435016474095, /* 0x1.12a5dd543cf36ffff */ | ||
498 | 1.074940837302467588937, /* 0x1.132f529d59552000b */ | ||
499 | 1.077042382749654914030, /* 0x1.13b90cb250d08fff5 */ | ||
500 | 1.079148036789447484528, /* 0x1.14430bb58da3dfff9 */ | ||
501 | 1.081257807444460983297, /* 0x1.14cd4fc984c4a000e */ | ||
502 | 1.083371702785017154417, /* 0x1.1557d910df9c7000e */ | ||
503 | 1.085489730853784307038, /* 0x1.15e2a7ae292d30002 */ | ||
504 | 1.087611899742884524772, /* 0x1.166dbbc422d8c0004 */ | ||
505 | 1.089738217537583819804, /* 0x1.16f9157586772ffff */ | ||
506 | 1.091868692357631731528, /* 0x1.1784b4e533cacfff0 */ | ||
507 | 1.094003332327482702577, /* 0x1.18109a360fc23fff2 */ | ||
508 | 1.096142145591650907149, /* 0x1.189cc58b155a70008 */ | ||
509 | 1.098285140311341168136, /* 0x1.1929370751ea50002 */ | ||
510 | 1.100432324652149906842, /* 0x1.19b5eecdd79cefff0 */ | ||
511 | 1.102583706811727015711, /* 0x1.1a42ed01dbdba000e */ | ||
512 | 1.104739294993289488947, /* 0x1.1ad031c69a2eafff0 */ | ||
513 | 1.106899097422573863281, /* 0x1.1b5dbd3f66e120003 */ | ||
514 | 1.109063122341542140286, /* 0x1.1beb8f8fa8150000b */ | ||
515 | 1.111231377994659874592, /* 0x1.1c79a8dac6ad0fff4 */ | ||
516 | 1.113403872669181282605, /* 0x1.1d0809445a97ffffc */ | ||
517 | 1.115580614653132185460, /* 0x1.1d96b0effc9db000e */ | ||
518 | 1.117761612217810673898, /* 0x1.1e25a001332190000 */ | ||
519 | 1.119946873713312474002, /* 0x1.1eb4d69bdb2a9fff1 */ | ||
520 | 1.122136407473298902480, /* 0x1.1f4454e3bfae00006 */ | ||
521 | 1.124330221845670330058, /* 0x1.1fd41afcbb48bfff8 */ | ||
522 | 1.126528325196519908506, /* 0x1.2064290abc98c0001 */ | ||
523 | 1.128730725913251964394, /* 0x1.20f47f31c9aa7000f */ | ||
524 | 1.130937432396844410880, /* 0x1.21851d95f776dfff0 */ | ||
525 | 1.133148453059692917203, /* 0x1.2216045b6784efffa */ | ||
526 | 1.135363796355857157764, /* 0x1.22a733a6692ae0004 */ | ||
527 | 1.137583470716100553249, /* 0x1.2338ab9b3221a0004 */ | ||
528 | 1.139807484614418608939, /* 0x1.23ca6c5e27aadfff7 */ | ||
529 | 1.142035846532929888057, /* 0x1.245c7613b7f6c0004 */ | ||
530 | 1.144268564977221958089, /* 0x1.24eec8e06b035000c */ | ||
531 | 1.146505648458203463465, /* 0x1.258164e8cea85fff8 */ | ||
532 | 1.148747105501412235671, /* 0x1.26144a5180d380009 */ | ||
533 | 1.150992944689175123667, /* 0x1.26a7793f5de2efffa */ | ||
534 | 1.153243174560058870217, /* 0x1.273af1d712179000d */ | ||
535 | 1.155497803703682491111, /* 0x1.27ceb43d81d42fff1 */ | ||
536 | 1.157756840726344771440, /* 0x1.2862c097a3d29000c */ | ||
537 | 1.160020294239811677834, /* 0x1.28f7170a74cf4fff1 */ | ||
538 | 1.162288172883275239058, /* 0x1.298bb7bb0faed0004 */ | ||
539 | 1.164560485298402170388, /* 0x1.2a20a2ce920dffff4 */ | ||
540 | 1.166837240167474476460, /* 0x1.2ab5d86a4631ffff6 */ | ||
541 | 1.169118446164539637555, /* 0x1.2b4b58b36d5220009 */ | ||
542 | 1.171404112007080167155, /* 0x1.2be123cf786790002 */ | ||
543 | 1.173694246390975415341, /* 0x1.2c7739e3c0aac000d */ | ||
544 | 1.175988858069749065617, /* 0x1.2d0d9b15deb58fff6 */ | ||
545 | 1.178287955789017793514, /* 0x1.2da4478b627040002 */ | ||
546 | 1.180591548323240091978, /* 0x1.2e3b3f69fb794fffc */ | ||
547 | 1.182899644456603782686, /* 0x1.2ed282d76421d0004 */ | ||
548 | 1.185212252993012693694, /* 0x1.2f6a11f96c685fff3 */ | ||
549 | 1.187529382762033236513, /* 0x1.3001ecf60082ffffa */ | ||
550 | 1.189851042595508889847, /* 0x1.309a13f30f28a0004 */ | ||
551 | 1.192177241354644978669, /* 0x1.31328716a758cfff7 */ | ||
552 | 1.194507987909589896687, /* 0x1.31cb4686e1e85fffb */ | ||
553 | 1.196843291137896336843, /* 0x1.32645269dfd04000a */ | ||
554 | 1.199183159977805113226, /* 0x1.32fdaae604c39000f */ | ||
555 | 1.201527603343041317132, /* 0x1.339750219980dfff3 */ | ||
556 | 1.203876630171082595692, /* 0x1.3431424300e480007 */ | ||
557 | 1.206230249419600664189, /* 0x1.34cb8170b3fee000e */ | ||
558 | 1.208588470077065268869, /* 0x1.35660dd14dbd4fffc */ | ||
559 | 1.210951301134513435915, /* 0x1.3600e78b6bdfc0005 */ | ||
560 | 1.213318751604272271958, /* 0x1.369c0ec5c38ebfff2 */ | ||
561 | 1.215690830512196507537, /* 0x1.373783a718d29000f */ | ||
562 | 1.218067546930756250870, /* 0x1.37d3465662f480007 */ | ||
563 | 1.220448909901335365929, /* 0x1.386f56fa770fe0008 */ | ||
564 | 1.222834928513994334780, /* 0x1.390bb5ba5fc540004 */ | ||
565 | 1.225225611877684750397, /* 0x1.39a862bd3c7a8fff3 */ | ||
566 | 1.227620969111500981433, /* 0x1.3a455e2a37bcafffd */ | ||
567 | 1.230021009336254911271, /* 0x1.3ae2a8287dfbefff6 */ | ||
568 | 1.232425741726685064472, /* 0x1.3b8040df76f39fffa */ | ||
569 | 1.234835175450728295084, /* 0x1.3c1e287682e48fff1 */ | ||
570 | 1.237249319699482263931, /* 0x1.3cbc5f151b86bfff8 */ | ||
571 | 1.239668183679933477545, /* 0x1.3d5ae4e2cc0a8000f */ | ||
572 | 1.242091776620540377629, /* 0x1.3df9ba07373bf0006 */ | ||
573 | 1.244520107762172811399, /* 0x1.3e98deaa0d8cafffe */ | ||
574 | 1.246953186383919165383, /* 0x1.3f3852f32973efff0 */ | ||
575 | 1.249391019292643401078, /* 0x1.3fd816ffc72b90001 */ | ||
576 | 1.251833623164381181797, /* 0x1.40782b17863250005 */ | ||
577 | 1.254280999953110153911, /* 0x1.41188f42caf400000 */ | ||
578 | 1.256733161434815393410, /* 0x1.41b943b42945bfffd */ | ||
579 | 1.259190116985283935980, /* 0x1.425a4893e5f10000a */ | ||
580 | 1.261651875958665236542, /* 0x1.42fb9e0a2df4c0009 */ | ||
581 | 1.264118447754797758244, /* 0x1.439d443f608c4fff9 */ | ||
582 | 1.266589841787181258708, /* 0x1.443f3b5bebf850008 */ | ||
583 | 1.269066067469190262045, /* 0x1.44e183883e561fff7 */ | ||
584 | 1.271547134259576328224, /* 0x1.45841cecf7a7a0001 */ | ||
585 | 1.274033051628237434048, /* 0x1.462707b2c43020009 */ | ||
586 | 1.276523829025464573684, /* 0x1.46ca44023aa410007 */ | ||
587 | 1.279019475999373156531, /* 0x1.476dd2045d46ffff0 */ | ||
588 | 1.281520002043128991825, /* 0x1.4811b1e1f1f19000b */ | ||
589 | 1.284025416692967214122, /* 0x1.48b5e3c3edd74fff4 */ | ||
590 | 1.286535729509738823464, /* 0x1.495a67d3613c8fff7 */ | ||
591 | 1.289050950070396384145, /* 0x1.49ff3e396e19d000b */ | ||
592 | 1.291571087985403654081, /* 0x1.4aa4671f5b401fff1 */ | ||
593 | 1.294096152842774794011, /* 0x1.4b49e2ae56d19000d */ | ||
594 | 1.296626154297237043484, /* 0x1.4befb10fd84a3fff4 */ | ||
595 | 1.299161101984141142272, /* 0x1.4c95d26d41d84fff8 */ | ||
596 | 1.301701005575179204100, /* 0x1.4d3c46f01d9f0fff3 */ | ||
597 | 1.304245874766450485904, /* 0x1.4de30ec21097d0003 */ | ||
598 | 1.306795719266019562007, /* 0x1.4e8a2a0ccce3d0002 */ | ||
599 | 1.309350548792467483458, /* 0x1.4f3198fa10346fff5 */ | ||
600 | 1.311910373099227200545, /* 0x1.4fd95bb3be8cffffd */ | ||
601 | 1.314475201942565174546, /* 0x1.50817263bf0e5fffb */ | ||
602 | 1.317045045107389400535, /* 0x1.5129dd3418575000e */ | ||
603 | 1.319619912422941299109, /* 0x1.51d29c4f01c54ffff */ | ||
604 | 1.322199813675649204855, /* 0x1.527bafde83a310009 */ | ||
605 | 1.324784758729532718739, /* 0x1.5325180cfb8b3fffd */ | ||
606 | 1.327374757430096474625, /* 0x1.53ced504b2bd0fff4 */ | ||
607 | 1.329969819671041886272, /* 0x1.5478e6f02775e0001 */ | ||
608 | 1.332569955346704748651, /* 0x1.55234df9d8a59fff8 */ | ||
609 | 1.335175174370685002822, /* 0x1.55ce0a4c5a6a9fff6 */ | ||
610 | 1.337785486688218616860, /* 0x1.56791c1263abefff7 */ | ||
611 | 1.340400902247843806217, /* 0x1.57248376aef21fffa */ | ||
612 | 1.343021431036279800211, /* 0x1.57d040a420c0bfff3 */ | ||
613 | 1.345647083048053138662, /* 0x1.587c53c5a630f0002 */ | ||
614 | 1.348277868295411074918, /* 0x1.5928bd063fd7bfff9 */ | ||
615 | 1.350913796821875845231, /* 0x1.59d57c9110ad60006 */ | ||
616 | 1.353554878672557082439, /* 0x1.5a8292913d68cfffc */ | ||
617 | 1.356201123929036356254, /* 0x1.5b2fff3212db00007 */ | ||
618 | 1.358852542671913132777, /* 0x1.5bddc29edcc06fff3 */ | ||
619 | 1.361509145047255398051, /* 0x1.5c8bdd032ed16000f */ | ||
620 | 1.364170941142184734180, /* 0x1.5d3a4e8a5bf61fff4 */ | ||
621 | 1.366837941171020309735, /* 0x1.5de9176042f1effff */ | ||
622 | 1.369510155261156381121, /* 0x1.5e9837b062f4e0005 */ | ||
623 | 1.372187593620959988833, /* 0x1.5f47afa69436cfff1 */ | ||
624 | 1.374870266463378287715, /* 0x1.5ff77f6eb3f8cfffd */ | ||
625 | 1.377558184010425845733, /* 0x1.60a7a734a9742fff9 */ | ||
626 | 1.380251356531521533853, /* 0x1.6158272490016000c */ | ||
627 | 1.382949794301995272203, /* 0x1.6208ff6a8978a000f */ | ||
628 | 1.385653507605306700170, /* 0x1.62ba3032c0a280004 */ | ||
629 | 1.388362506772382154503, /* 0x1.636bb9a994784000f */ | ||
630 | 1.391076802081129493127, /* 0x1.641d9bfb29a7bfff6 */ | ||
631 | 1.393796403973427855412, /* 0x1.64cfd7545928b0002 */ | ||
632 | 1.396521322756352656542, /* 0x1.65826be167badfff8 */ | ||
633 | 1.399251568859207761660, /* 0x1.663559cf20826000c */ | ||
634 | 1.401987152677323100733, /* 0x1.66e8a14a29486fffc */ | ||
635 | 1.404728084651919228815, /* 0x1.679c427f5a4b6000b */ | ||
636 | 1.407474375243217723560, /* 0x1.68503d9ba0add000f */ | ||
637 | 1.410226034922914983815, /* 0x1.690492cbf6303fff9 */ | ||
638 | 1.412983074197955213304, /* 0x1.69b9423d7b548fff6 */ | ||
639 | }; | ||
640 | |||
641 | /* All floating-point numbers can be put in one of these categories. */ | ||
642 | enum | ||
643 | { | ||
644 | FP_NAN, | ||
645 | # define FP_NAN FP_NAN | ||
646 | FP_INFINITE, | ||
647 | # define FP_INFINITE FP_INFINITE | ||
648 | FP_ZERO, | ||
649 | # define FP_ZERO FP_ZERO | ||
650 | FP_SUBNORMAL, | ||
651 | # define FP_SUBNORMAL FP_SUBNORMAL | ||
652 | FP_NORMAL | ||
653 | # define FP_NORMAL FP_NORMAL | ||
654 | }; | ||
655 | |||
656 | |||
657 | int | ||
658 | __fpclassifyf (float x) | ||
659 | { | ||
660 | uint32_t wx; | ||
661 | int retval = FP_NORMAL; | ||
662 | |||
663 | GET_FLOAT_WORD (wx, x); | ||
664 | wx &= 0x7fffffff; | ||
665 | if (wx == 0) | ||
666 | retval = FP_ZERO; | ||
667 | else if (wx < 0x800000) | ||
668 | retval = FP_SUBNORMAL; | ||
669 | else if (wx >= 0x7f800000) | ||
670 | retval = wx > 0x7f800000 ? FP_NAN : FP_INFINITE; | ||
671 | |||
672 | return retval; | ||
673 | } | ||
674 | |||
675 | |||
676 | int | ||
677 | __isinff (float x) | ||
678 | { | ||
679 | int32_t ix,t; | ||
680 | GET_FLOAT_WORD(ix,x); | ||
681 | t = ix & 0x7fffffff; | ||
682 | t ^= 0x7f800000; | ||
683 | t |= -t; | ||
684 | return ~(t >> 31) & (ix >> 30); | ||
685 | } | ||
686 | |||
687 | /* Return nonzero value if arguments are unordered. */ | ||
688 | #define fpclassify(x) \ | ||
689 | (sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassifyf (x)) | ||
690 | |||
691 | #ifndef isunordered | ||
692 | #define isunordered(u, v) \ | ||
693 | (__extension__ \ | ||
694 | ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \ | ||
695 | fpclassify (__u) == FP_NAN || fpclassify (__v) == FP_NAN; })) | ||
696 | #endif | ||
697 | |||
698 | /* Return nonzero value if X is less than Y. */ | ||
699 | #ifndef isless | ||
700 | #define isless(x, y) \ | ||
701 | (__extension__ \ | ||
702 | ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ | ||
703 | !isunordered (__x, __y) && __x < __y; })) | ||
704 | #endif | ||
705 | |||
706 | /* Return nonzero value if X is greater than Y. */ | ||
707 | #ifndef isgreater | ||
708 | #define isgreater(x, y) \ | ||
709 | (__extension__ \ | ||
710 | ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ | ||
711 | !isunordered (__x, __y) && __x > __y; })) | ||
712 | #endif | ||
713 | |||
714 | float rb_exp(float x) | ||
715 | { | ||
716 | static const float himark = 88.72283935546875; | ||
717 | static const float lomark = -103.972084045410; | ||
718 | /* Check for usual case. */ | ||
719 | if (isless (x, himark) && isgreater (x, lomark)) | ||
720 | { | ||
721 | static const float THREEp42 = 13194139533312.0; | ||
722 | static const float THREEp22 = 12582912.0; | ||
723 | /* 1/ln(2). */ | ||
724 | #undef M_1_LN2 | ||
725 | static const float M_1_LN2 = 1.44269502163f; | ||
726 | /* ln(2) */ | ||
727 | #undef M_LN2 | ||
728 | static const double M_LN2 = .6931471805599452862; | ||
729 | |||
730 | int tval; | ||
731 | double x22, t, result, dx; | ||
732 | float n, delta; | ||
733 | union ieee754_double ex2_u; | ||
734 | #ifndef ROCKBOX | ||
735 | fenv_t oldenv; | ||
736 | |||
737 | feholdexcept (&oldenv); | ||
738 | #endif | ||
739 | |||
740 | #ifdef FE_TONEAREST | ||
741 | fesetround (FE_TONEAREST); | ||
742 | #endif | ||
743 | |||
744 | /* Calculate n. */ | ||
745 | n = x * M_1_LN2 + THREEp22; | ||
746 | n -= THREEp22; | ||
747 | dx = x - n*M_LN2; | ||
748 | |||
749 | /* Calculate t/512. */ | ||
750 | t = dx + THREEp42; | ||
751 | t -= THREEp42; | ||
752 | dx -= t; | ||
753 | |||
754 | /* Compute tval = t. */ | ||
755 | tval = (int) (t * 512.0); | ||
756 | |||
757 | if (t >= 0) | ||
758 | delta = - __exp_deltatable[tval]; | ||
759 | else | ||
760 | delta = __exp_deltatable[-tval]; | ||
761 | |||
762 | /* Compute ex2 = 2^n e^(t/512+delta[t]). */ | ||
763 | ex2_u.d = __exp_atable[tval+177]; | ||
764 | ex2_u.ieee.exponent += (int) n; | ||
765 | |||
766 | /* Approximate e^(dx+delta) - 1, using a second-degree polynomial, | ||
767 | with maximum error in [-2^-10-2^-28,2^-10+2^-28] | ||
768 | less than 5e-11. */ | ||
769 | x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta; | ||
770 | |||
771 | /* Return result. */ | ||
772 | #ifndef ROCKBOX | ||
773 | fesetenv (&oldenv); | ||
774 | #endif | ||
775 | |||
776 | result = x22 * ex2_u.d + ex2_u.d; | ||
777 | return (float) result; | ||
778 | } | ||
779 | /* Exceptional cases: */ | ||
780 | else if (isless (x, himark)) | ||
781 | { | ||
782 | if (__isinff (x)) | ||
783 | /* e^-inf == 0, with no error. */ | ||
784 | return 0; | ||
785 | else | ||
786 | /* Underflow */ | ||
787 | return TWOM100 * TWOM100; | ||
788 | } | ||
789 | else | ||
790 | /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ | ||
791 | return TWO127*x; | ||
792 | } | ||
793 | |||
794 | /* Arc tangent, | ||
795 | taken from glibc-2.8. */ | ||
796 | |||
797 | static const float atanhi[] = { | ||
798 | 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ | ||
799 | 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ | ||
800 | 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ | ||
801 | 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ | ||
802 | }; | ||
803 | |||
804 | static const float atanlo[] = { | ||
805 | 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ | ||
806 | 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ | ||
807 | 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ | ||
808 | 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ | ||
809 | }; | ||
810 | |||
811 | static const float aT[] = { | ||
812 | 3.3333334327e-01, /* 0x3eaaaaaa */ | ||
813 | -2.0000000298e-01, /* 0xbe4ccccd */ | ||
814 | 1.4285714924e-01, /* 0x3e124925 */ | ||
815 | -1.1111110449e-01, /* 0xbde38e38 */ | ||
816 | 9.0908870101e-02, /* 0x3dba2e6e */ | ||
817 | -7.6918758452e-02, /* 0xbd9d8795 */ | ||
818 | 6.6610731184e-02, /* 0x3d886b35 */ | ||
819 | -5.8335702866e-02, /* 0xbd6ef16b */ | ||
820 | 4.9768779427e-02, /* 0x3d4bda59 */ | ||
821 | -3.6531571299e-02, /* 0xbd15a221 */ | ||
822 | 1.6285819933e-02, /* 0x3c8569d7 */ | ||
823 | }; | ||
824 | |||
825 | static const float | ||
826 | huge = 1.0e+30, | ||
827 | tiny = 1.0e-30, | ||
828 | one = 1.0f; | ||
829 | |||
830 | float atan_wrapper(float x) | ||
831 | { | ||
832 | float w,s1,s2,z; | ||
833 | int32_t ix,hx,id; | ||
834 | |||
835 | GET_FLOAT_WORD(hx,x); | ||
836 | ix = hx&0x7fffffff; | ||
837 | if(ix>=0x50800000) { /* if |x| >= 2^34 */ | ||
838 | if(ix>0x7f800000) | ||
839 | return x+x; /* NaN */ | ||
840 | if(hx>0) return atanhi[3]+atanlo[3]; | ||
841 | else return -atanhi[3]-atanlo[3]; | ||
842 | } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ | ||
843 | if (ix < 0x31000000) { /* |x| < 2^-29 */ | ||
844 | if(huge+x>one) return x; /* raise inexact */ | ||
845 | } | ||
846 | id = -1; | ||
847 | } else { | ||
848 | x = fabs_wrapper(x); | ||
849 | if (ix < 0x3f980000) { /* |x| < 1.1875 */ | ||
850 | if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ | ||
851 | id = 0; x = ((float)2.0*x-one)/((float)2.0+x); | ||
852 | } else { /* 11/16<=|x|< 19/16 */ | ||
853 | id = 1; x = (x-one)/(x+one); | ||
854 | } | ||
855 | } else { | ||
856 | if (ix < 0x401c0000) { /* |x| < 2.4375 */ | ||
857 | id = 2; x = (x-(float)1.5)/(one+(float)1.5*x); | ||
858 | } else { /* 2.4375 <= |x| < 2^66 */ | ||
859 | id = 3; x = -(float)1.0/x; | ||
860 | } | ||
861 | }} | ||
862 | /* end of argument reduction */ | ||
863 | z = x*x; | ||
864 | w = z*z; | ||
865 | /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ | ||
866 | s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); | ||
867 | s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); | ||
868 | if (id<0) return x - x*(s1+s2); | ||
869 | else { | ||
870 | z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); | ||
871 | return (hx<0)? -z:z; | ||
872 | } | ||
873 | } | ||
874 | |||
875 | /* Arc tangent from two variables, original. */ | ||
876 | |||
877 | static const float | ||
878 | pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */ | ||
879 | pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */ | ||
880 | pi = 3.1415927410e+00, /* 0x40490fdb */ | ||
881 | pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */ | ||
882 | |||
883 | float atan2_wrapper(float y, float x) | ||
884 | { | ||
885 | float z; | ||
886 | int32_t k,m,hx,hy,ix,iy; | ||
887 | |||
888 | GET_FLOAT_WORD(hx,x); | ||
889 | ix = hx&0x7fffffff; | ||
890 | GET_FLOAT_WORD(hy,y); | ||
891 | iy = hy&0x7fffffff; | ||
892 | if((ix>0x7f800000)|| | ||
893 | (iy>0x7f800000)) /* x or y is NaN */ | ||
894 | return x+y; | ||
895 | if(hx==0x3f800000) return atan_wrapper(y); /* x=1.0 */ | ||
896 | m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ | ||
897 | |||
898 | /* when y = 0 */ | ||
899 | if(iy==0) { | ||
900 | switch(m) { | ||
901 | case 0: | ||
902 | case 1: return y; /* atan(+-0,+anything)=+-0 */ | ||
903 | case 2: return pi+tiny;/* atan(+0,-anything) = pi */ | ||
904 | case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ | ||
905 | } | ||
906 | } | ||
907 | /* when x = 0 */ | ||
908 | if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; | ||
909 | |||
910 | /* when x is INF */ | ||
911 | if(ix==0x7f800000) { | ||
912 | if(iy==0x7f800000) { | ||
913 | switch(m) { | ||
914 | case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ | ||
915 | case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ | ||
916 | case 2: return (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ | ||
917 | case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ | ||
918 | } | ||
919 | } else { | ||
920 | switch(m) { | ||
921 | case 0: return zero ; /* atan(+...,+INF) */ | ||
922 | case 1: return -zero ; /* atan(-...,+INF) */ | ||
923 | case 2: return pi+tiny ; /* atan(+...,-INF) */ | ||
924 | case 3: return -pi-tiny ; /* atan(-...,-INF) */ | ||
925 | } | ||
926 | } | ||
927 | } | ||
928 | /* when y is INF */ | ||
929 | if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; | ||
930 | |||
931 | /* compute y/x */ | ||
932 | k = (iy-ix)>>23; | ||
933 | if(k > 60) z=pi_o_2+(float)0.5*pi_lo; /* |y/x| > 2**60 */ | ||
934 | else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ | ||
935 | else z=atan_wrapper(fabs_wrapper(y/x)); /* safe to do y/x */ | ||
936 | switch (m) { | ||
937 | case 0: return z ; /* atan(+,+) */ | ||
938 | case 1: { | ||
939 | uint32_t zh; | ||
940 | GET_FLOAT_WORD(zh,z); | ||
941 | SET_FLOAT_WORD(z,zh ^ 0x80000000); | ||
942 | } | ||
943 | return z ; /* atan(-,+) */ | ||
944 | case 2: return pi-(z-pi_lo);/* atan(+,-) */ | ||
945 | default: /* case 3 */ | ||
946 | return (z-pi_lo)-pi;/* atan(-,-) */ | ||
947 | } | ||
948 | } | ||
949 | |||
950 | /* Square root function, original. */ | ||
951 | float sqrt_wrapper(float x) | ||
952 | { | ||
953 | float z; | ||
954 | int32_t sign = (int)0x80000000; | ||
955 | int32_t ix,s,q,m,t,i; | ||
956 | uint32_t r; | ||
957 | |||
958 | GET_FLOAT_WORD(ix,x); | ||
959 | |||
960 | /* take care of Inf and NaN */ | ||
961 | if((ix&0x7f800000)==0x7f800000) { | ||
962 | return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf | ||
963 | sqrt(-inf)=sNaN */ | ||
964 | } | ||
965 | /* take care of zero */ | ||
966 | if(ix<=0) { | ||
967 | if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ | ||
968 | else if(ix<0) | ||
969 | return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ | ||
970 | } | ||
971 | /* normalize x */ | ||
972 | m = (ix>>23); | ||
973 | if(m==0) { /* subnormal x */ | ||
974 | for(i=0;(ix&0x00800000)==0;i++) ix<<=1; | ||
975 | m -= i-1; | ||
976 | } | ||
977 | m -= 127; /* unbias exponent */ | ||
978 | ix = (ix&0x007fffff)|0x00800000; | ||
979 | if(m&1) /* odd m, double x to make it even */ | ||
980 | ix += ix; | ||
981 | m >>= 1; /* m = [m/2] */ | ||
982 | |||
983 | /* generate sqrt(x) bit by bit */ | ||
984 | ix += ix; | ||
985 | q = s = 0; /* q = sqrt(x) */ | ||
986 | r = 0x01000000; /* r = moving bit from right to left */ | ||
987 | |||
988 | while(r!=0) { | ||
989 | t = s+r; | ||
990 | if(t<=ix) { | ||
991 | s = t+r; | ||
992 | ix -= t; | ||
993 | q += r; | ||
994 | } | ||
995 | ix += ix; | ||
996 | r>>=1; | ||
997 | } | ||
998 | |||
999 | /* use floating add to find out rounding direction */ | ||
1000 | if(ix!=0) { | ||
1001 | z = one-tiny; /* trigger inexact flag */ | ||
1002 | if (z>=one) { | ||
1003 | z = one+tiny; | ||
1004 | if (z>one) | ||
1005 | q += 2; | ||
1006 | else | ||
1007 | q += (q&1); | ||
1008 | } | ||
1009 | } | ||
1010 | ix = (q>>1)+0x3f000000; | ||
1011 | ix += (m <<23); | ||
1012 | SET_FLOAT_WORD(z,ix); | ||
1013 | return z; | ||
1014 | } | ||
1015 | |||
1016 | /* @(#)e_acos.c 1.3 95/01/18 */ | ||
1017 | /* | ||
1018 | * ==================================================== | ||
1019 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | ||
1020 | * | ||
1021 | * Developed at SunSoft, a Sun Microsystems, Inc. business. | ||
1022 | * Permission to use, copy, modify, and distribute this | ||
1023 | * software is freely granted, provided that this notice | ||
1024 | * is preserved. | ||
1025 | * ==================================================== | ||
1026 | */ | ||
1027 | |||
1028 | /* __ieee754_acos(x) | ||
1029 | * Method : | ||
1030 | * acos(x) = pi/2 - asin(x) | ||
1031 | * acos(-x) = pi/2 + asin(x) | ||
1032 | * For |x|<=0.5 | ||
1033 | * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) | ||
1034 | * For x>0.5 | ||
1035 | * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) | ||
1036 | * = 2asin(sqrt((1-x)/2)) | ||
1037 | * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) | ||
1038 | * = 2f + (2c + 2s*z*R(z)) | ||
1039 | * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term | ||
1040 | * for f so that f+c ~ sqrt(z). | ||
1041 | * For x<-0.5 | ||
1042 | * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) | ||
1043 | * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) | ||
1044 | * | ||
1045 | * Special cases: | ||
1046 | * if x is NaN, return x itself; | ||
1047 | * if |x|>1, return NaN with invalid signal. | ||
1048 | * | ||
1049 | * Function needed: sqrt | ||
1050 | */ | ||
1051 | |||
1052 | #ifdef __STDC__ | ||
1053 | static const double | ||
1054 | #else | ||
1055 | static double | ||
1056 | #endif | ||
1057 | pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ | ||
1058 | pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ | ||
1059 | pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ | ||
1060 | pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ | ||
1061 | pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ | ||
1062 | pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ | ||
1063 | pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ | ||
1064 | pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ | ||
1065 | qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ | ||
1066 | qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ | ||
1067 | qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ | ||
1068 | qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ | ||
1069 | |||
1070 | double acos_wrapper(double x) | ||
1071 | { | ||
1072 | double z,p,q,r,w,s,c,df; | ||
1073 | int hx,ix; | ||
1074 | hx = __HI(x); | ||
1075 | ix = hx&0x7fffffff; | ||
1076 | if(ix>=0x3ff00000) { /* |x| >= 1 */ | ||
1077 | if(((ix-0x3ff00000)|__LO(x))==0) { /* |x|==1 */ | ||
1078 | if(hx>0) return 0.0; /* acos(1) = 0 */ | ||
1079 | else return pi+2.0*pio2_lo; /* acos(-1)= pi */ | ||
1080 | } | ||
1081 | return (x-x)/(x-x); /* acos(|x|>1) is NaN */ | ||
1082 | } | ||
1083 | if(ix<0x3fe00000) { /* |x| < 0.5 */ | ||
1084 | if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ | ||
1085 | z = x*x; | ||
1086 | p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); | ||
1087 | q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); | ||
1088 | r = p/q; | ||
1089 | return pio2_hi - (x - (pio2_lo-x*r)); | ||
1090 | } else if (hx<0) { /* x < -0.5 */ | ||
1091 | z = (one+x)*0.5; | ||
1092 | p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); | ||
1093 | q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); | ||
1094 | s = sqrt_wrapper(z); | ||
1095 | r = p/q; | ||
1096 | w = r*s-pio2_lo; | ||
1097 | return pi - 2.0*(s+w); | ||
1098 | } else { /* x > 0.5 */ | ||
1099 | z = (one-x)*0.5; | ||
1100 | s = sqrt_wrapper(z); | ||
1101 | df = s; | ||
1102 | __LO(df) = 0; | ||
1103 | c = (z-df*df)/(s+df); | ||
1104 | p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); | ||
1105 | q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); | ||
1106 | r = p/q; | ||
1107 | w = r*s+c; | ||
1108 | return 2.0*(df+w); | ||
1109 | } | ||
1110 | |||
1111 | } | ||
1112 | |||
1113 | /* | ||
1114 | * Copyright (C) 2004 by egnite Software GmbH. All rights reserved. | ||
1115 | * | ||
1116 | * Redistribution and use in source and binary forms, with or without | ||
1117 | * modification, are permitted provided that the following conditions | ||
1118 | * are met: | ||
1119 | * | ||
1120 | * 1. Redistributions of source code must retain the above copyright | ||
1121 | * notice, this list of conditions and the following disclaimer. | ||
1122 | * 2. Redistributions in binary form must reproduce the above copyright | ||
1123 | * notice, this list of conditions and the following disclaimer in the | ||
1124 | * documentation and/or other materials provided with the distribution. | ||
1125 | * 3. Neither the name of the copyright holders nor the names of | ||
1126 | * contributors may be used to endorse or promote products derived | ||
1127 | * from this software without specific prior written permission. | ||
1128 | * | ||
1129 | * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS | ||
1130 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
1131 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
1132 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE | ||
1133 | * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
1134 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
1135 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
1136 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
1137 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
1138 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | ||
1139 | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
1140 | * SUCH DAMAGE. | ||
1141 | * | ||
1142 | * For additional information see http://www.ethernut.de/ | ||
1143 | * | ||
1144 | *- | ||
1145 | * Copyright (c) 1990 The Regents of the University of California. | ||
1146 | * All rights reserved. | ||
1147 | * | ||
1148 | * Redistribution and use in source and binary forms, with or without | ||
1149 | * modification, are permitted provided that the following conditions | ||
1150 | * are met: | ||
1151 | * 1. Redistributions of source code must retain the above copyright | ||
1152 | * notice, this list of conditions and the following disclaimer. | ||
1153 | * 2. Redistributions in binary form must reproduce the above copyright | ||
1154 | * notice, this list of conditions and the following disclaimer in the | ||
1155 | * documentation and/or other materials provided with the distribution. | ||
1156 | * 3. Neither the name of the University nor the names of its contributors | ||
1157 | * may be used to endorse or promote products derived from this software | ||
1158 | * without specific prior written permission. | ||
1159 | * | ||
1160 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
1161 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
1162 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
1163 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
1164 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
1165 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
1166 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
1167 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
1168 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
1169 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
1170 | * SUCH DAMAGE. | ||
1171 | */ | ||
1172 | |||
1173 | /* | ||
1174 | * $Log$ | ||
1175 | * Revision 1.4 2008/02/15 17:13:01 haraldkipp | ||
1176 | * Use configurable constant attribute. | ||
1177 | * | ||
1178 | * Revision 1.3 2006/10/08 16:48:08 haraldkipp | ||
1179 | * Documentation fixed | ||
1180 | * | ||
1181 | * Revision 1.2 2005/08/02 17:46:47 haraldkipp | ||
1182 | * Major API documentation update. | ||
1183 | * | ||
1184 | * Revision 1.1 2004/09/08 10:23:35 haraldkipp | ||
1185 | * Generic C stdlib added | ||
1186 | * | ||
1187 | */ | ||
1188 | |||
1189 | #define CONST const | ||
1190 | long strtol_wrapper(CONST char *nptr, char **endptr, int base) | ||
1191 | { | ||
1192 | register CONST char *s; | ||
1193 | register long acc, cutoff; | ||
1194 | register int c; | ||
1195 | register int neg, any, cutlim; | ||
1196 | |||
1197 | /* | ||
1198 | * Skip white space and pick up leading +/- sign if any. | ||
1199 | * If base is 0, allow 0x for hex and 0 for octal, else | ||
1200 | * assume decimal; if base is already 16, allow 0x. | ||
1201 | */ | ||
1202 | s = nptr; | ||
1203 | do { | ||
1204 | c = (unsigned char) *s++; | ||
1205 | } while (isspace(c)); | ||
1206 | if (c == '-') { | ||
1207 | neg = 1; | ||
1208 | c = *s++; | ||
1209 | } else { | ||
1210 | neg = 0; | ||
1211 | if (c == '+') | ||
1212 | c = *s++; | ||
1213 | } | ||
1214 | if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { | ||
1215 | c = s[1]; | ||
1216 | s += 2; | ||
1217 | base = 16; | ||
1218 | } | ||
1219 | if (base == 0) | ||
1220 | base = c == '0' ? 8 : 10; | ||
1221 | |||
1222 | /* | ||
1223 | * Compute the cutoff value between legal numbers and illegal | ||
1224 | * numbers. That is the largest legal value, divided by the | ||
1225 | * base. An input number that is greater than this value, if | ||
1226 | * followed by a legal input character, is too big. One that | ||
1227 | * is equal to this value may be valid or not; the limit | ||
1228 | * between valid and invalid numbers is then based on the last | ||
1229 | * digit. For instance, if the range for longs is | ||
1230 | * [-2147483648..2147483647] and the input base is 10, | ||
1231 | * cutoff will be set to 214748364 and cutlim to either | ||
1232 | * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated | ||
1233 | * a value > 214748364, or equal but the next digit is > 7 (or 8), | ||
1234 | * the number is too big, and we will return a range error. | ||
1235 | * | ||
1236 | * Set any if any `digits' consumed; make it negative to indicate | ||
1237 | * overflow. | ||
1238 | */ | ||
1239 | cutoff = neg ? LONG_MIN : LONG_MAX; | ||
1240 | cutlim = cutoff % base; | ||
1241 | cutoff /= base; | ||
1242 | if (neg) { | ||
1243 | if (cutlim > 0) { | ||
1244 | cutlim -= base; | ||
1245 | cutoff += 1; | ||
1246 | } | ||
1247 | cutlim = -cutlim; | ||
1248 | } | ||
1249 | for (acc = 0, any = 0;; c = (unsigned char) *s++) { | ||
1250 | if (isdigit(c)) | ||
1251 | c -= '0'; | ||
1252 | else if (isalpha(c)) | ||
1253 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; | ||
1254 | else | ||
1255 | break; | ||
1256 | if (c >= base) | ||
1257 | break; | ||
1258 | if (any < 0) | ||
1259 | continue; | ||
1260 | if (neg) { | ||
1261 | if ((acc < cutoff || acc == cutoff) && c > cutlim) { | ||
1262 | any = -1; | ||
1263 | acc = LONG_MIN; | ||
1264 | } else { | ||
1265 | any = 1; | ||
1266 | acc *= base; | ||
1267 | acc -= c; | ||
1268 | } | ||
1269 | } else { | ||
1270 | if ((acc > cutoff || acc == cutoff) && c > cutlim) { | ||
1271 | any = -1; | ||
1272 | acc = LONG_MAX; | ||
1273 | } else { | ||
1274 | any = 1; | ||
1275 | acc *= base; | ||
1276 | acc += c; | ||
1277 | } | ||
1278 | } | ||
1279 | } | ||
1280 | if (endptr != 0) | ||
1281 | *endptr = (char *) (any ? s - 1 : nptr); | ||
1282 | return (acc); | ||
1283 | } | ||
1284 | |||
1285 | int64_t strtoq_wrapper(CONST char *nptr, char **endptr, int base) | ||
1286 | { | ||
1287 | return strtol(nptr, endptr, base); | ||
1288 | } | ||
1289 | |||
1290 | uint64_t strtouq_wrapper(CONST char *nptr, char **endptr, int base) | ||
1291 | { | ||
1292 | return strtol(nptr, endptr, base); | ||
1293 | } | ||
1294 | |||
1295 | /* Power function, taken from glibc-2.8 and dietlibc-0.32 */ | ||
1296 | float pow_wrapper(float x, float y) | ||
1297 | { | ||
1298 | unsigned int e; | ||
1299 | float result; | ||
1300 | |||
1301 | /* Special cases 0^x */ | ||
1302 | if(x == 0.0f) | ||
1303 | { | ||
1304 | if(y > 0.0f) | ||
1305 | return 0.0f; | ||
1306 | else if(y == 0.0f) | ||
1307 | return 1.0f; | ||
1308 | else | ||
1309 | return 1.0f / x; | ||
1310 | } | ||
1311 | |||
1312 | /* Special case x^n where n is integer */ | ||
1313 | if(y == (int) (e = (int) y)) | ||
1314 | { | ||
1315 | if((int) e < 0) | ||
1316 | { | ||
1317 | e = -e; | ||
1318 | x = 1.0f / x; | ||
1319 | } | ||
1320 | |||
1321 | result = 1.0f; | ||
1322 | |||
1323 | while(1) | ||
1324 | { | ||
1325 | if(e & 1) | ||
1326 | result *= x; | ||
1327 | |||
1328 | if((e >>= 1) == 0) | ||
1329 | break; | ||
1330 | |||
1331 | x *= x; | ||
1332 | } | ||
1333 | |||
1334 | return result; | ||
1335 | } | ||
1336 | |||
1337 | /* Normal case */ | ||
1338 | return rb_exp(rb_log(x) * y); | ||
1339 | } | ||
1340 | |||
1341 | /* @(#)s_copysign.c 1.3 95/01/18 */ | ||
1342 | /* | ||
1343 | * ==================================================== | ||
1344 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | ||
1345 | * | ||
1346 | * Developed at SunSoft, a Sun Microsystems, Inc. business. | ||
1347 | * Permission to use, copy, modify, and distribute this | ||
1348 | * software is freely granted, provided that this notice | ||
1349 | * is preserved. | ||
1350 | * ==================================================== | ||
1351 | */ | ||
1352 | |||
1353 | /* | ||
1354 | * copysign(double x, double y) | ||
1355 | * copysign(x,y) returns a value with the magnitude of x and | ||
1356 | * with the sign bit of y. | ||
1357 | */ | ||
1358 | |||
1359 | double copysign_wrapper(double x, double y) | ||
1360 | { | ||
1361 | __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000); | ||
1362 | return x; | ||
1363 | } | ||
1364 | |||
1365 | /* @(#)s_scalbn.c 1.3 95/01/18 */ | ||
1366 | /* | ||
1367 | * ==================================================== | ||
1368 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | ||
1369 | * | ||
1370 | * Developed at SunSoft, a Sun Microsystems, Inc. business. | ||
1371 | * Permission to use, copy, modify, and distribute this | ||
1372 | * software is freely granted, provided that this notice | ||
1373 | * is preserved. | ||
1374 | * ==================================================== | ||
1375 | */ | ||
1376 | |||
1377 | /* | ||
1378 | * scalbn (double x, int n) | ||
1379 | * scalbn(x,n) returns x* 2**n computed by exponent | ||
1380 | * manipulation rather than by actually performing an | ||
1381 | * exponentiation or a multiplication. | ||
1382 | */ | ||
1383 | |||
1384 | #ifdef __STDC__ | ||
1385 | static const double | ||
1386 | #else | ||
1387 | static double | ||
1388 | #endif | ||
1389 | two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ | ||
1390 | twom54 = 5.55111512312578270212e-17; /* 0x3C900000, 0x00000000 */ | ||
1391 | |||
1392 | double scalbn_wrapper (double x, int n) | ||
1393 | { | ||
1394 | int k,hx,lx; | ||
1395 | hx = __HI(x); | ||
1396 | lx = __LO(x); | ||
1397 | k = (hx&0x7ff00000)>>20; /* extract exponent */ | ||
1398 | if (k==0) { /* 0 or subnormal x */ | ||
1399 | if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ | ||
1400 | x *= two54; | ||
1401 | hx = __HI(x); | ||
1402 | k = ((hx&0x7ff00000)>>20) - 54; | ||
1403 | if (n< -50000) return tiny*x; /*underflow*/ | ||
1404 | } | ||
1405 | if (k==0x7ff) return x+x; /* NaN or Inf */ | ||
1406 | k = k+n; | ||
1407 | if (k > 0x7fe) return huge*copysign_wrapper(huge,x); /* overflow */ | ||
1408 | if (k > 0) /* normal result */ | ||
1409 | {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} | ||
1410 | if (k <= -54) | ||
1411 | if (n > 50000) /* in case integer overflow in n+k */ | ||
1412 | return huge*copysign_wrapper(huge,x); /*overflow*/ | ||
1413 | else return tiny*copysign_wrapper(tiny,x); /*underflow*/ | ||
1414 | k += 54; /* subnormal result */ | ||
1415 | __HI(x) = (hx&0x800fffff)|(k<<20); | ||
1416 | return x*twom54; | ||
1417 | } | ||
1418 | |||
1419 | /* horrible hack */ | ||
1420 | float ceil_wrapper(float x) | ||
1421 | { | ||
1422 | return floor_wrapper(x) + 1.0; | ||
1423 | } | ||
1424 | |||
1425 | /* Implementation of strtod() and atof(), | ||
1426 | taken from SanOS (http://www.jbox.dk/sanos/). */ | ||
1427 | static int rb_errno = 0; | ||
1428 | |||
1429 | static double rb_strtod(const char *str, char **endptr) | ||
1430 | { | ||
1431 | double number; | ||
1432 | int exponent; | ||
1433 | int negative; | ||
1434 | char *p = (char *) str; | ||
1435 | double p10; | ||
1436 | int n; | ||
1437 | int num_digits; | ||
1438 | int num_decimals; | ||
1439 | |||
1440 | /* Reset Rockbox errno -- W.B. */ | ||
1441 | #ifdef ROCKBOX | ||
1442 | rb_errno = 0; | ||
1443 | #endif | ||
1444 | |||
1445 | // Skip leading whitespace | ||
1446 | while (isspace(*p)) p++; | ||
1447 | |||
1448 | // Handle optional sign | ||
1449 | negative = 0; | ||
1450 | switch (*p) | ||
1451 | { | ||
1452 | case '-': negative = 1; // Fall through to increment position | ||
1453 | case '+': p++; | ||
1454 | } | ||
1455 | |||
1456 | number = 0.; | ||
1457 | exponent = 0; | ||
1458 | num_digits = 0; | ||
1459 | num_decimals = 0; | ||
1460 | |||
1461 | // Process string of digits | ||
1462 | while (isdigit(*p)) | ||
1463 | { | ||
1464 | number = number * 10. + (*p - '0'); | ||
1465 | p++; | ||
1466 | num_digits++; | ||
1467 | } | ||
1468 | |||
1469 | // Process decimal part | ||
1470 | if (*p == '.') | ||
1471 | { | ||
1472 | p++; | ||
1473 | |||
1474 | while (isdigit(*p)) | ||
1475 | { | ||
1476 | number = number * 10. + (*p - '0'); | ||
1477 | p++; | ||
1478 | num_digits++; | ||
1479 | num_decimals++; | ||
1480 | } | ||
1481 | |||
1482 | exponent -= num_decimals; | ||
1483 | } | ||
1484 | |||
1485 | if (num_digits == 0) | ||
1486 | { | ||
1487 | #ifdef ROCKBOX | ||
1488 | rb_errno = 1; | ||
1489 | #else | ||
1490 | errno = ERANGE; | ||
1491 | #endif | ||
1492 | return 0.0; | ||
1493 | } | ||
1494 | |||
1495 | // Correct for sign | ||
1496 | if (negative) number = -number; | ||
1497 | |||
1498 | // Process an exponent string | ||
1499 | if (*p == 'e' || *p == 'E') | ||
1500 | { | ||
1501 | // Handle optional sign | ||
1502 | negative = 0; | ||
1503 | switch(*++p) | ||
1504 | { | ||
1505 | case '-': negative = 1; // Fall through to increment pos | ||
1506 | case '+': p++; | ||
1507 | } | ||
1508 | |||
1509 | // Process string of digits | ||
1510 | n = 0; | ||
1511 | while (isdigit(*p)) | ||
1512 | { | ||
1513 | n = n * 10 + (*p - '0'); | ||
1514 | p++; | ||
1515 | } | ||
1516 | |||
1517 | if (negative) | ||
1518 | exponent -= n; | ||
1519 | else | ||
1520 | exponent += n; | ||
1521 | } | ||
1522 | |||
1523 | #ifndef ROCKBOX | ||
1524 | if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) | ||
1525 | { | ||
1526 | errno = ERANGE; | ||
1527 | return HUGE_VAL; | ||
1528 | } | ||
1529 | #endif | ||
1530 | |||
1531 | // Scale the result | ||
1532 | p10 = 10.; | ||
1533 | n = exponent; | ||
1534 | if (n < 0) n = -n; | ||
1535 | while (n) | ||
1536 | { | ||
1537 | if (n & 1) | ||
1538 | { | ||
1539 | if (exponent < 0) | ||
1540 | number /= p10; | ||
1541 | else | ||
1542 | number *= p10; | ||
1543 | } | ||
1544 | n >>= 1; | ||
1545 | p10 *= p10; | ||
1546 | } | ||
1547 | |||
1548 | #ifndef ROCKBOX | ||
1549 | if (number == HUGE_VAL) errno = ERANGE; | ||
1550 | #endif | ||
1551 | if (endptr) *endptr = p; | ||
1552 | |||
1553 | return number; | ||
1554 | } | ||
1555 | |||
1556 | double atof_wrapper(const char *str) | ||
1557 | { | ||
1558 | return rb_strtod(str, NULL); | ||
1559 | } | ||
1560 | |||
1561 | /* | ||
1562 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. | ||
1563 | * | ||
1564 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | ||
1565 | * | ||
1566 | * This file contains Original Code and/or Modifications of Original Code | ||
1567 | * as defined in and that are subject to the Apple Public Source License | ||
1568 | * Version 2.0 (the 'License'). You may not use this file except in | ||
1569 | * compliance with the License. The rights granted to you under the License | ||
1570 | * may not be used to create, or enable the creation or redistribution of, | ||
1571 | * unlawful or unlicensed copies of an Apple operating system, or to | ||
1572 | * circumvent, violate, or enable the circumvention or violation of, any | ||
1573 | * terms of an Apple operating system software license agreement. | ||
1574 | * | ||
1575 | * Please obtain a copy of the License at | ||
1576 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | ||
1577 | * | ||
1578 | * The Original Code and all software distributed under the License are | ||
1579 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | ||
1580 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | ||
1581 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | ||
1582 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | ||
1583 | * Please see the License for the specific language governing rights and | ||
1584 | * limitations under the License. | ||
1585 | * | ||
1586 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | ||
1587 | */ | ||
1588 | /*- | ||
1589 | * Copyright (c) 1990, 1993 | ||
1590 | * The Regents of the University of California. All rights reserved. | ||
1591 | * | ||
1592 | * This code is derived from software contributed to Berkeley by | ||
1593 | * Chris Torek. | ||
1594 | * | ||
1595 | * Redistribution and use in source and binary forms, with or without | ||
1596 | * modification, are permitted provided that the following conditions | ||
1597 | * are met: | ||
1598 | * 1. Redistributions of source code must retain the above copyright | ||
1599 | * notice, this list of conditions and the following disclaimer. | ||
1600 | * 2. Redistributions in binary form must reproduce the above copyright | ||
1601 | * notice, this list of conditions and the following disclaimer in the | ||
1602 | * documentation and/or other materials provided with the distribution. | ||
1603 | * 3. All advertising materials mentioning features or use of this software | ||
1604 | * must display the following acknowledgement: | ||
1605 | * This product includes software developed by the University of | ||
1606 | * California, Berkeley and its contributors. | ||
1607 | * 4. Neither the name of the University nor the names of its contributors | ||
1608 | * may be used to endorse or promote products derived from this software | ||
1609 | * without specific prior written permission. | ||
1610 | * | ||
1611 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
1612 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
1613 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
1614 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
1615 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
1616 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
1617 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
1618 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
1619 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
1620 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
1621 | * SUCH DAMAGE. | ||
1622 | */ | ||
1623 | |||
1624 | #include "rbcompat.h" | ||
1625 | |||
1626 | #define BUF 32 /* Maximum length of numeric string. */ | ||
1627 | |||
1628 | /* | ||
1629 | * Flags used during conversion. | ||
1630 | */ | ||
1631 | #define LONG 0x01 /* l: long or double */ | ||
1632 | #define SHORT 0x04 /* h: short */ | ||
1633 | #define SUPPRESS 0x08 /* *: suppress assignment */ | ||
1634 | #define POINTER 0x10 /* p: void * (as hex) */ | ||
1635 | #define NOSKIP 0x20 /* [ or c: do not skip blanks */ | ||
1636 | #define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */ | ||
1637 | #define SHORTSHORT 0x4000 /* hh: char */ | ||
1638 | #define UNSIGNED 0x8000 /* %[oupxX] conversions */ | ||
1639 | |||
1640 | /* | ||
1641 | * The following are used in numeric conversions only: | ||
1642 | * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point; | ||
1643 | * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. | ||
1644 | */ | ||
1645 | #define SIGNOK 0x40 /* +/- is (still) legal */ | ||
1646 | #define NDIGITS 0x80 /* no digits detected */ | ||
1647 | |||
1648 | #define DPTOK 0x100 /* (float) decimal point is still legal */ | ||
1649 | #define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */ | ||
1650 | |||
1651 | #define PFXOK 0x100 /* 0x prefix is (still) legal */ | ||
1652 | #define NZDIGITS 0x200 /* no zero digits detected */ | ||
1653 | |||
1654 | /* | ||
1655 | * Conversion types. | ||
1656 | */ | ||
1657 | #define CT_CHAR 0 /* %c conversion */ | ||
1658 | #define CT_CCL 1 /* %[...] conversion */ | ||
1659 | #define CT_STRING 2 /* %s conversion */ | ||
1660 | #define CT_INT 3 /* %[dioupxX] conversion */ | ||
1661 | |||
1662 | typedef unsigned char u_char; | ||
1663 | typedef uint64_t u_quad_t; | ||
1664 | |||
1665 | static const u_char *__sccl(char *, const u_char *); | ||
1666 | |||
1667 | void bcopy(const void *src, void *dst, size_t n) | ||
1668 | { | ||
1669 | memmove(dst, src, n); | ||
1670 | } | ||
1671 | |||
1672 | int | ||
1673 | sscanf_wrapper(const char *ibuf, const char *fmt, ...) | ||
1674 | { | ||
1675 | va_list ap; | ||
1676 | int ret; | ||
1677 | |||
1678 | va_start(ap, fmt); | ||
1679 | ret = vsscanf(ibuf, fmt, ap); | ||
1680 | va_end(ap); | ||
1681 | return(ret); | ||
1682 | } | ||
1683 | |||
1684 | int | ||
1685 | vsscanf(const char *inp, char const *fmt0, va_list ap) | ||
1686 | { | ||
1687 | int inr; | ||
1688 | const u_char *fmt = (const u_char *)fmt0; | ||
1689 | int c; /* character from format, or conversion */ | ||
1690 | size_t width; /* field width, or 0 */ | ||
1691 | char *p; /* points into all kinds of strings */ | ||
1692 | int n; /* handy integer */ | ||
1693 | int flags; /* flags as defined above */ | ||
1694 | char *p0; /* saves original value of p when necessary */ | ||
1695 | int nassigned; /* number of fields assigned */ | ||
1696 | int nconversions; /* number of conversions */ | ||
1697 | int nread; /* number of characters consumed from fp */ | ||
1698 | int base; /* base argument to conversion function */ | ||
1699 | char ccltab[256]; /* character class table for %[...] */ | ||
1700 | char buf[BUF]; /* buffer for numeric conversions */ | ||
1701 | |||
1702 | /* `basefix' is used to avoid `if' tests in the integer scanner */ | ||
1703 | static short basefix[17] = | ||
1704 | { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; | ||
1705 | |||
1706 | inr = strlen(inp); | ||
1707 | |||
1708 | nassigned = 0; | ||
1709 | nconversions = 0; | ||
1710 | nread = 0; | ||
1711 | base = 0; /* XXX just to keep gcc happy */ | ||
1712 | for (;;) { | ||
1713 | c = *fmt++; | ||
1714 | if (c == 0) | ||
1715 | return (nassigned); | ||
1716 | if (isspace(c)) { | ||
1717 | while (inr > 0 && isspace(*inp)) | ||
1718 | nread++, inr--, inp++; | ||
1719 | continue; | ||
1720 | } | ||
1721 | if (c != '%') | ||
1722 | goto literal; | ||
1723 | width = 0; | ||
1724 | flags = 0; | ||
1725 | /* | ||
1726 | * switch on the format. continue if done; | ||
1727 | * break once format type is derived. | ||
1728 | */ | ||
1729 | again: c = *fmt++; | ||
1730 | switch (c) { | ||
1731 | case '%': | ||
1732 | literal: | ||
1733 | if (inr <= 0) | ||
1734 | goto input_failure; | ||
1735 | if (*inp != c) | ||
1736 | goto match_failure; | ||
1737 | inr--, inp++; | ||
1738 | nread++; | ||
1739 | continue; | ||
1740 | |||
1741 | case '*': | ||
1742 | flags |= SUPPRESS; | ||
1743 | goto again; | ||
1744 | case 'l': | ||
1745 | if (flags & LONG) { | ||
1746 | flags &= ~LONG; | ||
1747 | flags |= LONGLONG; | ||
1748 | } else | ||
1749 | flags |= LONG; | ||
1750 | goto again; | ||
1751 | case 'q': | ||
1752 | flags |= LONGLONG; /* not quite */ | ||
1753 | goto again; | ||
1754 | case 'h': | ||
1755 | if (flags & SHORT) { | ||
1756 | flags &= ~SHORT; | ||
1757 | flags |= SHORTSHORT; | ||
1758 | } else | ||
1759 | flags |= SHORT; | ||
1760 | goto again; | ||
1761 | |||
1762 | case '0': case '1': case '2': case '3': case '4': | ||
1763 | case '5': case '6': case '7': case '8': case '9': | ||
1764 | width = width * 10 + c - '0'; | ||
1765 | goto again; | ||
1766 | |||
1767 | /* | ||
1768 | * Conversions. | ||
1769 | */ | ||
1770 | case 'd': | ||
1771 | c = CT_INT; | ||
1772 | base = 10; | ||
1773 | break; | ||
1774 | |||
1775 | case 'i': | ||
1776 | c = CT_INT; | ||
1777 | base = 0; | ||
1778 | break; | ||
1779 | |||
1780 | case 'o': | ||
1781 | c = CT_INT; | ||
1782 | flags |= UNSIGNED; | ||
1783 | base = 8; | ||
1784 | break; | ||
1785 | |||
1786 | case 'u': | ||
1787 | c = CT_INT; | ||
1788 | flags |= UNSIGNED; | ||
1789 | base = 10; | ||
1790 | break; | ||
1791 | |||
1792 | case 'X': | ||
1793 | case 'x': | ||
1794 | flags |= PFXOK; /* enable 0x prefixing */ | ||
1795 | c = CT_INT; | ||
1796 | flags |= UNSIGNED; | ||
1797 | base = 16; | ||
1798 | break; | ||
1799 | |||
1800 | case 's': | ||
1801 | c = CT_STRING; | ||
1802 | break; | ||
1803 | |||
1804 | case '[': | ||
1805 | fmt = __sccl(ccltab, fmt); | ||
1806 | flags |= NOSKIP; | ||
1807 | c = CT_CCL; | ||
1808 | break; | ||
1809 | |||
1810 | case 'c': | ||
1811 | flags |= NOSKIP; | ||
1812 | c = CT_CHAR; | ||
1813 | break; | ||
1814 | |||
1815 | case 'p': /* pointer format is like hex */ | ||
1816 | flags |= POINTER | PFXOK; | ||
1817 | c = CT_INT; | ||
1818 | flags |= UNSIGNED; | ||
1819 | base = 16; | ||
1820 | break; | ||
1821 | |||
1822 | case 'n': | ||
1823 | nconversions++; | ||
1824 | if (flags & SUPPRESS) /* ??? */ | ||
1825 | continue; | ||
1826 | if (flags & SHORTSHORT) | ||
1827 | *va_arg(ap, char *) = nread; | ||
1828 | else if (flags & SHORT) | ||
1829 | *va_arg(ap, short *) = nread; | ||
1830 | else if (flags & LONG) | ||
1831 | *va_arg(ap, long *) = nread; | ||
1832 | else if (flags & LONGLONG) | ||
1833 | *va_arg(ap, long long *) = nread; | ||
1834 | else | ||
1835 | *va_arg(ap, int *) = nread; | ||
1836 | continue; | ||
1837 | } | ||
1838 | |||
1839 | /* | ||
1840 | * We have a conversion that requires input. | ||
1841 | */ | ||
1842 | if (inr <= 0) | ||
1843 | goto input_failure; | ||
1844 | |||
1845 | /* | ||
1846 | * Consume leading white space, except for formats | ||
1847 | * that suppress this. | ||
1848 | */ | ||
1849 | if ((flags & NOSKIP) == 0) { | ||
1850 | while (isspace(*inp)) { | ||
1851 | nread++; | ||
1852 | if (--inr > 0) | ||
1853 | inp++; | ||
1854 | else | ||
1855 | goto input_failure; | ||
1856 | } | ||
1857 | /* | ||
1858 | * Note that there is at least one character in | ||
1859 | * the buffer, so conversions that do not set NOSKIP | ||
1860 | * can no longer result in an input failure. | ||
1861 | */ | ||
1862 | } | ||
1863 | |||
1864 | /* | ||
1865 | * Do the conversion. | ||
1866 | */ | ||
1867 | switch (c) { | ||
1868 | |||
1869 | case CT_CHAR: | ||
1870 | /* scan arbitrary characters (sets NOSKIP) */ | ||
1871 | if (width == 0) | ||
1872 | width = 1; | ||
1873 | if (flags & SUPPRESS) { | ||
1874 | size_t sum = 0; | ||
1875 | for (;;) { | ||
1876 | if ((n = inr) < (int)width) { | ||
1877 | sum += n; | ||
1878 | width -= n; | ||
1879 | inp += n; | ||
1880 | if (sum == 0) | ||
1881 | goto input_failure; | ||
1882 | break; | ||
1883 | } else { | ||
1884 | sum += width; | ||
1885 | inr -= width; | ||
1886 | inp += width; | ||
1887 | break; | ||
1888 | } | ||
1889 | } | ||
1890 | nread += sum; | ||
1891 | } else { | ||
1892 | bcopy(inp, va_arg(ap, char *), width); | ||
1893 | inr -= width; | ||
1894 | inp += width; | ||
1895 | nread += width; | ||
1896 | nassigned++; | ||
1897 | } | ||
1898 | nconversions++; | ||
1899 | break; | ||
1900 | |||
1901 | case CT_CCL: | ||
1902 | /* scan a (nonempty) character class (sets NOSKIP) */ | ||
1903 | if (width == 0) | ||
1904 | width = (size_t)~0; /* `infinity' */ | ||
1905 | /* take only those things in the class */ | ||
1906 | if (flags & SUPPRESS) { | ||
1907 | n = 0; | ||
1908 | while (ccltab[(unsigned char)*inp]) { | ||
1909 | n++, inr--, inp++; | ||
1910 | if (--width == 0) | ||
1911 | break; | ||
1912 | if (inr <= 0) { | ||
1913 | if (n == 0) | ||
1914 | goto input_failure; | ||
1915 | break; | ||
1916 | } | ||
1917 | } | ||
1918 | if (n == 0) | ||
1919 | goto match_failure; | ||
1920 | } else { | ||
1921 | p0 = p = va_arg(ap, char *); | ||
1922 | while (ccltab[(unsigned char)*inp]) { | ||
1923 | inr--; | ||
1924 | *p++ = *inp++; | ||
1925 | if (--width == 0) | ||
1926 | break; | ||
1927 | if (inr <= 0) { | ||
1928 | if (p == p0) | ||
1929 | goto input_failure; | ||
1930 | break; | ||
1931 | } | ||
1932 | } | ||
1933 | n = p - p0; | ||
1934 | if (n == 0) | ||
1935 | goto match_failure; | ||
1936 | *p = 0; | ||
1937 | nassigned++; | ||
1938 | } | ||
1939 | nread += n; | ||
1940 | nconversions++; | ||
1941 | break; | ||
1942 | |||
1943 | case CT_STRING: | ||
1944 | /* like CCL, but zero-length string OK, & no NOSKIP */ | ||
1945 | if (width == 0) | ||
1946 | width = (size_t)~0; | ||
1947 | if (flags & SUPPRESS) { | ||
1948 | n = 0; | ||
1949 | while (!isspace(*inp)) { | ||
1950 | n++, inr--, inp++; | ||
1951 | if (--width == 0) | ||
1952 | break; | ||
1953 | if (inr <= 0) | ||
1954 | break; | ||
1955 | } | ||
1956 | nread += n; | ||
1957 | } else { | ||
1958 | p0 = p = va_arg(ap, char *); | ||
1959 | while (!isspace(*inp)) { | ||
1960 | inr--; | ||
1961 | *p++ = *inp++; | ||
1962 | if (--width == 0) | ||
1963 | break; | ||
1964 | if (inr <= 0) | ||
1965 | break; | ||
1966 | } | ||
1967 | *p = 0; | ||
1968 | nread += p - p0; | ||
1969 | nassigned++; | ||
1970 | } | ||
1971 | nconversions++; | ||
1972 | continue; | ||
1973 | |||
1974 | case CT_INT: | ||
1975 | /* scan an integer as if by the conversion function */ | ||
1976 | #ifdef hardway | ||
1977 | if (width == 0 || width > sizeof(buf) - 1) | ||
1978 | width = sizeof(buf) - 1; | ||
1979 | #else | ||
1980 | /* size_t is unsigned, hence this optimisation */ | ||
1981 | if (--width > sizeof(buf) - 2) | ||
1982 | width = sizeof(buf) - 2; | ||
1983 | width++; | ||
1984 | #endif | ||
1985 | flags |= SIGNOK | NDIGITS | NZDIGITS; | ||
1986 | for (p = buf; width; width--) { | ||
1987 | c = *inp; | ||
1988 | /* | ||
1989 | * Switch on the character; `goto ok' | ||
1990 | * if we accept it as a part of number. | ||
1991 | */ | ||
1992 | switch (c) { | ||
1993 | |||
1994 | /* | ||
1995 | * The digit 0 is always legal, but is | ||
1996 | * special. For %i conversions, if no | ||
1997 | * digits (zero or nonzero) have been | ||
1998 | * scanned (only signs), we will have | ||
1999 | * base==0. In that case, we should set | ||
2000 | * it to 8 and enable 0x prefixing. | ||
2001 | * Also, if we have not scanned zero digits | ||
2002 | * before this, do not turn off prefixing | ||
2003 | * (someone else will turn it off if we | ||
2004 | * have scanned any nonzero digits). | ||
2005 | */ | ||
2006 | case '0': | ||
2007 | if (base == 0) { | ||
2008 | base = 8; | ||
2009 | flags |= PFXOK; | ||
2010 | } | ||
2011 | if (flags & NZDIGITS) | ||
2012 | flags &= ~(SIGNOK|NZDIGITS|NDIGITS); | ||
2013 | else | ||
2014 | flags &= ~(SIGNOK|PFXOK|NDIGITS); | ||
2015 | goto ok; | ||
2016 | |||
2017 | /* 1 through 7 always legal */ | ||
2018 | case '1': case '2': case '3': | ||
2019 | case '4': case '5': case '6': case '7': | ||
2020 | base = basefix[base]; | ||
2021 | flags &= ~(SIGNOK | PFXOK | NDIGITS); | ||
2022 | goto ok; | ||
2023 | |||
2024 | /* digits 8 and 9 ok iff decimal or hex */ | ||
2025 | case '8': case '9': | ||
2026 | base = basefix[base]; | ||
2027 | if (base <= 8) | ||
2028 | break; /* not legal here */ | ||
2029 | flags &= ~(SIGNOK | PFXOK | NDIGITS); | ||
2030 | goto ok; | ||
2031 | |||
2032 | /* letters ok iff hex */ | ||
2033 | case 'A': case 'B': case 'C': | ||
2034 | case 'D': case 'E': case 'F': | ||
2035 | case 'a': case 'b': case 'c': | ||
2036 | case 'd': case 'e': case 'f': | ||
2037 | /* no need to fix base here */ | ||
2038 | if (base <= 10) | ||
2039 | break; /* not legal here */ | ||
2040 | flags &= ~(SIGNOK | PFXOK | NDIGITS); | ||
2041 | goto ok; | ||
2042 | |||
2043 | /* sign ok only as first character */ | ||
2044 | case '+': case '-': | ||
2045 | if (flags & SIGNOK) { | ||
2046 | flags &= ~SIGNOK; | ||
2047 | goto ok; | ||
2048 | } | ||
2049 | break; | ||
2050 | |||
2051 | /* x ok iff flag still set & 2nd char */ | ||
2052 | case 'x': case 'X': | ||
2053 | if (flags & PFXOK && p == buf + 1) { | ||
2054 | base = 16; /* if %i */ | ||
2055 | flags &= ~PFXOK; | ||
2056 | goto ok; | ||
2057 | } | ||
2058 | break; | ||
2059 | } | ||
2060 | |||
2061 | /* | ||
2062 | * If we got here, c is not a legal character | ||
2063 | * for a number. Stop accumulating digits. | ||
2064 | */ | ||
2065 | break; | ||
2066 | ok: | ||
2067 | /* | ||
2068 | * c is legal: store it and look at the next. | ||
2069 | */ | ||
2070 | *p++ = c; | ||
2071 | if (--inr > 0) | ||
2072 | inp++; | ||
2073 | else | ||
2074 | break; /* end of input */ | ||
2075 | } | ||
2076 | /* | ||
2077 | * If we had only a sign, it is no good; push | ||
2078 | * back the sign. If the number ends in `x', | ||
2079 | * it was [sign] '0' 'x', so push back the x | ||
2080 | * and treat it as [sign] '0'. | ||
2081 | */ | ||
2082 | if (flags & NDIGITS) { | ||
2083 | if (p > buf) { | ||
2084 | inp--; | ||
2085 | inr++; | ||
2086 | } | ||
2087 | goto match_failure; | ||
2088 | } | ||
2089 | c = ((u_char *)p)[-1]; | ||
2090 | if (c == 'x' || c == 'X') { | ||
2091 | --p; | ||
2092 | inp--; | ||
2093 | inr++; | ||
2094 | } | ||
2095 | if ((flags & SUPPRESS) == 0) { | ||
2096 | u_quad_t res; | ||
2097 | |||
2098 | *p = 0; | ||
2099 | if ((flags & UNSIGNED) == 0) | ||
2100 | res = strtoq(buf, (char **)NULL, base); | ||
2101 | else | ||
2102 | res = strtouq(buf, (char **)NULL, base); | ||
2103 | if (flags & POINTER) | ||
2104 | *va_arg(ap, void **) = | ||
2105 | (void *)(uintptr_t)res; | ||
2106 | else if (flags & SHORTSHORT) | ||
2107 | *va_arg(ap, char *) = res; | ||
2108 | else if (flags & SHORT) | ||
2109 | *va_arg(ap, short *) = res; | ||
2110 | else if (flags & LONG) | ||
2111 | *va_arg(ap, long *) = res; | ||
2112 | else if (flags & LONGLONG) | ||
2113 | *va_arg(ap, long long *) = res; | ||
2114 | else | ||
2115 | *va_arg(ap, int *) = res; | ||
2116 | nassigned++; | ||
2117 | } | ||
2118 | nread += p - buf; | ||
2119 | nconversions++; | ||
2120 | break; | ||
2121 | |||
2122 | } | ||
2123 | } | ||
2124 | input_failure: | ||
2125 | return (nconversions != 0 ? nassigned : -1); | ||
2126 | match_failure: | ||
2127 | return (nassigned); | ||
2128 | } | ||
2129 | |||
2130 | /* | ||
2131 | * Fill in the given table from the scanset at the given format | ||
2132 | * (just after `['). Return a pointer to the character past the | ||
2133 | * closing `]'. The table has a 1 wherever characters should be | ||
2134 | * considered part of the scanset. | ||
2135 | */ | ||
2136 | static const u_char * | ||
2137 | __sccl(char *tab, const u_char *fmt) | ||
2138 | { | ||
2139 | int c, n, v; | ||
2140 | |||
2141 | /* first `clear' the whole table */ | ||
2142 | c = *fmt++; /* first char hat => negated scanset */ | ||
2143 | if (c == '^') { | ||
2144 | v = 1; /* default => accept */ | ||
2145 | c = *fmt++; /* get new first char */ | ||
2146 | } else | ||
2147 | v = 0; /* default => reject */ | ||
2148 | |||
2149 | /* XXX: Will not work if sizeof(tab*) > sizeof(char) */ | ||
2150 | (void) memset(tab, v, 256); | ||
2151 | |||
2152 | if (c == 0) | ||
2153 | return (fmt - 1);/* format ended before closing ] */ | ||
2154 | |||
2155 | /* | ||
2156 | * Now set the entries corresponding to the actual scanset | ||
2157 | * to the opposite of the above. | ||
2158 | * | ||
2159 | * The first character may be ']' (or '-') without being special; | ||
2160 | * the last character may be '-'. | ||
2161 | */ | ||
2162 | v = 1 - v; | ||
2163 | for (;;) { | ||
2164 | tab[c] = v; /* take character c */ | ||
2165 | doswitch: | ||
2166 | n = *fmt++; /* and examine the next */ | ||
2167 | switch (n) { | ||
2168 | |||
2169 | case 0: /* format ended too soon */ | ||
2170 | return (fmt - 1); | ||
2171 | |||
2172 | case '-': | ||
2173 | /* | ||
2174 | * A scanset of the form | ||
2175 | * [01+-] | ||
2176 | * is defined as `the digit 0, the digit 1, | ||
2177 | * the character +, the character -', but | ||
2178 | * the effect of a scanset such as | ||
2179 | * [a-zA-Z0-9] | ||
2180 | * is implementation defined. The V7 Unix | ||
2181 | * scanf treats `a-z' as `the letters a through | ||
2182 | * z', but treats `a-a' as `the letter a, the | ||
2183 | * character -, and the letter a'. | ||
2184 | * | ||
2185 | * For compatibility, the `-' is not considerd | ||
2186 | * to define a range if the character following | ||
2187 | * it is either a close bracket (required by ANSI) | ||
2188 | * or is not numerically greater than the character | ||
2189 | * we just stored in the table (c). | ||
2190 | */ | ||
2191 | n = *fmt; | ||
2192 | if (n == ']' || n < c) { | ||
2193 | c = '-'; | ||
2194 | break; /* resume the for(;;) */ | ||
2195 | } | ||
2196 | fmt++; | ||
2197 | /* fill in the range */ | ||
2198 | do { | ||
2199 | tab[++c] = v; | ||
2200 | } while (c < n); | ||
2201 | c = n; | ||
2202 | /* | ||
2203 | * Alas, the V7 Unix scanf also treats formats | ||
2204 | * such as [a-c-e] as `the letters a through e'. | ||
2205 | * This too is permitted by the standard.... | ||
2206 | */ | ||
2207 | goto doswitch; | ||
2208 | break; | ||
2209 | |||
2210 | case ']': /* end of scanset */ | ||
2211 | return (fmt); | ||
2212 | |||
2213 | default: /* just another character */ | ||
2214 | c = n; | ||
2215 | break; | ||
2216 | } | ||
2217 | } | ||
2218 | /* NOTREACHED */ | ||
2219 | } | ||
2220 | |||
2221 | /* | ||
2222 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | ||
2223 | * | ||
2224 | * @APPLE_LICENSE_HEADER_START@ | ||
2225 | * | ||
2226 | * The contents of this file constitute Original Code as defined in and | ||
2227 | * are subject to the Apple Public Source License Version 1.1 (the | ||
2228 | * "License"). You may not use this file except in compliance with the | ||
2229 | * License. Please obtain a copy of the License at | ||
2230 | * http://www.apple.com/publicsource and read it before using this file. | ||
2231 | * | ||
2232 | * This Original Code and all software distributed under the License are | ||
2233 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | ||
2234 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | ||
2235 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | ||
2236 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | ||
2237 | * License for the specific language governing rights and limitations | ||
2238 | * under the License. | ||
2239 | * | ||
2240 | * @APPLE_LICENSE_HEADER_END@ | ||
2241 | */ | ||
2242 | /* | ||
2243 | * Copyright (c) 1990, 1993 | ||
2244 | * The Regents of the University of California. All rights reserved. | ||
2245 | * | ||
2246 | * This code is derived from software contributed to Berkeley by | ||
2247 | * Chris Torek. | ||
2248 | * | ||
2249 | * Redistribution and use in source and binary forms, with or without | ||
2250 | * modification, are permitted provided that the following conditions | ||
2251 | * are met: | ||
2252 | * 1. Redistributions of source code must retain the above copyright | ||
2253 | * notice, this list of conditions and the following disclaimer. | ||
2254 | * 2. Redistributions in binary form must reproduce the above copyright | ||
2255 | * notice, this list of conditions and the following disclaimer in the | ||
2256 | * documentation and/or other materials provided with the distribution. | ||
2257 | * 3. All advertising materials mentioning features or use of this software | ||
2258 | * must display the following acknowledgement: | ||
2259 | * This product includes software developed by the University of | ||
2260 | * California, Berkeley and its contributors. | ||
2261 | * 4. Neither the name of the University nor the names of its contributors | ||
2262 | * may be used to endorse or promote products derived from this software | ||
2263 | * without specific prior written permission. | ||
2264 | * | ||
2265 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
2266 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
2267 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
2268 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
2269 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
2270 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
2271 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
2272 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
2273 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
2274 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
2275 | * SUCH DAMAGE. | ||
2276 | */ | ||
2277 | |||
2278 | #include "plugin.h" | ||
2279 | |||
2280 | /* | ||
2281 | * Span the complement of string s2. | ||
2282 | */ | ||
2283 | size_t | ||
2284 | strcspn_wrapper(const char *s1, const char *s2) | ||
2285 | { | ||
2286 | register const char *p, *spanp; | ||
2287 | register char c, sc; | ||
2288 | |||
2289 | /* | ||
2290 | * Stop as soon as we find any character from s2. Note that there | ||
2291 | * must be a NUL in s2; it suffices to stop when we find that, too. | ||
2292 | */ | ||
2293 | for (p = s1;;) { | ||
2294 | c = *p++; | ||
2295 | spanp = s2; | ||
2296 | do { | ||
2297 | if ((sc = *spanp++) == c) | ||
2298 | return (p - 1 - s1); | ||
2299 | } while (sc != 0); | ||
2300 | } | ||
2301 | /* NOTREACHED */ | ||
2302 | } | ||
2303 | |||
2304 | /* | ||
2305 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | ||
2306 | * | ||
2307 | * @APPLE_LICENSE_HEADER_START@ | ||
2308 | * | ||
2309 | * The contents of this file constitute Original Code as defined in and | ||
2310 | * are subject to the Apple Public Source License Version 1.1 (the | ||
2311 | * "License"). You may not use this file except in compliance with the | ||
2312 | * License. Please obtain a copy of the License at | ||
2313 | * http://www.apple.com/publicsource and read it before using this file. | ||
2314 | * | ||
2315 | * This Original Code and all software distributed under the License are | ||
2316 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | ||
2317 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | ||
2318 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | ||
2319 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | ||
2320 | * License for the specific language governing rights and limitations | ||
2321 | * under the License. | ||
2322 | * | ||
2323 | * @APPLE_LICENSE_HEADER_END@ | ||
2324 | */ | ||
2325 | /* | ||
2326 | * Copyright (c) 1989, 1993 | ||
2327 | * The Regents of the University of California. All rights reserved. | ||
2328 | * | ||
2329 | * Redistribution and use in source and binary forms, with or without | ||
2330 | * modification, are permitted provided that the following conditions | ||
2331 | * are met: | ||
2332 | * 1. Redistributions of source code must retain the above copyright | ||
2333 | * notice, this list of conditions and the following disclaimer. | ||
2334 | * 2. Redistributions in binary form must reproduce the above copyright | ||
2335 | * notice, this list of conditions and the following disclaimer in the | ||
2336 | * documentation and/or other materials provided with the distribution. | ||
2337 | * 3. All advertising materials mentioning features or use of this software | ||
2338 | * must display the following acknowledgement: | ||
2339 | * This product includes software developed by the University of | ||
2340 | * California, Berkeley and its contributors. | ||
2341 | * 4. Neither the name of the University nor the names of its contributors | ||
2342 | * may be used to endorse or promote products derived from this software | ||
2343 | * without specific prior written permission. | ||
2344 | * | ||
2345 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
2346 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
2347 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
2348 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
2349 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
2350 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
2351 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
2352 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
2353 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
2354 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
2355 | * SUCH DAMAGE. | ||
2356 | */ | ||
2357 | |||
2358 | #include "rbcompat.h" | ||
2359 | |||
2360 | /* | ||
2361 | * Span the string s2 (skip characters that are in s2). | ||
2362 | */ | ||
2363 | size_t | ||
2364 | strspn_wrapper(const char *s1, const char *s2) | ||
2365 | { | ||
2366 | register const char *p = s1, *spanp; | ||
2367 | register char c, sc; | ||
2368 | |||
2369 | /* | ||
2370 | * Skip any characters in s2, excluding the terminating \0. | ||
2371 | */ | ||
2372 | cont: | ||
2373 | c = *p++; | ||
2374 | for (spanp = s2; (sc = *spanp++) != 0;) | ||
2375 | if (sc == c) | ||
2376 | goto cont; | ||
2377 | return (p - 1 - s1); | ||
2378 | } | ||