You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 07:41:12 UTC

svn commit: r1131855 - in /incubator/mesos/trunk: Doxyfile src/configuration.cpp src/configuration.hpp src/tests/test_configuration.cpp

Author: benh
Date: Sun Jun  5 05:41:11 2011
New Revision: 1131855

URL: http://svn.apache.org/viewvc?rev=1131855&view=rev
Log:
Added functionality to Configuration that lets you register options with defaults values and print usage. Some tests added for it too.

Modified:
    incubator/mesos/trunk/Doxyfile
    incubator/mesos/trunk/src/configuration.cpp
    incubator/mesos/trunk/src/configuration.hpp
    incubator/mesos/trunk/src/tests/test_configuration.cpp

Modified: incubator/mesos/trunk/Doxyfile
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/Doxyfile?rev=1131855&r1=1131854&r2=1131855&view=diff
==============================================================================
--- incubator/mesos/trunk/Doxyfile (original)
+++ incubator/mesos/trunk/Doxyfile Sun Jun  5 05:41:11 2011
@@ -611,7 +611,7 @@ EXCLUDE_SYMLINKS       = NO
 # against the file with absolute path, so to exclude all test directories
 # for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = /*.d/
+EXCLUDE_PATTERNS       = *.d
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the

Modified: incubator/mesos/trunk/src/configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configuration.cpp?rev=1131855&r1=1131854&r2=1131855&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configuration.cpp (original)
+++ incubator/mesos/trunk/src/configuration.cpp Sun Jun  5 05:41:11 2011
@@ -138,7 +138,8 @@ void Configuration::loadCommandLine(int 
 }
 
 
