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"]);