diff options
Diffstat (limited to 'lldb/source/Host/windows/Windows.cpp')
-rw-r--r-- | lldb/source/Host/windows/Windows.cpp | 401 |
1 files changed, 189 insertions, 212 deletions
diff --git a/lldb/source/Host/windows/Windows.cpp b/lldb/source/Host/windows/Windows.cpp index a1ee5d6..8347b82 100644 --- a/lldb/source/Host/windows/Windows.cpp +++ b/lldb/source/Host/windows/Windows.cpp @@ -9,276 +9,253 @@ // This file provides Windows support functions -#include "lldb/Host/windows/windows.h" #include "lldb/Host/PosixApi.h" +#include "lldb/Host/windows/windows.h" #include "llvm/Support/ConvertUTF.h" #include <assert.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <stdlib.h> -#include <io.h> #include <cerrno> #include <ctype.h> +#include <io.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> -// These prototypes are defined in <direct.h>, but it also defines chdir() and getcwd(), giving multiply defined errors -extern "C" -{ - char *_getcwd(char *buffer, int maxlen); - int _chdir(const char *path); +// These prototypes are defined in <direct.h>, but it also defines chdir() and +// getcwd(), giving multiply defined errors +extern "C" { +char *_getcwd(char *buffer, int maxlen); +int _chdir(const char *path); } -namespace -{ -bool -utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize) -{ - const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(utf8); - size_t sourceLen = strlen(utf8) + 1 /* convert null too */; - UTF16 *target = reinterpret_cast<UTF16 *>(buf); - ConversionFlags flags = strictConversion; - return ConvertUTF8toUTF16(&sourceStart, sourceStart + sourceLen, &target, target + bufSize, flags) == conversionOK; +namespace { +bool utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize) { + const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(utf8); + size_t sourceLen = strlen(utf8) + 1 /* convert null too */; + UTF16 *target = reinterpret_cast<UTF16 *>(buf); + ConversionFlags flags = strictConversion; + return ConvertUTF8toUTF16(&sourceStart, sourceStart + sourceLen, &target, + target + bufSize, flags) == conversionOK; } -bool -wideToUtf8(const wchar_t *wide, char *buf, size_t bufSize) -{ - const UTF16 *sourceStart = reinterpret_cast<const UTF16 *>(wide); - size_t sourceLen = wcslen(wide) + 1 /* convert null too */; - UTF8 *target = reinterpret_cast<UTF8 *>(buf); - ConversionFlags flags = strictConversion; - return ConvertUTF16toUTF8(&sourceStart, sourceStart + sourceLen, &target, target + bufSize, flags) == conversionOK; +bool wideToUtf8(const wchar_t *wide, char *buf, size_t bufSize) { + const UTF16 *sourceStart = reinterpret_cast<const UTF16 *>(wide); + size_t sourceLen = wcslen(wide) + 1 /* convert null too */; + UTF8 *target = reinterpret_cast<UTF8 *>(buf); + ConversionFlags flags = strictConversion; + return ConvertUTF16toUTF8(&sourceStart, sourceStart + sourceLen, &target, + target + bufSize, flags) == conversionOK; } } -int vasprintf(char **ret, const char *fmt, va_list ap) -{ - char *buf; - int len; - size_t buflen; - va_list ap2; +int vasprintf(char **ret, const char *fmt, va_list ap) { + char *buf; + int len; + size_t buflen; + va_list ap2; #if defined(_MSC_VER) || defined(__MINGW64) - ap2 = ap; - len = _vscprintf(fmt, ap2); + ap2 = ap; + len = _vscprintf(fmt, ap2); #else - va_copy(ap2, ap); - len = vsnprintf(NULL, 0, fmt, ap2); + va_copy(ap2, ap); + len = vsnprintf(NULL, 0, fmt, ap2); #endif - if (len >= 0 && (buf = (char*) malloc ((buflen = (size_t) (len + 1)))) != NULL) { - len = vsnprintf(buf, buflen, fmt, ap); - *ret = buf; - } else { - *ret = NULL; - len = -1; - } - - va_end(ap2); - return len; + if (len >= 0 && + (buf = (char *)malloc((buflen = (size_t)(len + 1)))) != NULL) { + len = vsnprintf(buf, buflen, fmt, ap); + *ret = buf; + } else { + *ret = NULL; + len = -1; + } + + va_end(ap2); + return len; } -char* strcasestr(const char *s, const char* find) -{ - char c, sc; - size_t len; - - if ((c = *find++) != 0) { - c = tolower((unsigned char) c); - len = strlen(find); - do { - do { - if ((sc = *s++) == 0) - return 0; - } while ((char) tolower((unsigned char) sc) != c); - } while (strncasecmp(s, find, len) != 0); - s--; - } - return ((char *) s); +char *strcasestr(const char *s, const char *find) { + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return 0; + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); } -char* realpath(const char * name, char * resolved) -{ - char *retname = NULL; - - /* SUSv3 says we must set `errno = EINVAL', and return NULL, - * if `name' is passed as a NULL pointer. - */ - if (name == NULL) - { - errno = EINVAL; - return NULL; - } +char *realpath(const char *name, char *resolved) { + char *retname = NULL; - /* Otherwise, `name' must refer to a readable filesystem object, - * if we are going to resolve its absolute path name. - */ - wchar_t wideNameBuffer[PATH_MAX]; - wchar_t *wideName = wideNameBuffer; - if (!utf8ToWide(name, wideName, PATH_MAX)) - { - errno = EINVAL; - return NULL; - } + /* SUSv3 says we must set `errno = EINVAL', and return NULL, + * if `name' is passed as a NULL pointer. + */ + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + /* Otherwise, `name' must refer to a readable filesystem object, + * if we are going to resolve its absolute path name. + */ + wchar_t wideNameBuffer[PATH_MAX]; + wchar_t *wideName = wideNameBuffer; + if (!utf8ToWide(name, wideName, PATH_MAX)) { + errno = EINVAL; + return NULL; + } - if (_waccess(wideName, 4) != 0) - return NULL; + if (_waccess(wideName, 4) != 0) + return NULL; - /* If `name' didn't point to an existing entity, - * then we don't get to here; we simply fall past this block, - * returning NULL, with `errno' appropriately set by `access'. + /* If `name' didn't point to an existing entity, + * then we don't get to here; we simply fall past this block, + * returning NULL, with `errno' appropriately set by `access'. + * + * When we _do_ get to here, then we can use `_fullpath' to + * resolve the full path for `name' into `resolved', but first, + * check that we have a suitable buffer, in which to return it. + */ + + if ((retname = resolved) == NULL) { + /* Caller didn't give us a buffer, so we'll exercise the + * option granted by SUSv3, and allocate one. * - * When we _do_ get to here, then we can use `_fullpath' to - * resolve the full path for `name' into `resolved', but first, - * check that we have a suitable buffer, in which to return it. + * `_fullpath' would do this for us, but it uses `malloc', and + * Microsoft's implementation doesn't set `errno' on failure. + * If we don't do this explicitly ourselves, then we will not + * know if `_fullpath' fails on `malloc' failure, or for some + * other reason, and we want to set `errno = ENOMEM' for the + * `malloc' failure case. */ - if ((retname = resolved) == NULL) - { - /* Caller didn't give us a buffer, so we'll exercise the - * option granted by SUSv3, and allocate one. - * - * `_fullpath' would do this for us, but it uses `malloc', and - * Microsoft's implementation doesn't set `errno' on failure. - * If we don't do this explicitly ourselves, then we will not - * know if `_fullpath' fails on `malloc' failure, or for some - * other reason, and we want to set `errno = ENOMEM' for the - * `malloc' failure case. - */ - - retname = (char *)malloc(PATH_MAX); - if (retname == NULL) - { - errno = ENOMEM; - return NULL; - } + retname = (char *)malloc(PATH_MAX); + if (retname == NULL) { + errno = ENOMEM; + return NULL; } + } - /* Otherwise, when we do have a valid buffer, - * `_fullpath' should only fail if the path name is too long. - */ + /* Otherwise, when we do have a valid buffer, + * `_fullpath' should only fail if the path name is too long. + */ - wchar_t wideFullPathBuffer[PATH_MAX]; - wchar_t *wideFullPath; - if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) == NULL) - { - errno = ENAMETOOLONG; - return NULL; - } + wchar_t wideFullPathBuffer[PATH_MAX]; + wchar_t *wideFullPath; + if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) == + NULL) { + errno = ENAMETOOLONG; + return NULL; + } - // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS - // FIXME: Check for failure - size_t initialLength = wcslen(wideFullPath); - GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX); - GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1); + // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS + // FIXME: Check for failure + size_t initialLength = wcslen(wideFullPath); + GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX); + GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1); - // Convert back to UTF-8 - if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX)) - { - errno = EINVAL; - return NULL; - } + // Convert back to UTF-8 + if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX)) { + errno = EINVAL; + return NULL; + } - // Force drive to be upper case - if (retname[1] == ':') - retname[0] = toupper(retname[0]); + // Force drive to be upper case + if (retname[1] == ':') + retname[0] = toupper(retname[0]); - return retname; + return retname; } #ifdef _MSC_VER -char* basename(char *path) -{ - char* l1 = strrchr(path, '\\'); - char* l2 = strrchr(path, '/'); - if (l2 > l1) l1 = l2; - if (!l1) return path; // no base name - return &l1[1]; +char *basename(char *path) { + char *l1 = strrchr(path, '\\'); + char *l2 = strrchr(path, '/'); + if (l2 > l1) + l1 = l2; + if (!l1) + return path; // no base name + return &l1[1]; } // use _getcwd() instead of GetCurrentDirectory() because it updates errno -char* getcwd(char* path, int max) -{ - assert(path == NULL || max <= PATH_MAX); - wchar_t wpath[PATH_MAX]; - if (wchar_t *wresult = _wgetcwd(wpath, PATH_MAX)) - { - // Caller is allowed to pass in NULL for `path`. - // In that case, we're supposed to allocate a - // buffer on the caller's behalf. - if (path == NULL) - { - max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1; - path = (char *)malloc(max); - if (path == NULL) - { - errno = ENOMEM; - return NULL; - } - } - if (wideToUtf8(wresult, path, max)) - return path; +char *getcwd(char *path, int max) { + assert(path == NULL || max <= PATH_MAX); + wchar_t wpath[PATH_MAX]; + if (wchar_t *wresult = _wgetcwd(wpath, PATH_MAX)) { + // Caller is allowed to pass in NULL for `path`. + // In that case, we're supposed to allocate a + // buffer on the caller's behalf. + if (path == NULL) { + max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1; + path = (char *)malloc(max); + if (path == NULL) { + errno = ENOMEM; + return NULL; + } } - return NULL; + if (wideToUtf8(wresult, path, max)) + return path; + } + return NULL; } // use _chdir() instead of SetCurrentDirectory() because it updates errno -int chdir(const char* path) -{ - return _chdir(path); -} - -char *dirname(char *path) -{ - char* l1 = strrchr(path, '\\'); - char* l2 = strrchr(path, '/'); - if (l2 > l1) l1 = l2; - if (!l1) return NULL; // no dir name - *l1 = 0; - return path; +int chdir(const char *path) { return _chdir(path); } + +char *dirname(char *path) { + char *l1 = strrchr(path, '\\'); + char *l2 = strrchr(path, '/'); + if (l2 > l1) + l1 = l2; + if (!l1) + return NULL; // no dir name + *l1 = 0; + return path; } -int strcasecmp(const char* s1, const char* s2) -{ - return stricmp(s1, s2); -} +int strcasecmp(const char *s1, const char *s2) { return stricmp(s1, s2); } -int strncasecmp(const char* s1, const char* s2, size_t n) -{ - return strnicmp(s1, s2, n); +int strncasecmp(const char *s1, const char *s2, size_t n) { + return strnicmp(s1, s2, n); } -int usleep(uint32_t useconds) -{ - Sleep(useconds / 1000); - return 0; +int usleep(uint32_t useconds) { + Sleep(useconds / 1000); + return 0; } #if _MSC_VER < 1900 namespace lldb_private { -int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) -{ - int old_errno = errno; - int r = ::vsnprintf(buffer, count, format, argptr); - int new_errno = errno; - buffer[count-1] = '\0'; - if (r == -1 || r == count) - { - FILE *nul = fopen("nul", "w"); - int bytes_written = ::vfprintf(nul, format, argptr); - fclose(nul); - if (bytes_written < count) - errno = new_errno; - else - { - errno = old_errno; - r = bytes_written; - } +int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) { + int old_errno = errno; + int r = ::vsnprintf(buffer, count, format, argptr); + int new_errno = errno; + buffer[count - 1] = '\0'; + if (r == -1 || r == count) { + FILE *nul = fopen("nul", "w"); + int bytes_written = ::vfprintf(nul, format, argptr); + fclose(nul); + if (bytes_written < count) + errno = new_errno; + else { + errno = old_errno; + r = bytes_written; } - return r; + } + return r; } } // namespace lldb_private #endif |