1 /**
2  * Compiler implementation of the D programming language
3  * http://dlang.org
4  *
5  * Copyright: Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved
6  * Authors:   Walter Bright, http://www.digitalmars.com
7  * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source:    $(DMDSRC root/_port.d)
9  */
10 
11 module ddmd.root.port;
12 
13 import core.stdc.ctype;
14 import core.stdc.errno;
15 import core.stdc..string;
16 import core.stdc.stdio;
17 import core.stdc.stdlib;
18 
19 private extern (C)
20 {
21     version(CRuntime_DigitalMars) __gshared extern const(char)* __locale_decpoint;
22 
23     version(CRuntime_Microsoft)
24     {
25         enum _OVERFLOW  = 3;   /* overflow range error */
26         enum _UNDERFLOW = 4;   /* underflow range error */
27 
28         int _atoflt(float*  value, const(char)* str);
29         int _atodbl(double* value, const(char)* str);
30     }
31 }
32 
33 extern (C++) struct Port
34 {
35     static int memicmp(const char* s1, const char* s2, size_t n)
36     {
37         int result = 0;
38 
39         for (int i = 0; i < n; i++)
40         {
41             char c1 = s1[i];
42             char c2 = s2[i];
43 
44             result = c1 - c2;
45             if (result)
46             {
47                 result = toupper(c1) - toupper(c2);
48                 if (result)
49                     break;
50             }
51         }
52         return result;
53     }
54 
55     static char* strupr(char* s)
56     {
57         char* t = s;
58 
59         while (*s)
60         {
61             *s = cast(char)toupper(*s);
62             s++;
63         }
64 
65         return t;
66     }
67 
68     static bool isFloat32LiteralOutOfRange(const(char)* s)
69     {
70         errno = 0;
71         version (CRuntime_DigitalMars)
72         {
73             auto save = __locale_decpoint;
74             __locale_decpoint = ".";
75         }
76         version (CRuntime_Microsoft)
77         {
78             float r;
79             int res = _atoflt(&r, s);
80             if (res == _UNDERFLOW || res == _OVERFLOW)
81                 errno = ERANGE;
82         }
83         else
84         {
85             strtof(s, null);
86         }
87         version (CRuntime_DigitalMars) __locale_decpoint = save;
88         return errno == ERANGE;
89     }
90 
91     static bool isFloat64LiteralOutOfRange(const(char)* s)
92     {
93         errno = 0;
94         version (CRuntime_DigitalMars)
95         {
96             auto save = __locale_decpoint;
97             __locale_decpoint = ".";
98         }
99         version (CRuntime_Microsoft)
100         {
101             double r;
102             int res = _atodbl(&r, s);
103             if (res == _UNDERFLOW || res == _OVERFLOW)
104                 errno = ERANGE;
105         }
106         else
107         {
108             strtod(s, null);
109         }
110         version (CRuntime_DigitalMars) __locale_decpoint = save;
111         return errno == ERANGE;
112     }
113 
114     // Little endian
115     static void writelongLE(uint value, void* buffer)
116     {
117         auto p = cast(ubyte*)buffer;
118         p[3] = cast(ubyte)(value >> 24);
119         p[2] = cast(ubyte)(value >> 16);
120         p[1] = cast(ubyte)(value >> 8);
121         p[0] = cast(ubyte)(value);
122     }
123 
124     // Little endian
125     static uint readlongLE(void* buffer)
126     {
127         auto p = cast(ubyte*)buffer;
128         return (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
129     }
130 
131     // Big endian
132     static void writelongBE(uint value, void* buffer)
133     {
134         auto p = cast(ubyte*)buffer;
135         p[0] = cast(ubyte)(value >> 24);
136         p[1] = cast(ubyte)(value >> 16);
137         p[2] = cast(ubyte)(value >> 8);
138         p[3] = cast(ubyte)(value);
139     }
140 
141     // Big endian
142     static uint readlongBE(void* buffer)
143     {
144         auto p = cast(ubyte*)buffer;
145         return (((((p[0] << 8) | p[1]) << 8) | p[2]) << 8) | p[3];
146     }
147 
148     // Little endian
149     static uint readwordLE(void* buffer)
150     {
151         auto p = cast(ubyte*)buffer;
152         return (p[1] << 8) | p[0];
153     }
154 
155     // Big endian
156     static uint readwordBE(void* buffer)
157     {
158         auto p = cast(ubyte*)buffer;
159         return (p[0] << 8) | p[1];
160     }
161 
162     static void valcpy(void *dst, ulong val, size_t size)
163     {
164         switch (size)
165         {
166             case 1: *cast(ubyte *)dst = cast(ubyte)val; break;
167             case 2: *cast(ushort *)dst = cast(ushort)val; break;
168             case 4: *cast(uint *)dst = cast(uint)val; break;
169             case 8: *cast(ulong *)dst = cast(ulong)val; break;
170             default: assert(0);
171         }
172     }
173 }