[llvm] r213114 - Perform wildcard expansion in Process::GetArgumentVector on Windows (PR17098)
David Majnemer
david.majnemer at gmail.com
Wed Jul 16 07:47:01 PDT 2014
On Wednesday, July 16, 2014, Timur Iskhodzhanov <timurrrr at google.com> wrote:
> 2014-07-16 4:52 GMT+04:00 Hans Wennborg <hans at hanshq.net <javascript:;>>:
> > Author: hans
> > Date: Tue Jul 15 19:52:11 2014
> > New Revision: 213114
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=213114&view=rev
> > Log:
> > Perform wildcard expansion in Process::GetArgumentVector on Windows
> (PR17098)
> >
> > On Windows, wildcard expansion isn't performed by the shell, but left to
> the
> > program itself. The common way to do this is to link with setargv.obj,
> which
> > performs the expansion on argc/argv before main is entered. However, we
> don't
> > use argv in Clang on Windows, but instead call GetCommandLineW so we can
> handle
> > unicode arguments.
>
> Why don't we use wmain?
Because using it with MinGW is non trivial.
>
> > This means we have to do wildcard expansion ourselves.
> >
> > A test case will be added on the Clang side.
> >
> > Differential Revision: http://reviews.llvm.org/D4529
> >
> > Modified:
> > llvm/trunk/lib/Support/Windows/Process.inc
> >
> > Modified: llvm/trunk/lib/Support/Windows/Process.inc
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Process.inc?rev=213114&r1=213113&r2=213114&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Support/Windows/Process.inc (original)
> > +++ llvm/trunk/lib/Support/Windows/Process.inc Tue Jul 15 19:52:11 2014
> > @@ -183,37 +183,89 @@ static std::error_code windows_error(DWO
> > return mapWindowsError(E);
> > }
> >
> > +static void AllocateAndPush(const SmallVectorImpl<char> &S,
> > + SmallVectorImpl<const char *> &Vector,
> > + SpecificBumpPtrAllocator<char> &Allocator) {
> > + char *Buffer = Allocator.Allocate(S.size() + 1);
> > + ::memcpy(Buffer, S.data(), S.size());
> > + Buffer[S.size()] = '\0';
> > + Vector.push_back(Buffer);
> > +}
> > +
> > +/// Convert Arg from UTF-16 to UTF-8 and push it onto Args.
> > +static std::error_code
> > +ConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl<const char *>
> &Args,
> > + SpecificBumpPtrAllocator<char> &Allocator) {
> > + SmallVector<char, MAX_PATH> ArgString;
> > + if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg),
> ArgString))
> > + return ec;
> > + AllocateAndPush(ArgString, Args, Allocator);
> > + return std::error_code();
> > +}
> > +
> > +/// \brief Perform wildcard expansion of Arg, or just push it into Args
> if it
> > +/// doesn't have wildcards or doesn't match any files.
> > +static std::error_code
> > +WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args,
> > + SpecificBumpPtrAllocator<char> &Allocator) {
> > + if (!wcspbrk(Arg, L"*?")) {
> > + // Arg does not contain any wildcard characters. This is the common
> case.
> > + return ConvertAndPushArg(Arg, Args, Allocator);
> > + }
> > +
> > + // Extract any directory part of the argument.
> > + SmallVector<char, MAX_PATH> Dir;
> > + if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), Dir))
> > + return ec;
> > + sys::path::remove_filename(Dir);
> > + const int DirSize = Dir.size();
> > +
> > + // Search for matching files.
> > + WIN32_FIND_DATAW FileData;
> > + HANDLE FindHandle = FindFirstFileW(Arg, &FileData);
> > + if (FindHandle == INVALID_HANDLE_VALUE) {
> > + return ConvertAndPushArg(Arg, Args, Allocator);
> > + }
> > +
> > + std::error_code ec;
> > + do {
> > + SmallVector<char, MAX_PATH> FileName;
> > + ec = windows::UTF16ToUTF8(FileData.cFileName,
> wcslen(FileData.cFileName),
> > + FileName);
> > + if (ec)
> > + break;
> > +
> > + // Push the filename onto Dir, and remove it afterwards.
> > + llvm::sys::path::append(Dir, StringRef(FileName.data(),
> FileName.size()));
> > + AllocateAndPush(Dir, Args, Allocator);
> > + Dir.resize(DirSize);
> > + } while (FindNextFileW(FindHandle, &FileData));
> > +
> > + FindClose(FindHandle);
> > + return ec;
> > +}
> > +
> > std::error_code
> > Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
> > ArrayRef<const char *>,
> > SpecificBumpPtrAllocator<char>
> &ArgAllocator) {
> > - int NewArgCount;
> > - std::error_code ec;
> > -
> > - wchar_t **UnicodeCommandLine = CommandLineToArgvW(GetCommandLineW(),
> > - &NewArgCount);
> > + int ArgCount;
> > + wchar_t **UnicodeCommandLine =
> > + CommandLineToArgvW(GetCommandLineW(), &ArgCount);
> > if (!UnicodeCommandLine)
> > return windows_error(::GetLastError());
> >
> > - Args.reserve(NewArgCount);
> > + Args.reserve(ArgCount);
> > + std::error_code ec;
> >
> > - for (int i = 0; i < NewArgCount; ++i) {
> > - SmallVector<char, MAX_PATH> NewArgString;
> > - ec = windows::UTF16ToUTF8(UnicodeCommandLine[i],
> > - wcslen(UnicodeCommandLine[i]),
> > - NewArgString);
> > + for (int i = 0; i < ArgCount; ++i) {
> > + ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator);
> > if (ec)
> > break;
> > -
> > - char *Buffer = ArgAllocator.Allocate(NewArgString.size() + 1);
> > - ::memcpy(Buffer, NewArgString.data(), NewArgString.size() + 1);
> > - Args.push_back(Buffer);
> > }
> > - LocalFree(UnicodeCommandLine);
> > - if (ec)
> > - return ec;
> >
> > - return std::error_code();
> > + LocalFree(UnicodeCommandLine);
> > + return ec;
> > }
> >
> > bool Process::StandardInIsUserInput() {
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu <javascript:;>
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu <javascript:;>
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140716/a897ca56/attachment.html>
More information about the llvm-commits
mailing list