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 }