From 431b0a7646105c53c607cbf0015c615269bc5f11 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 18 Jul 2013 16:52:05 +0000 Subject: [Support] Beef up and expose the response file parsing in llvm::cl The plan is to use it for clang and lld. Major behavior changes: - We can now parse UTF-16 files that have a byte order mark. - PR16209: Don't drop backslashes on the floor if they don't escape anything. The actual parsing loop was based on code from Clang's driver.cpp, although it's been rewritten to track its state with control flow rather than state variables. Reviewers: hans Differential Revision: http://llvm-reviews.chandlerc.com/D1170 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186587 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/CommandLine.h | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'include') diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 531760b01d..8fb4630667 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -1745,6 +1745,59 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false); /// llvm::cl::ParseCommandLineOptions(). void getRegisteredOptions(StringMap &Map); +//===----------------------------------------------------------------------===// +// Standalone command line processing utilities. +// + +/// \brief Saves strings in the inheritor's stable storage and returns a stable +/// raw character pointer. +class StringSaver { +public: + virtual const char *SaveString(const char *Str) = 0; + virtual ~StringSaver() {}; // Pacify -Wnon-virtual-dtor. +}; + +/// \brief Tokenizes a command line that can contain escapes and quotes. +// +/// The quoting rules match those used by GCC and other tools that use +/// libiberty's buildargv() or expandargv() utilities, and do not match bash. +/// They differ from buildargv() on treatment of backslashes that do not escape +/// a special character to make it possible to accept most Windows file paths. +/// +/// \param [in] Source The string to be split on whitespace with quotes. +/// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [out] NewArgv All parsed strings are appended to NewArgv. +void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, + SmallVectorImpl &NewArgv); + +/// \brief Tokenizes a Windows command line which may contain quotes and escaped +/// quotes. +/// +/// See MSDN docs for CommandLineToArgvW for information on the quoting rules. +/// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx +/// +/// \param [in] Source The string to be split on whitespace with quotes. +/// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [out] NewArgv All parsed strings are appended to NewArgv. +void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, + SmallVectorImpl &NewArgv); + +/// \brief String tokenization function type. Should be compatible with either +/// Windows or Unix command line tokenizers. +typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver, + SmallVectorImpl &NewArgv); + +/// \brief Expand response files on a command line recursively using the given +/// StringSaver and tokenization strategy. Argv should contain the command line +/// before expansion and will be modified in place. +/// +/// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [in] Tokenize Tokenization strategy. Typically Unix or Windows. +/// \param [in,out] Argv Command line into which to expand response files. +/// \return true if all @files were expanded successfully or there were none. +bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, + SmallVectorImpl &Argv); + } // End namespace cl } // End namespace llvm -- cgit v1.2.3