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 }