summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/rbwrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/puzzles/rbwrappers.c')
-rw-r--r--apps/plugins/puzzles/rbwrappers.c2378
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
4int 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
13char *getenv_wrapper(const char *c)
14{
15 return NULL;
16}
17
18int puts_wrapper(const char *s)
19{
20 LOGF("%s", s);
21 return 0;
22}
23
24/* fixed-point wrappers */
25double sin_wrapper(double rads)
26{
27 int degs = rads * 180/PI;
28 long fixed = fp14_sin(degs);
29 return fixed / (16384.0);
30}
31
32double cos_wrapper(double rads)
33{
34 int degs = rads * 180/PI;
35 long fixed = fp14_cos(degs);
36 return fixed / (16384.0);
37}
38
39int 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 */
46float fabs_wrapper(float x)
47{
48 return (x < 0.0f) ? -x : x;
49}
50
51float 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 */
61static const float
62ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
63ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
64two25 = 3.355443200e+07, /* 0x4c000000 */
65Lg1 = 6.6666668653e-01, /* 3F2AAAAB */
66Lg2 = 4.0000000596e-01, /* 3ECCCCCD */
67Lg3 = 2.8571429849e-01, /* 3E924925 */
68Lg4 = 2.2222198546e-01, /* 3E638E29 */
69Lg5 = 1.8183572590e-01, /* 3E3A3325 */
70Lg6 = 1.5313838422e-01, /* 3E1CD04F */
71Lg7 = 1.4798198640e-01; /* 3E178897 */
72
73static const float zero = 0.0;
74
75/* A union which permits us to convert between a float and a 32 bit
76 int. */
77
78typedef 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) \
87do { \
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) \
96do { \
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
114static 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
179union 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
222static const volatile float TWOM100 = 7.88860905e-31;
223static 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)
235const 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
283const 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. */
642enum
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
657int
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
676int
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
714float 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
797static 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
804static 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
811static 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
825static const float
826huge = 1.0e+30,
827tiny = 1.0e-30,
828one = 1.0f;
829
830float 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
877static const float
878pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */
879pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */
880pi = 3.1415927410e+00, /* 0x40490fdb */
881pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
882
883float 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. */
951float 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__
1053static const double
1054#else
1055static double
1056#endif
1057pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
1058pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
1059pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
1060pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
1061pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
1062pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
1063pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
1064pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
1065qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
1066qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
1067qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
1068qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
1069
1070double 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
1190long 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
1285int64_t strtoq_wrapper(CONST char *nptr, char **endptr, int base)
1286{
1287 return strtol(nptr, endptr, base);
1288}
1289
1290uint64_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 */
1296float 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
1359double 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__
1385static const double
1386#else
1387static double
1388#endif
1389two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
1390 twom54 = 5.55111512312578270212e-17; /* 0x3C900000, 0x00000000 */
1391
1392double 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 */
1420float 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/). */
1427static int rb_errno = 0;
1428
1429static 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
1556double 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
1662typedef unsigned char u_char;
1663typedef uint64_t u_quad_t;
1664
1665static const u_char *__sccl(char *, const u_char *);
1666
1667void bcopy(const void *src, void *dst, size_t n)
1668{
1669 memmove(dst, src, n);
1670}
1671
1672int
1673sscanf_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
1684int
1685vsscanf(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 */
1729again: c = *fmt++;
1730 switch (c) {
1731 case '%':
1732literal:
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 }
2124input_failure:
2125 return (nconversions != 0 ? nassigned : -1);
2126match_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 */
2136static 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 */
2165doswitch:
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 */
2283size_t
2284strcspn_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 */
2363size_t
2364strspn_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 */
2372cont:
2373 c = *p++;
2374 for (spanp = s2; (sc = *spanp++) != 0;)
2375 if (sc == c)
2376 goto cont;
2377 return (p - 1 - s1);
2378}