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:44:00 UTC

svn commit: r1131879 - in /incubator/mesos/trunk/src: configuration.cpp configuration.hpp master_main.cpp option.hpp tests/test_configuration.cpp

Author: benh
Date: Sun Jun  5 05:43:59 2011
New Revision: 1131879

URL: http://svn.apache.org/viewvc?rev=1131879&view=rev
Log:
Added support for short version of options a la '-p 80' and some tests.

Added:
    incubator/mesos/trunk/src/option.hpp
Modified:
    incubator/mesos/trunk/src/configuration.cpp
    incubator/mesos/trunk/src/configuration.hpp
    incubator/mesos/trunk/src/master_main.cpp
    incubator/mesos/trunk/src/tests/test_configuration.cpp

Modified: incubator/mesos/trunk/src/configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configuration.cpp?rev=1131879&r1=1131878&r2=1131879&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configuration.cpp (original)
+++ incubator/mesos/trunk/src/configuration.cpp Sun Jun  5 05:43:59 2011
@@ -128,21 +128,13 @@ void Configuration::loadCommandLine(int 
         set = true;
       } 
     } else if (args[i].find_first_of("-", 0) == 0) {
-      // handle -blah 25 and -blah
-      if ((i+1 >= args.size()) ||  // last arg || next arg is new arg
-          (i+1 < args.size() && args[i+1].find_first_of("-", 0) == 0 &&
-           args[i+1].find_first_of("0123456789.", 1) != 1)) {
-        key = args[i].substr(1);
-        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
-        val = "1";
-        set = true;
-      } else { // not last arg && next arg is a value
-        key = args[i].substr(1);
-        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
+      // handle -blah 25
+      key = getLongName(args[i][1]);
+      if (key != "" && i+1 < args.size()) {
         val = args[i+1];
         set = true;
         i++;  // we've consumed next parameter as a "value"-parameter
-      }
+      }      
     }
     if (set && (overwrite || !params.contains(key))) {
       params[key] = val;
@@ -182,36 +174,43 @@ void Configuration::loadConfigFile(const
 string Configuration::getUsage() const 
 {
   const int PAD = 10;
-  const int PADEXTRA = string("--=VAL").size(); // adjust for "--" and "=VAL"
-  string usage = "";
+  const int LONG_PAD = string("--=VAL").size(); 
+  const int SHORT_PAD = string(" (or -  VAL)").size(); 
+  string usage;
   
-  // get max key length
+  // get max length of the first column of usage output
   int maxLen = 0;
-  foreachpair (const string& key, _, options) {
-    maxLen = key.size() > maxLen ? key.length() : maxLen;
+  foreachpair (const string& key, const Option& opt, options) {
+    int len = key.length() + LONG_PAD;
+    len += opt.hasShort ? SHORT_PAD : 0;
+    maxLen = len > maxLen ? len : maxLen;
   }
-  maxLen += PADEXTRA; 
 
-  foreachpair (const string& key, const Option& val, options) {
-    string helpStr = val.helpString;
+  foreachpair (const string& key, const Option& opt, options) {
+    string helpStr = opt.helpString;
+    string line;
 
-    if (val.hasDefault) {  // add default value
-      helpStr += " (default: " + val.defaultValue + ")";
+    if (opt.defaultValue != "") {  // add default value
+      helpStr += " (default: " + opt.defaultValue + ")";
     }
 
-    usage += "--" + key + "=VAL";
-    string pad(PAD + maxLen - key.size() - PADEXTRA, ' ');
-    usage += pad;
+    line += "--" + key + "=VAL";
+    line += opt.hasShort ? string(" (or -") + opt.shortName + " VAL)" : "";
+    string pad(PAD + maxLen - line.size(), ' ');
+    line += pad;
     size_t pos1 = 0, pos2 = 0;
     pos2 = helpStr.find_first_of("\n\r", pos1);
-    usage += helpStr.substr(pos1, pos2 - pos1) + "\n";
+    line += helpStr.substr(pos1, pos2 - pos1) + "\n";
+    usage += line;
 
     while(pos2 != string::npos) {  // handle multi line help strings
+      line = "";
       pos1 = pos2 + 1;
       string pad2(PAD + maxLen, ' ');
-      usage += pad2;
+      line += pad2;
       pos2 = helpStr.find_first_of("\n\r", pos1);
-      usage += helpStr.substr(pos1, pos2 - pos1) + "\n";
+      line += helpStr.substr(pos1, pos2 - pos1) + "\n";
+      usage += line;
     }
 
   }
@@ -233,3 +232,12 @@ Params& Configuration::getParams()
 {
   return params;
 }
+
+string Configuration::getLongName(char shortName) const
+{
+  foreachpair (const string& key, const Option& opt, options) {
+    if (opt.hasShort && opt.shortName == shortName)
+      return key;
+  }
+  return "";
+}

Modified: incubator/mesos/trunk/src/configuration.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configuration.hpp?rev=1131879&r1=1131878&r2=1131879&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configuration.hpp (original)
+++ incubator/mesos/trunk/src/configuration.hpp Sun Jun  5 05:43:59 2011
@@ -9,7 +9,7 @@
 #include <glog/logging.h>
 #include "params.hpp"
 #include "foreach.hpp"
-
+#include "option.hpp"
 
 namespace nexus { namespace internal {
     
@@ -22,45 +22,6 @@ using std::map;
 using boost::lexical_cast;
 using boost::bad_lexical_cast;
 
-/**
- * Interface of a validator
- **/
-class ValidatorBase {
-public:
-  virtual bool isValid(const string& val) const = 0;
-  virtual ValidatorBase* clone() const = 0;
-};
-
-/**
- * Validator that checks if a string can be cast to its templated type.
- **/
-template <class T>
-class Validator : public ValidatorBase {
-public:
-  Validator() {}
-
-  /**
-   * Checks if the provided string can be cast to a T.
-   * @param val value associated with some option
-   * @return true if val can be cast to a T, otherwise false.
-   **/
-  virtual bool isValid(const string& val) const
-  {
-    try {
-      lexical_cast<T>(val);
-    }
-    catch(const bad_lexical_cast& ex) {
-      return false;
-    }
-    return true;
-  }
-
-  virtual ValidatorBase* clone() const
-  {
-    return new Validator<T>();
-  }
-
-};
 
 /**
  * Exception type thrown by Configuration.
@@ -72,65 +33,6 @@ struct ConfigurationException : std::exc
   const char* what() const throw () { return message; }
 };
 
-/**
- * Exception type thrown if the the value of an Option 
- * doesn't match the default value type.
- */
-struct BadOptionValueException : std::exception
-{
-  const char* message;
-  BadOptionValueException(const char* msg): message(msg) {}
-  const char* what() const throw () { return message; }
-};
-
-/**
- * Registered option with help string and default value
- **/
-struct Option {
-  Option(string _helpString) : 
-    helpString(_helpString), hasDefault(false), validator(NULL) {} 
-
-  Option(string _helpString,
-         const ValidatorBase& _validator,
-         string _defaultValue)
-    : helpString(_helpString), hasDefault(true), defaultValue(_defaultValue) 
-  {
-    validator = _validator.clone();
-  }
-
-  Option(string _helpString, const ValidatorBase& _validator)
-    : helpString(_helpString), hasDefault(false)
-  {
-    validator = _validator.clone();
-  }
-
-  Option() : hasDefault(false), validator(NULL) {}
-
-  Option(const Option& opt)
-    : helpString(opt.helpString), hasDefault(opt.hasDefault),
-      defaultValue(opt.defaultValue)
-  {
-    validator = opt.validator == NULL ? NULL : opt.validator->clone();
-  }
-
-  Option &operator=(const Option& opt)
-  {
-    helpString = opt.helpString;
-    defaultValue = opt.defaultValue;
-    validator = opt.validator == NULL ? NULL : opt.validator->clone();
-    return *this;
-  }
-
-  ~Option() 
-  { 
-    if (validator != 0) delete validator; 
-  }
-
-  string helpString;
-  bool hasDefault;
-  string defaultValue;
-  ValidatorBase *validator;
-};
 
 /** 
  * This class populates a Params object, which can be retrieved with
@@ -186,43 +88,47 @@ public:
    *        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
+   * @param shortName character representing short name of option, e.g. 'I'
+   * @return 0 on success, -1 if option already exists,
+   *         -2 if defaultValue cannot be converted to templated type T
    **/
   template <class T>
   int addOption(string optName, const string& helpString, 
-             const T& defaultValue) 
+                const string& defaultValue, char shortName = '\0') 
   {
     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, Validator<T>(), os.str());
+    try { 
+      lexical_cast<T>(defaultValue);
+    } catch(const bad_lexical_cast& ex) { return -2; }
+    
+    options[optName] = Option(helpString, Validator<T>(), 
+                              defaultValue, shortName);
 
     if (!params.contains(optName))  // insert default value
-      params[optName] = os.str();
+      params[optName] = defaultValue;
 
     return 0;
   }
 
   
   /**
-   * Adds a registered option together with a help string.
+   * 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,...)
+   * @param shortName character representing short name of option, e.g. 'I'
    * @return 0 on success, -1 if option already exists
    **/
   template <class T>
-  int addOption(string optName, const string& helpString) 
+  int addOption(string optName, const string& helpString, 
+                char shortName = '\0') 
   {
     std::transform(optName.begin(), optName.end(), optName.begin(), ::tolower);
     if (options.find(optName) != options.end())
       return -1;
-    options[optName] = Option(helpString, Validator<T>());
+    options[optName] = Option(helpString, Validator<T>(), shortName);
+
     return 0;
   }
 
@@ -344,6 +250,12 @@ private:
    */
   void loadConfigFileIfGiven(bool overwrite=false);
 
+  /**
+   * Gets the first long name option associated with the provided short name.
+   * @return first long name option matching the short name, "" if none found.
+   */
+  string getLongName(char shortName) const;
+
 };
 
 } }   // end nexus :: internal namespace

Modified: incubator/mesos/trunk/src/master_main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master_main.cpp?rev=1131879&r1=1131878&r2=1131879&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master_main.cpp (original)
+++ incubator/mesos/trunk/src/master_main.cpp Sun Jun  5 05:43:59 2011
@@ -32,8 +32,8 @@ int main(int argc, char **argv)
 {
   Configuration conf;
   conf.addOption<string>("url", "URL used for contending to a master.");
-  conf.addOption<int>("port", "Port to listen on");
-  conf.addOption<bool>("quiet", "Do not log to stderr", false);
+  conf.addOption<int>("port", "Port to listen on", 'p');
+  conf.addOption<bool>("quiet", "Do not log to stderr", "0", 'q');
   conf.addOption<string>("log_dir", "Where to place logs", "/tmp");
   Master::registerOptions(&conf);
 

Added: incubator/mesos/trunk/src/option.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/option.hpp?rev=1131879&view=auto
==============================================================================
--- incubator/mesos/trunk/src/option.hpp (added)
+++ incubator/mesos/trunk/src/option.hpp Sun Jun  5 05:43:59 2011
@@ -0,0 +1,143 @@
+#ifndef __OPTION_HPP__
+#define __OPTION_HPP__
+
+#include <algorithm>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <map>
+#include <glog/logging.h>
+#include "params.hpp"
+#include "foreach.hpp"
+
+namespace nexus { namespace internal {
+    
+using std::string;
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::ifstream;
+using std::map;
+using boost::lexical_cast;
+using boost::bad_lexical_cast;
+
+
+/**
+ * Interface of a validator
+ **/
+class ValidatorBase {
+public:
+  virtual bool isValid(const string& val) const = 0;
+  virtual ValidatorBase* clone() const = 0;
+};
+
+/**
+ * Validator that checks if a string can be cast to its templated type.
+ **/
+template <class T>
+class Validator : public ValidatorBase {
+public:
+  Validator() {}
+
+  /**
+   * Checks if the provided string can be cast to a T.
+   * @param val value associated with some option
+   * @return true if val can be cast to a T, otherwise false.
+   **/
+  virtual bool isValid(const string& val) const
+  {
+    try {
+      lexical_cast<T>(val);
+    }
+    catch(const bad_lexical_cast& ex) {
+      return false;
+    }
+    return true;
+  }
+
+  virtual ValidatorBase* clone() const
+  {
+    return new Validator<T>();
+  }
+
+};
+
+/**
+ * Exception type thrown if the the value of an Option 
+ * doesn't match the default value type.
+ */
+struct BadOptionValueException : std::exception
+{
+  const char* message;
+  BadOptionValueException(const char* msg): message(msg) {}
+  const char* what() const throw () { return message; }
+};
+
+/**
+ * Registered option with help string and default value
+ **/
+struct Option {
+
+  Option() : hasDefault(false), validator(NULL) {}
+
+  Option(const string& _helpString,
+         const ValidatorBase& _validator,
+         const string& _defaultValue = "",
+         char _shortName = '\0')
+    : helpString(_helpString), 
+      defaultValue(_defaultValue),
+      shortName(_shortName)
+  {
+    hasDefault = _defaultValue == "" ? false : true;
+    hasShort = _shortName == '\0' ? false : true;
+    validator = _validator.clone();
+  }
+  
+  Option(const string& _helpString,
+         const ValidatorBase& _validator,
+         char _shortName)
+    : helpString(_helpString), 
+      hasDefault(false),
+      shortName(_shortName)
+  {
+    hasShort = _shortName == '\0' ? false : true;
+    validator = _validator.clone();
+  }
+  
+  Option(const Option& opt)
+    : helpString(opt.helpString), 
+      hasDefault(opt.hasDefault),
+      hasShort(opt.hasShort),
+      shortName(opt.shortName),
+      defaultValue(opt.defaultValue)
+  {
+    validator = opt.validator == NULL ? NULL : opt.validator->clone();
+  }
+
+  Option &operator=(const Option& opt)
+  {
+    helpString = opt.helpString;
+    hasDefault = opt.hasDefault;
+    hasShort = opt.hasShort;
+    shortName = opt.shortName;
+    defaultValue = opt.defaultValue;
+    validator = opt.validator == NULL ? NULL : opt.validator->clone();
+    return *this;
+  }
+
+  ~Option() 
+  { 
+    if (validator != 0) delete validator; 
+  }
+
+  string helpString;
+  bool hasDefault;
+  string defaultValue;
+  bool hasShort;
+  char shortName;
+  ValidatorBase *validator;
+};
+
+} }   // end nexus :: internal namespace
+
+#endif

Modified: incubator/mesos/trunk/src/tests/test_configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/test_configuration.cpp?rev=1131879&r1=1131878&r2=1131879&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/test_configuration.cpp (original)
+++ incubator/mesos/trunk/src/tests/test_configuration.cpp Sun Jun  5 05:43:59 2011
@@ -41,16 +41,20 @@ TEST(ConfigurationTest, DefaultOptions)
 
   Configuration conf;
 
+  int ret = 0;
   EXPECT_NO_THROW( {
-      conf.addOption<int>("test1", "Testing option", 500);
-      conf.addOption<short>("test2", "Another tester", 0);
-      conf.addOption<long>("test3", "Tests the default\noption.", 2010);
-      conf.addOption<string>("test4", "Option without default\noption.");
-      conf.addOption<string>("test5", "Option with a default string.", "arb");
+      ret += conf.addOption<int>("test1", "Testing option", "500");
+      ret += conf.addOption<short>("test2", "Another tester", "0");
+      ret += conf.addOption<long>("test3", "Tests the default", "2010");
+      ret += conf.addOption<string>("test4", "Option without default");
+      ret += conf.addOption<string>("test5", "Option with a default", "arb");
       conf.load(ARGC, argv, false);
     } );
-  
-  conf.addOption<int>("excp", "Exception tester.", 50);
+
+  int addOptionError = ret;
+  EXPECT_EQ(addOptionError, 0);
+
+  conf.addOption<int>("excp", "Exception tester.", "50");
   EXPECT_THROW(conf.validate(), BadOptionValueException);
   conf.getParams()["excp"] = "27";
   EXPECT_NO_THROW(conf.validate());
@@ -66,26 +70,27 @@ TEST(ConfigurationTest, DefaultOptions)
 
 TEST(ConfigurationTest, CommandLine)
 {
-  const int ARGC = 10;
+  const int ARGC = 8;
   char* argv[ARGC];
   argv[0] = (char*) "./filename";
   argv[1] = (char*) "--test1=text1";
   argv[2] = (char*) "--test2";
-  argv[3] = (char*) "-test3";
-  argv[4] = (char*) "text2";
-  argv[5] = (char*) "-test4";
-  argv[6] = (char*) "-negative";
-  argv[7] = (char*) "-25";
-  argv[8] = (char*) "--cAsE=4";
-  argv[9] = (char*) "--space=Long String";
+  argv[3] = (char*) "text2";
+  argv[4] = (char*) "-N";
+  argv[5] = (char*) "-25";
+  argv[6] = (char*) "--cAsE=4";
+  argv[7] = (char*) "--space=Long String";
 
   Configuration conf;
+  int addOptionError = 0;
+  addOptionError += conf.addOption<int>("negative", "some val", "-30", 'N');
+  addOptionError += conf.addOption<string>("test1", "textual value", "text2");
+
+  EXPECT_EQ(addOptionError, 0);
   EXPECT_NO_THROW( conf.load(ARGC, argv, false) );
 
   EXPECT_EQ("text1",       conf.getParams()["test1"]);
   EXPECT_EQ("1",           conf.getParams()["test2"]);
-  EXPECT_EQ("text2",       conf.getParams()["test3"]);
-  EXPECT_EQ("1",           conf.getParams()["test4"]);
   EXPECT_EQ("-25",         conf.getParams()["negative"]);
   EXPECT_EQ("4",           conf.getParams()["case"]);
   EXPECT_EQ("Long String", conf.getParams()["space"]);