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