1 /******************************************************************************* 2 3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: November 2005 8 9 author: Kris 10 11 *******************************************************************************/ 12 13 module tango.sys.Common; 14 15 version (Win32) 16 { 17 public import tango.sys.win32.UserGdi; 18 } 19 20 version (linux) 21 { 22 public import tango.sys.linux.linux; 23 alias tango.sys.linux.linux posix; 24 } 25 26 version (darwin) 27 { 28 public import tango.sys.darwin.darwin; 29 alias tango.sys.darwin.darwin posix; 30 } 31 version (FreeBSD) 32 { 33 public import tango.sys.freebsd.freebsd; 34 alias tango.sys.freebsd.freebsd posix; 35 } 36 version (solaris) 37 { 38 public import tango.sys.solaris.solaris; 39 alias tango.sys.solaris.solaris posix; 40 } 41 42 /******************************************************************************* 43 44 Stuff for sysErrorMsg(), kindly provided by Regan Heath. 45 46 *******************************************************************************/ 47 48 version (Win32) 49 { 50 private enum FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; 51 private enum FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; 52 private enum FORMAT_MESSAGE_FROM_STRING = 0x00000400; 53 private enum FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; 54 private enum FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; 55 private enum FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; 56 private enum FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF; 57 58 private DWORD MAKELANGID(WORD p, WORD s) { return (((cast(WORD)s) << 10) | cast(WORD)p); } 59 60 private alias HGLOBAL HLOCAL; 61 62 private enum LANG_NEUTRAL = 0x00; 63 private enum SUBLANG_DEFAULT = 0x01; 64 65 private extern (Windows) 66 { 67 DWORD FormatMessageW (DWORD dwFlags, 68 LPCVOID lpSource, 69 DWORD dwMessageId, 70 DWORD dwLanguageId, 71 LPWSTR lpBuffer, 72 DWORD nSize, 73 LPCVOID args 74 ); 75 76 HLOCAL LocalFree(HLOCAL hMem); 77 } 78 } 79 else 80 version (Posix) 81 { 82 private import tango.stdc.errno; 83 private import tango.stdc.string; 84 } 85 else 86 { 87 pragma (msg, "Unsupported environment; neither Win32 or Posix is declared"); 88 static assert(0); 89 } 90 91 92 /******************************************************************************* 93 94 *******************************************************************************/ 95 96 struct SysError 97 { 98 /*********************************************************************** 99 100 ***********************************************************************/ 101 102 @property static uint lastCode () 103 { 104 version (Win32) 105 return GetLastError(); 106 else 107 return errno; 108 } 109 110 /*********************************************************************** 111 112 ***********************************************************************/ 113 114 @property static char[] lastMsg () 115 { 116 return lookup (lastCode); 117 } 118 119 /*********************************************************************** 120 121 ***********************************************************************/ 122 123 @property static char[] lookup (uint errcode) 124 { 125 char[] text; 126 127 version (Win32) 128 { 129 DWORD i; 130 LPWSTR lpMsgBuf; 131 132 i = FormatMessageW ( 133 FORMAT_MESSAGE_ALLOCATE_BUFFER | 134 FORMAT_MESSAGE_FROM_SYSTEM | 135 FORMAT_MESSAGE_IGNORE_INSERTS, 136 null, 137 errcode, 138 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 139 cast(LPWSTR)&lpMsgBuf, 140 0, 141 null); 142 143 /* Remove \r\n from error string */ 144 if (i >= 2) i -= 2; 145 text = new char[i * 3]; 146 i = WideCharToMultiByte (CP_UTF8, 0, lpMsgBuf, i, 147 cast(PCHAR)text.ptr, text.length, null, null); 148 text = text [0 .. i]; 149 LocalFree (cast(HLOCAL) lpMsgBuf); 150 } 151 else 152 { 153 size_t r; 154 char* pemsg; 155 156 pemsg = strerror(errcode); 157 r = strlen(pemsg); 158 159 /* Remove \r\n from error string */ 160 if (pemsg[r-1] == '\n') r--; 161 if (pemsg[r-1] == '\r') r--; 162 text = pemsg[0..r].dup; 163 } 164 165 return text; 166 } 167 }