blob: cb69a9cb3e42ba337ad35fb7275ea2a98715fe83 [file] [log] [blame]
Virgile Bellob2f1fb22013-08-23 12:44:05 +00001//===-- Windows.cpp ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// This file provides Windows support functions
11
12#include "lldb/Host/windows/windows.h"
13#include "lldb/Host/windows/win32.h"
14
15#include <stdio.h>
16#include <stdarg.h>
17#include <string.h>
18#include <stdlib.h>
19#include <io.h>
20#include <cerrno>
Hafiz Abid Qadeerbdb51592014-03-12 10:39:46 +000021#include <ctype.h>
Virgile Bellob2f1fb22013-08-23 12:44:05 +000022
23int vasprintf(char **ret, const char *fmt, va_list ap)
24{
25 char *buf;
26 int len;
27 size_t buflen;
28 va_list ap2;
29
30#if defined(_MSC_VER) || defined(__MINGW64)
31 ap2 = ap;
32 len = _vscprintf(fmt, ap2);
33#else
34 va_copy(ap2, ap);
35 len = vsnprintf(NULL, 0, fmt, ap2);
36#endif
37
38 if (len >= 0 && (buf = (char*) malloc ((buflen = (size_t) (len + 1)))) != NULL) {
39 len = vsnprintf(buf, buflen, fmt, ap);
40 *ret = buf;
41 } else {
42 *ret = NULL;
43 len = -1;
44 }
45
46 va_end(ap2);
47 return len;
48}
49
Virgile Bellod87fc152013-09-07 05:05:49 +000050char* strcasestr(const char *s, const char* find)
Virgile Bellob2f1fb22013-08-23 12:44:05 +000051{
52 char c, sc;
53 size_t len;
54
55 if ((c = *find++) != 0) {
56 c = tolower((unsigned char) c);
57 len = strlen(find);
58 do {
59 do {
60 if ((sc = *s++) == 0)
61 return 0;
62 } while ((char) tolower((unsigned char) sc) != c);
63 } while (strncasecmp(s, find, len) != 0);
64 s--;
65 }
66 return ((char *) s);
67}
68
Virgile Belloae12a362013-08-27 16:21:49 +000069char* realpath(const char * name, char * resolved)
Virgile Bellob2f1fb22013-08-23 12:44:05 +000070{
71 char *retname = NULL; /* we will return this, if we fail */
72
73 /* SUSv3 says we must set `errno = EINVAL', and return NULL,
74 * if `name' is passed as a NULL pointer.
75 */
76
77 if (name == NULL)
78 errno = EINVAL;
79
80 /* Otherwise, `name' must refer to a readable filesystem object,
81 * if we are going to resolve its absolute path name.
82 */
83
84 else if (access(name, 4) == 0)
85 {
86 /* If `name' didn't point to an existing entity,
87 * then we don't get to here; we simply fall past this block,
88 * returning NULL, with `errno' appropriately set by `access'.
89 *
90 * When we _do_ get to here, then we can use `_fullpath' to
91 * resolve the full path for `name' into `resolved', but first,
92 * check that we have a suitable buffer, in which to return it.
93 */
94
95 if ((retname = resolved) == NULL)
96 {
97 /* Caller didn't give us a buffer, so we'll exercise the
98 * option granted by SUSv3, and allocate one.
99 *
100 * `_fullpath' would do this for us, but it uses `malloc', and
101 * Microsoft's implementation doesn't set `errno' on failure.
102 * If we don't do this explicitly ourselves, then we will not
103 * know if `_fullpath' fails on `malloc' failure, or for some
104 * other reason, and we want to set `errno = ENOMEM' for the
105 * `malloc' failure case.
106 */
107
108 retname = (char*) malloc(_MAX_PATH);
109 }
110
111 /* By now, we should have a valid buffer.
112 * If we don't, then we know that `malloc' failed,
113 * so we can set `errno = ENOMEM' appropriately.
114 */
115
116 if (retname == NULL)
117 errno = ENOMEM;
118
119 /* Otherwise, when we do have a valid buffer,
120 * `_fullpath' should only fail if the path name is too long.
121 */
122
123 else if ((retname = _fullpath(retname, name, _MAX_PATH)) == NULL)
124 errno = ENAMETOOLONG;
125 }
126
127 /* By the time we get to here,
128 * `retname' either points to the required resolved path name,
129 * or it is NULL, with `errno' set appropriately, either of which
130 * is our required return condition.
131 */
132
133 if (retname != NULL)
134 {
135 // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
136 int initialLength = strlen(retname);
137 TCHAR buffer[MAX_PATH];
138 GetShortPathName(retname, buffer, MAX_PATH);
139 GetLongPathName(buffer, retname, initialLength + 1);
140
141 // Force drive to be upper case
142 if (retname[1] == ':')
143 retname[0] = toupper(retname[0]);
144 }
145
146 return retname;
147}
Virgile Bellod87fc152013-09-07 05:05:49 +0000148
149#ifdef _MSC_VER
150
151char* basename(char *path)
152{
153 char* l1 = strrchr(path, '\\');
154 char* l2 = strrchr(path, '/');
155 if (l2 > l1) l1 = l2;
156 if (!l1) return path; // no base name
157 return &l1[1];
158}
159
160char* getcwd(char* path, int max)
161{
162 if (GetCurrentDirectory(max, path) == 0)
163 return path;
164 return NULL;
165}
166
167char *dirname(char *path)
168{
169 char* l1 = strrchr(path, '\\');
170 char* l2 = strrchr(path, '/');
171 if (l2 > l1) l1 = l2;
172 if (!l1) return NULL; // no dir name
173 *l1 = 0;
174 return path;
175}
176
177int strcasecmp(const char* s1, const char* s2)
178{
Zachary Turner12f6f532014-07-29 19:08:55 +0000179 return stricmp(s1, s2);
Virgile Bellod87fc152013-09-07 05:05:49 +0000180}
181
182int strncasecmp(const char* s1, const char* s2, size_t n)
183{
Zachary Turner12f6f532014-07-29 19:08:55 +0000184 return strnicmp(s1, s2, n);
Virgile Bellod87fc152013-09-07 05:05:49 +0000185}
186
187int usleep(uint32_t useconds)
188{
189 Sleep(useconds / 1000);
190 return 0;
191}
192
193#endif // _MSC_VER