1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2015 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // Distributed under the Boost Software License, Version 1.0.
7 // http://www.boost.org/LICENSE_1_0.txt
8 
9 module ddmd.root.port;
10 
11 import core.stdc.ctype;
12 import core.stdc..string;
13 import core.math;
14 
15 version (Windows) __gshared extern (C) extern const(char)* __locale_decpoint;
16 
17 extern (C) float strtof(const(char)* p, char** endp);
18 extern (C) double strtod(const(char)* p, char** endp);
19 extern (C) real strtold(const(char)* p, char** endp);
20 
21 extern (C++) struct Port
22 {
23     enum nan = double.nan;
24     enum infinity = double.infinity;
25     enum ldbl_max = real.max;
26     enum ldbl_nan = real.nan;
27     enum ldbl_infinity = real.infinity;
28     static __gshared bool yl2x_supported = true;
29     static __gshared bool yl2xp1_supported = true;
30     static __gshared real snan;
31     static this()
32     {
33         /*
34          * Use a payload which is different from the machine NaN,
35          * so that uninitialised variables can be
36          * detected even if exceptions are disabled.
37          */
38         ushort* us = cast(ushort*)&snan;
39         us[0] = 0;
40         us[1] = 0;
41         us[2] = 0;
42         us[3] = 0xA000;
43         us[4] = 0x7FFF;
44     }
45 
46     static bool isNan(double r)
47     {
48         return !(r == r);
49     }
50 
51     static real sqrt(real x)
52     {
53         return .sqrt(x);
54     }
55 
56     static real fmodl(real a, real b)
57     {
58         return a % b;
59     }
60 
61     static real fequal(real a, real b)
62     {
63         return memcmp(&a, &b, 10) == 0;
64     }
65 
66     static int memicmp(const char* s1, const char* s2, size_t n)
67     {
68         int result = 0;
69 
70         for (int i = 0; i < n; i++)
71         {
72             char c1 = s1[i];
73             char c2 = s2[i];
74 
75             result = c1 - c2;
76             if (result)
77             {
78                 result = toupper(c1) - toupper(c2);
79                 if (result)
80                     break;
81             }
82         }
83         return result;
84     }
85 
86     static char* strupr(char* s)
87     {
88         char* t = s;
89 
90         while (*s)
91         {
92             *s = cast(char)toupper(*s);
93             s++;
94         }
95 
96         return t;
97     }
98 
99     static int isSignallingNan(double r)
100     {
101         return isNan(r) && !(((cast(ubyte*)&r)[6]) & 8);
102     }
103 
104     static int isSignallingNan(real r)
105     {
106         return isNan(r) && !(((cast(ubyte*)&r)[7]) & 0x40);
107     }
108 
109     static int isInfinity(double r)
110     {
111         return r is double.infinity || r is -double.infinity;
112     }
113 
114     static float strtof(const(char)* p, char** endp)
115     {
116         version (Windows)
117         {
118             auto save = __locale_decpoint;
119             __locale_decpoint = ".";
120         }
121         auto r = .strtof(p, endp);
122         version (Windows) __locale_decpoint = save;
123         return r;
124     }
125 
126     static double strtod(const(char)* p, char** endp)
127     {
128         version (Windows)
129         {
130             auto save = __locale_decpoint;
131             __locale_decpoint = ".";
132         }
133         auto r = .strtod(p, endp);
134         version (Windows) __locale_decpoint = save;
135         return r;
136     }
137 
138     static real strtold(const(char)* p, char** endp)
139     {
140         version (Windows)
141         {
142             auto save = __locale_decpoint;
143             __locale_decpoint = ".";
144         }
145         auto r = .strtold(p, endp);
146         version (Windows) __locale_decpoint = save;
147         return r;
148     }
149 
150     static void yl2x_impl(real* x, real* y, real* res)
151     {
152         *res = yl2x(*x, *y);
153     }
154 
155     static void yl2xp1_impl(real* x, real* y, real* res)
156     {
157         *res = yl2xp1(*x, *y);
158     }
159 
160     // Little endian
161     static void writelongLE(uint value, void* buffer)
162     {
163         auto p = cast(ubyte*)buffer;
164         p[3] = cast(ubyte)(value >> 24);
165         p[2] = cast(ubyte)(value >> 16);
166         p[1] = cast(ubyte)(value >> 8);
167         p[0] = cast(ubyte)(value);
168     }
169 
170     // Little endian
171     static uint readlongLE(void* buffer)
172     {
173         auto p = cast(ubyte*)buffer;
174         return (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
175     }
176 
177     // Big endian
178     static void writelongBE(uint value, void* buffer)
179     {
180         auto p = cast(ubyte*)buffer;
181         p[0] = cast(ubyte)(value >> 24);
182         p[1] = cast(ubyte)(value >> 16);
183         p[2] = cast(ubyte)(value >> 8);
184         p[3] = cast(ubyte)(value);
185     }
186 
187     // Big endian
188     static uint readlongBE(void* buffer)
189     {
190         auto p = cast(ubyte*)buffer;
191         return (((((p[0] << 8) | p[1]) << 8) | p[2]) << 8) | p[3];
192     }
193 
194     // Little endian
195     static uint readwordLE(void* buffer)
196     {
197         auto p = cast(ubyte*)buffer;
198         return (p[1] << 8) | p[0];
199     }
200 
201     // Big endian
202     static uint readwordBE(void* buffer)
203     {
204         auto p = cast(ubyte*)buffer;
205         return (p[0] << 8) | p[1];
206     }
207 }