[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