[llvm-commits] CVS: llvm/lib/Support/CommandLine.cpp

Brian Gaeke gaeke at niobe.cs.uiuc.edu
Fri Aug 15 16:07:12 PDT 2003


Changes in directory llvm/lib/Support:

CommandLine.cpp updated: 1.35 -> 1.36

---
Log message:

lib/Support/CommandLine.cpp:
Many changes suggested by Chris. It's okay, I'll recover from the emotional
damage...maybe someday. :-)

Collapse ParseCStringVector into ParseStringVector.  Comment it.
Make it take a const input.
Use std::string::npos instead of -1 (what a mouthful!)
Make ParseEnvironmentOptions take const inputs.
Check its args at the very beginning.
Strdup all the contents of newArgv and free them all at the end.

include/Support/CommandLine.h:
Constify progName and envVar arguments to ParseEnvironmentOptions().


---
Diffs of the changes:

Index: llvm/lib/Support/CommandLine.cpp
diff -u llvm/lib/Support/CommandLine.cpp:1.35 llvm/lib/Support/CommandLine.cpp:1.36
--- llvm/lib/Support/CommandLine.cpp:1.35	Thu Aug 14 17:00:58 2003
+++ llvm/lib/Support/CommandLine.cpp	Fri Aug 15 16:05:57 2003
@@ -152,44 +152,48 @@
          O->getNumOccurrencesFlag() == cl::OneOrMore;
 }
 
-/// ParseStringVector - Break INPUT up wherever one or more characters
-/// from DELIMS are found, and store the resulting tokens in OUTPUT.
+/// ParseCStringVector - Break INPUT up wherever one or more
+/// whitespace characters are found, and store the resulting tokens in
+/// OUTPUT. The tokens stored in OUTPUT are dynamically allocated
+/// using strdup (), so it is the caller's responsibility to free ()
+/// them later.
 ///
-static void ParseStringVector (std::vector<std::string> &output,
-			       std::string &input, const char *delims) {
+static void ParseCStringVector (std::vector<char *> &output,
+				const char *input) {
+  // Characters which will be treated as token separators:
+  static const char *delims = " \v\f\t\r\n";
+
   std::string work (input);
-  int pos = work.find_first_not_of (delims);
-  if (pos == -1) return;
+  // Skip past any delims at head of input string.
+  size_t pos = work.find_first_not_of (delims);
+  // If the string consists entirely of delims, then exit early.
+  if (pos == std::string::npos) return;
+  // Otherwise, jump forward to beginning of first word.
   work = work.substr (pos);
+  // Find position of first delimiter.
   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) {
+
+  while (!work.empty() && pos != std::string::npos) {
+    // Everything from 0 to POS is the next word to copy.
+    output.push_back (strdup (work.substr (0,pos).c_str ()));
+    // Is there another word in the string?
+    size_t nextpos = work.find_first_not_of (delims, pos + 1);
+    if (nextpos != std::string::npos) {
+      // Yes? Then remove delims from beginning ...
       work = work.substr (work.find_first_not_of (delims, pos + 1));
+      // and find the end of the word.
       pos = work.find_first_of (delims);
     } else {
+      // No? (Remainder of string is delims.) End the loop.
       work = "";
-      pos = -1;
+      pos = std::string::npos;
     }
   }
-  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<char *> &output,
-				std::string &input, const char *delims) {
-  std::vector<std::string> work;
-  ParseStringVector (work, input, delims);
-  for (std::vector<std::string>::iterator i = work.begin(), e = work.end();
-       i != e; ++i) {
-    output.push_back (strdup (i->c_str ()));
+  // If `input' ended with non-delim char, then we'll get here with
+  // the last word of `input' in `work'; copy it now.
+  if (!work.empty ()) {
+    output.push_back (strdup (work.c_str ()));
   }
 }
 
@@ -198,32 +202,33 @@
 /// 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,
+void cl::ParseEnvironmentOptions (const char *progName, const char *envVar,
 				  const char *Overview) {
-  // Get program's "name", which we wouldn't know without the caller
-  // telling us.
+  // Check args.
   assert (progName && "Program name not specified");
-  static std::vector<char *> newargv; // Maybe making it "static" is a hack.
-  int newargc;
-  newargv.push_back (progName);
-
+  assert (envVar && "Environment variable name missing");
+  
   // 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);
+  const char *envValue = getenv (envVar);
+  if (!envValue)
     return;
-  }
-  std::string envvaluestr (envvalue);
+
+  // Get program's "name", which we wouldn't know without the caller
+  // telling us.
+  std::vector<char *> newArgv;
+  newArgv.push_back (strdup (progName));
 
   // 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);
+  ParseCStringVector (newArgv, envValue);
+  int newArgc = newArgv.size ();
+  ParseCommandLineOptions (newArgc, &newArgv[0], Overview);
+
+  // Free all the strdup()ed strings.
+  for (std::vector<char *>::iterator i = newArgv.begin (), e = newArgv.end ();
+       i != e; ++i) {
+    free (*i);
+  }
 }
 
 void cl::ParseCommandLineOptions(int &argc, char **argv,





More information about the llvm-commits mailing list