comparison dmd/root/port.c @ 1195:e961851fb8be

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