aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Host/windows/Windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/windows/Windows.cpp')
-rw-r--r--lldb/source/Host/windows/Windows.cpp401
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