From: Brian Gaeke Date: Thu, 14 Aug 2003 22:00:59 +0000 (+0000) Subject: Add support for reading command line arguments from an environment variable. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=06b06c5f00acffdab8c59e3dc5baca3eacca172a;p=oota-llvm.git Add support for reading command line arguments from an environment variable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7851 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/Support/CommandLine.h b/include/Support/CommandLine.h index 245d15bc51d..faf82062cc6 100644 --- a/include/Support/CommandLine.h +++ b/include/Support/CommandLine.h @@ -31,6 +31,13 @@ namespace cl { void cl::ParseCommandLineOptions(int &argc, char **argv, const char *Overview = 0); +//===----------------------------------------------------------------------===// +// ParseEnvironmentOptions - Environment variable option processing alternate +// entry point. +// +void cl::ParseEnvironmentOptions (char *progName, char *envvar, + const char *Overview = 0); + //===----------------------------------------------------------------------===// // Flags permitted to be passed to command line arguments // diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 245d15bc51d..faf82062cc6 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -31,6 +31,13 @@ namespace cl { void cl::ParseCommandLineOptions(int &argc, char **argv, const char *Overview = 0); +//===----------------------------------------------------------------------===// +// ParseEnvironmentOptions - Environment variable option processing alternate +// entry point. +// +void cl::ParseEnvironmentOptions (char *progName, char *envvar, + const char *Overview = 0); + //===----------------------------------------------------------------------===// // Flags permitted to be passed to command line arguments // diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 4e3a92fec29..f038d39154a 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -152,6 +152,80 @@ static bool EatsUnboundedNumberOfValues(const Option *O) { O->getNumOccurrencesFlag() == cl::OneOrMore; } +/// ParseStringVector - Break INPUT up wherever one or more characters +/// from DELIMS are found, and store the resulting tokens in OUTPUT. +/// +static void ParseStringVector (std::vector &output, + std::string &input, const char *delims) { + std::string work (input); + int pos = work.find_first_not_of (delims); + if (pos == -1) return; + work = work.substr (pos); + pos = work.find_first_of (delims); + while (!work.empty() && pos != -1) { + if (pos == -1) break; + output.push_back (work.substr (0,pos)); + int nextpos = work.find_first_not_of (delims, pos + 1); + if (nextpos != -1) { + work = work.substr (work.find_first_not_of (delims, pos + 1)); + pos = work.find_first_of (delims); + } else { + work = ""; + pos = -1; + } + } + if (!work.empty ()) { + output.push_back (work); + } +} + +/// ParseCStringVector - Same effect as ParseStringVector, but the +/// resulting output vector contains dynamically-allocated pointers to +/// char, instead of standard C++ strings. +/// +static void ParseCStringVector (std::vector &output, + std::string &input, const char *delims) { + std::vector work; + ParseStringVector (work, input, delims); + for (std::vector::iterator i = work.begin(), e = work.end(); + i != e; ++i) { + output.push_back (strdup (i->c_str ())); + } +} + +/// ParseEnvironmentOptions - An alternative entry point to the +/// CommandLine library, which allows you to read the program's name +/// from the caller (as PROGNAME) and its command-line arguments from +/// an environment variable (whose name is given in ENVVAR). +/// +void cl::ParseEnvironmentOptions (char *progName, char *envvar, + const char *Overview) { + // Get program's "name", which we wouldn't know without the caller + // telling us. + assert (progName && "Program name not specified"); + static std::vector newargv; // Maybe making it "static" is a hack. + int newargc; + newargv.push_back (progName); + + // Get the environment variable they want us to parse options out of. + assert (envvar && "Environment variable name missing"); + char *envvalue = getenv (envvar); + if (envvalue == NULL) { + // Env var not set --> act like there are no more command line + // arguments. + newargc = newargv.size (); + ParseCommandLineOptions (newargc, &newargv[0], Overview); + return; + } + std::string envvaluestr (envvalue); + + // Parse the value of the environment variable into a "command line" + // and hand it off to ParseCommandLineOptions(). + ParseCStringVector (newargv, envvaluestr, " \v\f\t\r\n"); + newargc = newargv.size (); + ParseCommandLineOptions (newargc, &newargv[0], Overview); +} + void cl::ParseCommandLineOptions(int &argc, char **argv, const char *Overview) { assert((!getOpts().empty() || !getPositionalOpts().empty()) && diff --git a/support/lib/Support/CommandLine.cpp b/support/lib/Support/CommandLine.cpp index 4e3a92fec29..f038d39154a 100644 --- a/support/lib/Support/CommandLine.cpp +++ b/support/lib/Support/CommandLine.cpp @@ -152,6 +152,80 @@ static bool EatsUnboundedNumberOfValues(const Option *O) { O->getNumOccurrencesFlag() == cl::OneOrMore; } +/// ParseStringVector - Break INPUT up wherever one or more characters +/// from DELIMS are found, and store the resulting tokens in OUTPUT. +/// +static void ParseStringVector (std::vector &output, + std::string &input, const char *delims) { + std::string work (input); + int pos = work.find_first_not_of (delims); + if (pos == -1) return; + work = work.substr (pos); + pos = work.find_first_of (delims); + while (!work.empty() && pos != -1) { + if (pos == -1) break; + output.push_back (work.substr (0,pos)); + int nextpos = work.find_first_not_of (delims, pos + 1); + if (nextpos != -1) { + work = work.substr (work.find_first_not_of (delims, pos + 1)); + pos = work.find_first_of (delims); + } else { + work = ""; + pos = -1; + } + } + if (!work.empty ()) { + output.push_back (work); + } +} + +/// ParseCStringVector - Same effect as ParseStringVector, but the +/// resulting output vector contains dynamically-allocated pointers to +/// char, instead of standard C++ strings. +/// +static void ParseCStringVector (std::vector &output, + std::string &input, const char *delims) { + std::vector work; + ParseStringVector (work, input, delims); + for (std::vector::iterator i = work.begin(), e = work.end(); + i != e; ++i) { + output.push_back (strdup (i->c_str ())); + } +} + +/// ParseEnvironmentOptions - An alternative entry point to the +/// CommandLine library, which allows you to read the program's name +/// from the caller (as PROGNAME) and its command-line arguments from +/// an environment variable (whose name is given in ENVVAR). +/// +void cl::ParseEnvironmentOptions (char *progName, char *envvar, + const char *Overview) { + // Get program's "name", which we wouldn't know without the caller + // telling us. + assert (progName && "Program name not specified"); + static std::vector newargv; // Maybe making it "static" is a hack. + int newargc; + newargv.push_back (progName); + + // Get the environment variable they want us to parse options out of. + assert (envvar && "Environment variable name missing"); + char *envvalue = getenv (envvar); + if (envvalue == NULL) { + // Env var not set --> act like there are no more command line + // arguments. + newargc = newargv.size (); + ParseCommandLineOptions (newargc, &newargv[0], Overview); + return; + } + std::string envvaluestr (envvalue); + + // Parse the value of the environment variable into a "command line" + // and hand it off to ParseCommandLineOptions(). + ParseCStringVector (newargv, envvaluestr, " \v\f\t\r\n"); + newargc = newargv.size (); + ParseCommandLineOptions (newargc, &newargv[0], Overview); +} + void cl::ParseCommandLineOptions(int &argc, char **argv, const char *Overview) { assert((!getOpts().empty() || !getPositionalOpts().empty()) &&