-void Configuration::loadConfigFile(const string& fname) {
+void Configuration::loadConfigFile(const string& fname) 
+{
   ifstream cfg(fname.c_str(), std::ios::in);
   if (!cfg.is_open()) {
     string message = "Couldn't read Mesos config file: " + fname;
@@ -164,8 +165,74 @@ void Configuration::loadConfigFile(const
   }
 }
 
+string Configuration::getUsage() const 
+{
+  const int PAD = 10;
+  const int PADEXTRA = string("--=VAL").size(); // adjust for "--" and "=VAL"
+  string usage = "Parameters:\n\n";
+  
+  // get max key length
+  int maxLen = 0;
+  foreachpair(const string& key, _, options) {
+    maxLen = key.size() > maxLen ? key.length() : maxLen;
+  }
+  maxLen += PADEXTRA; 
+
+  foreachpair(const string& key, const Option& val, options) {
+    string helpStr = val.helpString;
+
+    if (val.defaultValue != "") {  // add default value
+      helpStr += " (default VAL=" + val.defaultValue + ")";
+    }
+
+    usage += "--" + key + "=VAL";
+    string pad(PAD + maxLen - key.size() - PADEXTRA, ' ');
+    usage += pad;
+    size_t pos1 = 0, pos2 = 0;
+    pos2 = helpStr.find_first_of("\n\r", pos1);
+    usage += helpStr.substr(pos1, pos2 - pos1) + "\n";
+
+    while(pos2 != string::npos) {  // handle multi line help strings
+      pos1 = pos2 + 1;
+      string pad2(PAD + maxLen, ' ');
+      usage += pad2;
+      pos2 = helpStr.find_first_of("\n\r", pos1);
+      usage += helpStr.substr(pos1, pos2 - pos1) + "\n";
+    }
+
+  }
+  return usage;
+}
+  
+
+int Configuration::addOption(string optName, const string& helpString) 
+{
+  std::transform(optName.begin(), optName.end(), optName.begin(), ::tolower);
+  if (options.find(optName) != options.end())
+    return -1;
+  options[optName] = Option(helpString);
+  return 0;
+}
+
+string Configuration::getOptionDefault(string optName) const
+{
+  std::transform(optName.begin(), optName.end(), optName.begin(), ::tolower);
+  if (options.find(optName) == options.end()) 
+    return "";
+  return options.find(optName)->second.defaultValue;
+}
+
+vector<string> Configuration::getOptions() const 
+{
+  vector<string> ret;
+  foreachpair(const string& key, _, options) {
+    ret.push_back(key);
+  }
+  return ret;
+}
+
 
-Params& Configuration::getParams() 
+Params& Configuration::getParams()
 {
   return params;
 }

Modified: incubator/mesos/trunk/src/configuration.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configuration.hpp?rev=1131855&r1=1131854&r2=1131855&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configuration.hpp (original)
+++ incubator/mesos/trunk/src/configuration.hpp Sun Jun  5 05:41:11 2011
@@ -5,8 +5,10 @@
 #include <fstream>
 #include <string>
 #include <map>
+#include <boost/any.hpp>
 #include <glog/logging.h>
 #include "params.hpp"
+#include "foreach.hpp"
 
 
 namespace nexus { namespace internal {
@@ -29,6 +31,18 @@ struct ConfigurationException : std::exc
   const char* what() const throw () { return message; }
 };
 
+/**
+ * Registered option with help string and defautl value
+ **/
+struct Option {
+  Option(string _helpString, string _defaultValue="") : 
+    helpString(_helpString), defaultValue(_defaultValue) {} 
+
+  Option() {}
+
+  string helpString;
+  string defaultValue;
+};
 
 /** 
  * This class populates a Params object, which can be retrieved with
@@ -51,6 +65,7 @@ public:
 
 private:
   Params params;
+  map<string, Option> options;
 
 public:
   /** 
@@ -85,6 +100,63 @@ public:
    **/
   Params& getParams();
 
+  /**
+   * Returns a usage string with all registered options
+   * @see addOption()
+   * @return usage string
+   **/
+  string getUsage() const;
+  
+  /**
+   * Adds a registered option together with a default value and a help string.
+   * @param optName name of the option, e.g. "home"
+   * @param helpString description of the option, may contain line breaks
+   * @param defaultValue default value of the option. 
+   *        The default option is put in the internal params, 
+   *        unless the option already has a value in params.
+   *        Its type must support operator<<(ostream,...)
+   * @return 0 on success, -1 if option already exists
+   **/
+  template <class T>
+  int addOption(string optName, const string& helpString, 
+             const T& defaultValue) 
+  {
+    std::transform(optName.begin(), optName.end(), optName.begin(), ::tolower);
+    if (options.find(optName) != options.end())
+      return -1;
+    ostringstream os;
+    os << defaultValue;
+    options[optName] = Option(helpString, os.str());
+
+    if (!params.contains(optName))  // insert default value
+      params[optName] = os.str();
+
+    return 0;
+  }
+
+  /**
+   * Adds a registered option together with a help string
+   * It's recommended to use the other version of this method, 
+   * which takes a default value.
+   * @param optName name of the option, e.g. "home"
+   * @param helpString description of the option, may contain line breaks
+   * @return 0 on success, -1 if option already exists
+   **/
+  int addOption(string optName, const string& helpString);
+
+  /**
+   * Returns the default string value associated with an option.
+   * @param optName name of the option, e.g. "home"
+   * @return default value associated with optName
+   **/
+  string getOptionDefault(string optName) const;
+
+  /**
+   * Returns the name of all options.
+   * @return name of every registered option
+   **/
+  vector<string> getOptions() const;
+
 private:
   /**
    * Parses the environment variables and populates a Params.
@@ -123,6 +195,7 @@ private:
    * Load the config file set through the command line or environment, if any.
    */
   void loadConfigFileIfGiven();
+
 };
 
 } }   // end nexus :: internal namespace

Modified: incubator/mesos/trunk/src/tests/test_configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/test_configuration.cpp?rev=1131855&r1=1131854&r2=1131855&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/test_configuration.cpp (original)
+++ incubator/mesos/trunk/src/tests/test_configuration.cpp Sun Jun  5 05:41:11 2011
@@ -29,6 +29,26 @@ TEST(ConfigurationTest, Environment)
 }
 
 
+TEST(ConfigurationTest, DefaultOptions)
+{
+  const int ARGC = 3;
+  char* argv[ARGC];
+  argv[0] = (char*) "./filename";
+  argv[1] = (char*) "--test1=text1";
+  argv[2] = (char*) "--test2";
+
+  Configuration conf(ARGC, argv, false);
+  conf.addOption("test1", "Testing option", 500);
+  conf.addOption("test2", "Another tester", 0);
+  conf.addOption("test3", "Tests the default\noption.", 2010);
+  conf.addOption("test4", "Option without default\noption.");
+
+  EXPECT_EQ("text1",  conf.getParams()["test1"]);
+  EXPECT_EQ("1",      conf.getParams()["test2"]);
+  EXPECT_EQ("2010",   conf.getParams()["test3"]);
+  EXPECT_EQ("",       conf.getParams()["test4"]);
+}
+
 TEST(ConfigurationTest, CommandLine)
 {
   const int ARGC = 10;