Mercurial > projects > ldc
comparison dmd2/root/port.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | |
2 // Copyright (c) 1999-2009 by Digital Mars | |
3 // All Rights Reserved | |
4 // written by Walter Bright | |
5 // http://www.digitalmars.com | |
6 | |
7 #include "port.h" | |
8 #if __DMC__ | |
9 #include <math.h> | |
10 #include <float.h> | |
11 #include <fp.h> | |
12 #include <time.h> | |
13 #include <stdlib.h> | |
14 #include <string.h> | |
15 | |
16 double Port::nan = NAN; | |
17 double Port::infinity = INFINITY; | |
18 double Port::dbl_max = DBL_MAX; | |
19 double Port::dbl_min = DBL_MIN; | |
20 long double Port::ldbl_max = LDBL_MAX; | |
21 | |
22 int Port::isNan(double r) | |
23 { | |
24 return ::isnan(r); | |
25 } | |
26 | |
27 int Port::isNan(long double r) | |
28 { | |
29 return ::isnan(r); | |
30 } | |
31 | |
32 int Port::isSignallingNan(double r) | |
33 { | |
34 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
35 * its significand, which is bit 51 of 0..63 for 64 bit doubles. | |
36 */ | |
37 return isNan(r) && !((((unsigned char*)&r)[6]) & 8); | |
38 } | |
39 | |
40 int Port::isSignallingNan(long double r) | |
41 { | |
42 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
43 * its significand, which is bit 62 of 0..79 for 80 bit reals. | |
44 */ | |
45 return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); | |
46 } | |
47 | |
48 int Port::isFinite(double r) | |
49 { | |
50 return ::isfinite(r); | |
51 } | |
52 | |
53 int Port::isInfinity(double r) | |
54 { | |
55 return (::fpclassify(r) == FP_INFINITE); | |
56 } | |
57 | |
58 int Port::Signbit(double r) | |
59 { | |
60 return ::signbit(r); | |
61 } | |
62 | |
63 double Port::floor(double d) | |
64 { | |
65 return ::floor(d); | |
66 } | |
67 | |
68 double Port::pow(double x, double y) | |
69 { | |
70 return ::pow(x, y); | |
71 } | |
72 | |
73 unsigned long long Port::strtoull(const char *p, char **pend, int base) | |
74 { | |
75 return ::strtoull(p, pend, base); | |
76 } | |
77 | |
78 char *Port::ull_to_string(char *buffer, ulonglong ull) | |
79 { | |
80 sprintf(buffer, "%llu", ull); | |
81 return buffer; | |
82 } | |
83 | |
84 wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) | |
85 { | |
86 swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); | |
87 return buffer; | |
88 } | |
89 | |
90 double Port::ull_to_double(ulonglong ull) | |
91 { | |
92 return (double) ull; | |
93 } | |
94 | |
95 const char *Port::list_separator() | |
96 { | |
97 // LOCALE_SLIST for Windows | |
98 return ","; | |
99 } | |
100 | |
101 const wchar_t *Port::wlist_separator() | |
102 { | |
103 // LOCALE_SLIST for Windows | |
104 return L","; | |
105 } | |
106 | |
107 char *Port::strupr(char *s) | |
108 { | |
109 return ::strupr(s); | |
110 } | |
111 | |
112 #endif | |
113 | |
114 #if _MSC_VER | |
115 | |
116 // Disable useless warnings about unreferenced functions | |
117 #pragma warning (disable : 4514) | |
118 | |
119 #include <math.h> | |
120 #include <float.h> | |
121 #include <time.h> | |
122 #include <errno.h> | |
123 #include <string.h> | |
124 #include <ctype.h> | |
125 #include <stdlib.h> | |
126 #include <limits> // for std::numeric_limits | |
127 | |
128 static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF }; | |
129 //static unsigned long nanarray[2] = {0,0x7FF80000 }; | |
130 double Port::nan = (*(double *)nanarray); | |
131 | |
132 //static unsigned long infinityarray[2] = {0,0x7FF00000 }; | |
133 static double zero = 0; | |
134 double Port::infinity = 1 / zero; | |
135 | |
136 double Port::dbl_max = DBL_MAX; | |
137 double Port::dbl_min = DBL_MIN; | |
138 long double Port::ldbl_max = LDBL_MAX; | |
139 | |
140 struct PortInitializer | |
141 { | |
142 PortInitializer(); | |
143 }; | |
144 | |
145 static PortInitializer portinitializer; | |
146 | |
147 PortInitializer::PortInitializer() | |
148 { | |
149 Port::infinity = std::numeric_limits<long double>::infinity(); | |
150 } | |
151 | |
152 int Port::isNan(double r) | |
153 { | |
154 return ::_isnan(r); | |
155 } | |
156 | |
157 int Port::isNan(long double r) | |
158 { | |
159 return ::_isnan(r); | |
160 } | |
161 | |
162 int Port::isSignallingNan(double r) | |
163 { | |
164 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
165 * its significand, which is bit 51 of 0..63 for 64 bit doubles. | |
166 */ | |
167 return isNan(r) && !((((unsigned char*)&r)[6]) & 8); | |
168 } | |
169 | |
170 int Port::isSignallingNan(long double r) | |
171 { | |
172 /* MSVC doesn't have 80 bit long doubles | |
173 */ | |
174 return isSignallingNan((double) r); | |
175 } | |
176 | |
177 int Port::isFinite(double r) | |
178 { | |
179 return ::_finite(r); | |
180 } | |
181 | |
182 int Port::isInfinity(double r) | |
183 { | |
184 return (::_fpclass(r) & (_FPCLASS_NINF | _FPCLASS_PINF)); | |
185 } | |
186 | |
187 int Port::Signbit(double r) | |
188 { | |
189 return (long)(((long *)&(r))[1] & 0x80000000); | |
190 } | |
191 | |
192 double Port::floor(double d) | |
193 { | |
194 return ::floor(d); | |
195 } | |
196 | |
197 double Port::pow(double x, double y) | |
198 { | |
199 if (y == 0) | |
200 return 1; // even if x is NAN | |
201 return ::pow(x, y); | |
202 } | |
203 | |
204 unsigned _int64 Port::strtoull(const char *p, char **pend, int base) | |
205 { | |
206 unsigned _int64 number = 0; | |
207 int c; | |
208 int error; | |
209 #define ULLONG_MAX ((unsigned _int64)~0I64) | |
210 | |
211 while (isspace(*p)) /* skip leading white space */ | |
212 p++; | |
213 if (*p == '+') | |
214 p++; | |
215 switch (base) | |
216 { case 0: | |
217 base = 10; /* assume decimal base */ | |
218 if (*p == '0') | |
219 { base = 8; /* could be octal */ | |
220 p++; | |
221 switch (*p) | |
222 { case 'x': | |
223 case 'X': | |
224 base = 16; /* hex */ | |
225 p++; | |
226 break; | |
227 #if BINARY | |
228 case 'b': | |
229 case 'B': | |
230 base = 2; /* binary */ | |
231 p++; | |
232 break; | |
233 #endif | |
234 } | |
235 } | |
236 break; | |
237 case 16: /* skip over '0x' and '0X' */ | |
238 if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) | |
239 p += 2; | |
240 break; | |
241 #if BINARY | |
242 case 2: /* skip over '0b' and '0B' */ | |
243 if (*p == '0' && (p[1] == 'b' || p[1] == 'B')) | |
244 p += 2; | |
245 break; | |
246 #endif | |
247 } | |
248 error = 0; | |
249 for (;;) | |
250 { c = *p; | |
251 if (isdigit(c)) | |
252 c -= '0'; | |
253 else if (isalpha(c)) | |
254 c = (c & ~0x20) - ('A' - 10); | |
255 else /* unrecognized character */ | |
256 break; | |
257 if (c >= base) /* not in number base */ | |
258 break; | |
259 if ((ULLONG_MAX - c) / base < number) | |
260 error = 1; | |
261 number = number * base + c; | |
262 p++; | |
263 } | |
264 if (pend) | |
265 *pend = (char *)p; | |
266 if (error) | |
267 { number = ULLONG_MAX; | |
268 errno = ERANGE; | |
269 } | |
270 return number; | |
271 } | |
272 | |
273 char *Port::ull_to_string(char *buffer, ulonglong ull) | |
274 { | |
275 _ui64toa(ull, buffer, 10); | |
276 return buffer; | |
277 } | |
278 | |
279 wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) | |
280 { | |
281 _ui64tow(ull, buffer, 10); | |
282 return buffer; | |
283 } | |
284 | |
285 double Port::ull_to_double(ulonglong ull) | |
286 { double d; | |
287 | |
288 if ((__int64) ull < 0) | |
289 { | |
290 // MSVC doesn't implement the conversion | |
291 d = (double) (__int64)(ull - 0x8000000000000000i64); | |
292 d += (double)(signed __int64)(0x7FFFFFFFFFFFFFFFi64) + 1.0; | |
293 } | |
294 else | |
295 d = (double)(__int64)ull; | |
296 return d; | |
297 } | |
298 | |
299 const char *Port::list_separator() | |
300 { | |
301 // LOCALE_SLIST for Windows | |
302 return ","; | |
303 } | |
304 | |
305 const wchar_t *Port::wlist_separator() | |
306 { | |
307 // LOCALE_SLIST for Windows | |
308 return L","; | |
309 } | |
310 | |
311 char *Port::strupr(char *s) | |
312 { | |
313 return ::strupr(s); | |
314 } | |
315 | |
316 #endif | |
317 | |
318 #if linux || __APPLE__ || __FreeBSD__ | |
319 | |
320 #include <math.h> | |
321 #if linux | |
322 #include <bits/nan.h> | |
323 #include <bits/mathdef.h> | |
324 #endif | |
325 #include <time.h> | |
326 #include <sys/time.h> | |
327 #include <unistd.h> | |
328 #include <stdio.h> | |
329 #include <stdlib.h> | |
330 #include <ctype.h> | |
331 #include <float.h> | |
332 | |
333 static double zero = 0; | |
334 double Port::nan = NAN; | |
335 double Port::infinity = 1 / zero; | |
336 double Port::dbl_max = 1.7976931348623157e308; | |
337 double Port::dbl_min = 5e-324; | |
338 long double Port::ldbl_max = LDBL_MAX; | |
339 | |
340 struct PortInitializer | |
341 { | |
342 PortInitializer(); | |
343 }; | |
344 | |
345 static PortInitializer portinitializer; | |
346 | |
347 PortInitializer::PortInitializer() | |
348 { | |
349 // gcc nan's have the sign bit set by default, so turn it off | |
350 // Need the volatile to prevent gcc from doing incorrect | |
351 // constant folding. | |
352 volatile long double foo; | |
353 foo = NAN; | |
354 if (signbit(foo)) // signbit sometimes, not always, set | |
355 foo = -foo; // turn off sign bit | |
356 Port::nan = foo; | |
357 | |
358 #if __FreeBSD__ | |
359 // LDBL_MAX comes out as infinity. Fix. | |
360 static unsigned char x[sizeof(long double)] = | |
361 { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F }; | |
362 Port::ldbl_max = *(long double *)&x[0]; | |
363 #endif | |
364 } | |
365 | |
366 #undef isnan | |
367 int Port::isNan(double r) | |
368 { | |
369 #if __APPLE__ | |
370 return __inline_isnan(r); | |
371 #else | |
372 return ::isnan(r); | |
373 #endif | |
374 } | |
375 | |
376 int Port::isNan(long double r) | |
377 { | |
378 #if __APPLE__ | |
379 return __inline_isnan(r); | |
380 #else | |
381 return ::isnan(r); | |
382 #endif | |
383 } | |
384 | |
385 int Port::isSignallingNan(double r) | |
386 { | |
387 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
388 * its significand, which is bit 51 of 0..63 for 64 bit doubles. | |
389 */ | |
390 return isNan(r) && !((((unsigned char*)&r)[6]) & 8); | |
391 } | |
392 | |
393 int Port::isSignallingNan(long double r) | |
394 { | |
395 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
396 * its significand, which is bit 62 of 0..79 for 80 bit reals. | |
397 */ | |
398 return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); | |
399 } | |
400 | |
401 #undef isfinite | |
402 int Port::isFinite(double r) | |
403 { | |
404 return ::finite(r); | |
405 } | |
406 | |
407 #undef isinf | |
408 int Port::isInfinity(double r) | |
409 { | |
410 #if __APPLE__ | |
411 return fpclassify(r) == FP_INFINITE; | |
412 #else | |
413 return ::isinf(r); | |
414 #endif | |
415 } | |
416 | |
417 #undef signbit | |
418 int Port::Signbit(double r) | |
419 { | |
420 return (long)(((long *)&r)[1] & 0x80000000); | |
421 } | |
422 | |
423 double Port::floor(double d) | |
424 { | |
425 return ::floor(d); | |
426 } | |
427 | |
428 double Port::pow(double x, double y) | |
429 { | |
430 return ::pow(x, y); | |
431 } | |
432 | |
433 unsigned long long Port::strtoull(const char *p, char **pend, int base) | |
434 { | |
435 return ::strtoull(p, pend, base); | |
436 } | |
437 | |
438 char *Port::ull_to_string(char *buffer, ulonglong ull) | |
439 { | |
440 sprintf(buffer, "%llu", ull); | |
441 return buffer; | |
442 } | |
443 | |
444 wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) | |
445 { | |
446 swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); | |
447 return buffer; | |
448 } | |
449 | |
450 double Port::ull_to_double(ulonglong ull) | |
451 { | |
452 return (double) ull; | |
453 } | |
454 | |
455 const char *Port::list_separator() | |
456 { | |
457 return ","; | |
458 } | |
459 | |
460 const wchar_t *Port::wlist_separator() | |
461 { | |
462 return L","; | |
463 } | |
464 | |
465 char *Port::strupr(char *s) | |
466 { | |
467 char *t = s; | |
468 | |
469 while (*s) | |
470 { | |
471 *s = toupper(*s); | |
472 s++; | |
473 } | |
474 | |
475 return t; | |
476 } | |
477 | |
478 #endif | |
479 | |
480 #if __sun&&__SVR4 | |
481 | |
482 #define __C99FEATURES__ 1 // Needed on Solaris for NaN and more | |
483 #include <math.h> | |
484 #include <time.h> | |
485 #include <sys/time.h> | |
486 #include <unistd.h> | |
487 #include <stdio.h> | |
488 #include <stdlib.h> | |
489 #include <ctype.h> | |
490 #include <float.h> | |
491 #include <ieeefp.h> | |
492 | |
493 static double zero = 0; | |
494 double Port::nan = NAN; | |
495 double Port::infinity = 1 / zero; | |
496 double Port::dbl_max = 1.7976931348623157e308; | |
497 double Port::dbl_min = 5e-324; | |
498 long double Port::ldbl_max = LDBL_MAX; | |
499 | |
500 struct PortInitializer | |
501 { | |
502 PortInitializer(); | |
503 }; | |
504 | |
505 static PortInitializer portinitializer; | |
506 | |
507 PortInitializer::PortInitializer() | |
508 { | |
509 // gcc nan's have the sign bit set by default, so turn it off | |
510 // Need the volatile to prevent gcc from doing incorrect | |
511 // constant folding. | |
512 volatile long double foo; | |
513 foo = NAN; | |
514 if (signbit(foo)) // signbit sometimes, not always, set | |
515 foo = -foo; // turn off sign bit | |
516 Port::nan = foo; | |
517 } | |
518 | |
519 int Port::isNan(double r) | |
520 { | |
521 return isnan(r); | |
522 } | |
523 | |
524 int Port::isNan(long double r) | |
525 { | |
526 return isnan(r); | |
527 } | |
528 | |
529 int Port::isSignallingNan(double r) | |
530 { | |
531 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
532 * its significand, which is bit 51 of 0..63 for 64 bit doubles. | |
533 */ | |
534 return isNan(r) && !((((unsigned char*)&r)[6]) & 8); | |
535 } | |
536 | |
537 int Port::isSignallingNan(long double r) | |
538 { | |
539 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
540 * its significand, which is bit 62 of 0..79 for 80 bit reals. | |
541 */ | |
542 return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); | |
543 } | |
544 | |
545 #undef isfinite | |
546 int Port::isFinite(double r) | |
547 { | |
548 return finite(r); | |
549 } | |
550 | |
551 int Port::isInfinity(double r) | |
552 { | |
553 return isinf(r); | |
554 } | |
555 | |
556 #undef signbit | |
557 int Port::Signbit(double r) | |
558 { | |
559 return (long)(((long *)&r)[1] & 0x80000000); | |
560 } | |
561 | |
562 double Port::floor(double d) | |
563 { | |
564 return ::floor(d); | |
565 } | |
566 | |
567 double Port::pow(double x, double y) | |
568 { | |
569 return ::pow(x, y); | |
570 } | |
571 | |
572 unsigned long long Port::strtoull(const char *p, char **pend, int base) | |
573 { | |
574 return ::strtoull(p, pend, base); | |
575 } | |
576 | |
577 char *Port::ull_to_string(char *buffer, ulonglong ull) | |
578 { | |
579 sprintf(buffer, "%llu", ull); | |
580 return buffer; | |
581 } | |
582 | |
583 wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) | |
584 { | |
585 swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull); | |
586 return buffer; | |
587 } | |
588 | |
589 double Port::ull_to_double(ulonglong ull) | |
590 { | |
591 return (double) ull; | |
592 } | |
593 | |
594 const char *Port::list_separator() | |
595 { | |
596 return ","; | |
597 } | |
598 | |
599 const wchar_t *Port::wlist_separator() | |
600 { | |
601 return L","; | |
602 } | |
603 | |
604 char *Port::strupr(char *s) | |
605 { | |
606 char *t = s; | |
607 | |
608 while (*s) | |
609 { | |
610 *s = toupper(*s); | |
611 s++; | |
612 } | |
613 | |
614 return t; | |
615 } | |
616 | |
617 #endif | |
618 | |
619 #if IN_GCC | |
620 | |
621 #include <math.h> | |
622 #include <bits/nan.h> | |
623 #include <bits/mathdef.h> | |
624 #include <time.h> | |
625 #include <sys/time.h> | |
626 #include <unistd.h> | |
627 #include <stdio.h> | |
628 #include <stdlib.h> | |
629 #include <ctype.h> | |
630 | |
631 static double zero = 0; | |
632 double Port::nan = NAN; | |
633 double Port::infinity = 1 / zero; | |
634 double Port::dbl_max = 1.7976931348623157e308; | |
635 double Port::dbl_min = 5e-324; | |
636 long double Port::ldbl_max = LDBL_MAX; | |
637 | |
638 #include "d-gcc-real.h" | |
639 extern "C" bool real_isnan (const real_t *); | |
640 | |
641 struct PortInitializer | |
642 { | |
643 PortInitializer(); | |
644 }; | |
645 | |
646 static PortInitializer portinitializer; | |
647 | |
648 PortInitializer::PortInitializer() | |
649 { | |
650 Port::infinity = real_t::getinfinity(); | |
651 Port::nan = real_t::getnan(real_t::LongDouble); | |
652 } | |
653 | |
654 #undef isnan | |
655 int Port::isNan(double r) | |
656 { | |
657 #if __APPLE__ | |
658 return __inline_isnan(r); | |
659 #else | |
660 return ::isnan(r); | |
661 #endif | |
662 } | |
663 | |
664 int Port::isNan(long double r) | |
665 { | |
666 return real_isnan(&r); | |
667 } | |
668 | |
669 int Port::isSignallingNan(double r) | |
670 { | |
671 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
672 * its significand, which is bit 51 of 0..63 for 64 bit doubles. | |
673 */ | |
674 return isNan(r) && !((((unsigned char*)&r)[6]) & 8); | |
675 } | |
676 | |
677 int Port::isSignallingNan(long double r) | |
678 { | |
679 /* A signalling NaN is a NaN with 0 as the most significant bit of | |
680 * its significand, which is bit 62 of 0..79 for 80 bit reals. | |
681 */ | |
682 return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40); | |
683 } | |
684 | |
685 #undef isfinite | |
686 int Port::isFinite(double r) | |
687 { | |
688 return ::finite(r); | |
689 } | |
690 | |
691 #undef isinf | |
692 int Port::isInfinity(double r) | |
693 { | |
694 return ::isinf(r); | |
695 } | |
696 | |
697 #undef signbit | |
698 int Port::Signbit(double r) | |
699 { | |
700 return (long)(((long *)&r)[1] & 0x80000000); | |
701 } | |
702 | |
703 double Port::floor(double d) | |
704 { | |
705 return ::floor(d); | |
706 } | |
707 | |
708 double Port::pow(double x, double y) | |
709 { | |
710 return ::pow(x, y); | |
711 } | |
712 | |
713 unsigned long long Port::strtoull(const char *p, char **pend, int base) | |
714 { | |
715 return ::strtoull(p, pend, base); | |
716 } | |
717 | |
718 char *Port::ull_to_string(char *buffer, ulonglong ull) | |
719 { | |
720 sprintf(buffer, "%llu", ull); | |
721 return buffer; | |
722 } | |
723 | |
724 wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull) | |
725 { | |
726 swprintf(buffer, L"%llu", ull); | |
727 return buffer; | |
728 } | |
729 | |
730 double Port::ull_to_double(ulonglong ull) | |
731 { | |
732 return (double) ull; | |
733 } | |
734 | |
735 const char *Port::list_separator() | |
736 { | |
737 return ","; | |
738 } | |
739 | |
740 const wchar_t *Port::wlist_separator() | |
741 { | |
742 return L","; | |
743 } | |
744 | |
745 char *Port::strupr(char *s) | |
746 { | |
747 char *t = s; | |
748 | |
749 while (*s) | |
750 { | |
751 *s = toupper(*s); | |
752 s++; | |
753 } | |
754 | |
755 return t; | |
756 } | |
757 | |
758 #endif | |
759 |