blob: 9c15e26b79d378563015ac69da7fe00411cc7d87 [file] [log] [blame]
Michael J. Spencerdffde992010-11-29 22:28:51 +00001//===- llvm/Support/Win32/PathV2.cpp - Windows Path Impl --------*- 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 implements the Windows specific implementation of the PathV2 API.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15//=== WARNING: Implementation here must contain only generic Windows code that
16//=== is guaranteed to work on *all* Windows variants.
17//===----------------------------------------------------------------------===//
18
19#include "Windows.h"
20
21namespace llvm {
22namespace sys {
23namespace path {
24
25error_code current_path(SmallVectorImpl<char> &result) {
26 SmallVector<wchar_t, 128> cur_path;
27 cur_path.reserve(128);
28retry_cur_dir:
29 DWORD len = ::GetCurrentDirectoryW(cur_path.capacity(), cur_path.data());
30
31 // A zero return value indicates a failure other than insufficient space.
32 if (len == 0)
33 return make_error_code(windows_error(::GetLastError()));
34
35 // If there's insufficient space, the len returned is larger than the len
36 // given.
37 if (len > cur_path.capacity()) {
38 cur_path.reserve(len);
39 goto retry_cur_dir;
40 }
41
42 cur_path.set_size(len);
43 // cur_path now holds the current directory in utf-16. Convert to utf-8.
44
45 // Find out how much space we need. Sadly, this function doesn't return the
46 // size needed unless you tell it the result size is 0, which means you
47 // _always_ have to call it twice.
48 len = ::WideCharToMultiByte(CP_UTF8, NULL,
49 cur_path.data(), cur_path.size(),
50 result.data(), 0,
51 NULL, NULL);
52
53 if (len == 0)
54 return make_error_code(windows_error(::GetLastError()));
55
56 result.reserve(len);
57 result.set_size(len);
58 // Now do the actual conversion.
59 len = ::WideCharToMultiByte(CP_UTF8, NULL,
60 cur_path.data(), cur_path.size(),
61 result.data(), result.size(),
62 NULL, NULL);
63 if (len == 0)
64 return make_error_code(windows_error(::GetLastError()));
65
66 return make_error_code(errc::success);
67}
68
69} // end namespace path
70} // end namespace sys
71} // end namespace llvm