forked from OSchip/llvm-project
Properly handle short file names on the command line in Windows [TAKE 2]
Trying to expand short names with a relative path doesn't work, so this first gets the module name to get a full path (which can still have short names). llvm-svn: 273171
This commit is contained in:
parent
a038240660
commit
f833141187
|
@ -201,6 +201,9 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
|||
const int DirSize = Dir.size();
|
||||
|
||||
// Search for matching files.
|
||||
// FIXME: This assumes the wildcard is only in the file name and not in the
|
||||
// directory portion of the file path. For example, it doesn't handle
|
||||
// "*\foo.c" nor "s?c\bar.cpp".
|
||||
WIN32_FIND_DATAW FileData;
|
||||
HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
|
||||
if (FindHandle == INVALID_HANDLE_VALUE) {
|
||||
|
@ -215,7 +218,7 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
|||
if (ec)
|
||||
break;
|
||||
|
||||
// Push the filename onto Dir, and remove it afterwards.
|
||||
// Append FileName to Dir, and remove it afterwards.
|
||||
llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size()));
|
||||
AllocateAndPush(Dir, Args, Allocator);
|
||||
Dir.resize(DirSize);
|
||||
|
@ -225,6 +228,23 @@ WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
|||
return ec;
|
||||
}
|
||||
|
||||
static std::error_code
|
||||
ExpandShortFileName(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
|
||||
SpecificBumpPtrAllocator<char> &Allocator) {
|
||||
SmallVector<wchar_t, MAX_PATH> LongPath;
|
||||
DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
|
||||
if (Length == 0)
|
||||
return mapWindowsError(GetLastError());
|
||||
if (Length > LongPath.capacity()) {
|
||||
// We're not going to try to deal with paths longer than MAX_PATH, so we'll
|
||||
// treat this as an error. GetLastError() returns ERROR_SUCCESS, which
|
||||
// isn't useful, so we'll hardcode an appropriate error value.
|
||||
return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
LongPath.set_size(Length);
|
||||
return ConvertAndPushArg(LongPath.data(), Args, Allocator);
|
||||
}
|
||||
|
||||
std::error_code
|
||||
Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
|
||||
ArrayRef<const char *>,
|
||||
|
@ -238,7 +258,19 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
|
|||
Args.reserve(ArgCount);
|
||||
std::error_code ec;
|
||||
|
||||
for (int i = 0; i < ArgCount; ++i) {
|
||||
// The first argument may contain just the name of the executable (e.g.,
|
||||
// "clang") rather than the full path, so swap it with the full path.
|
||||
wchar_t ModuleName[MAX_PATH];
|
||||
int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
|
||||
if (0 < Length && Length < MAX_PATH)
|
||||
UnicodeCommandLine[0] = ModuleName;
|
||||
|
||||
// If the first argument is a shortened (8.3) name (which is possible even
|
||||
// if we got the module name), the driver will have trouble distinguishing it
|
||||
// (e.g., clang.exe v. clang++.exe), so expand it now.
|
||||
ec = ExpandShortFileName(UnicodeCommandLine[0], Args, ArgAllocator);
|
||||
|
||||
for (int i = 1; i < ArgCount && !ec; ++i) {
|
||||
ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
|
||||
if (ec)
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue