[mlpack-svn] r10788 - mlpack/trunk/src/mlpack/core/util
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Wed Dec 14 12:37:53 EST 2011
Author: mamidon
Date: 2011-12-14 12:37:52 -0500 (Wed, 14 Dec 2011)
New Revision: 10788
Modified:
mlpack/trunk/src/mlpack/core/util/cli.cpp
mlpack/trunk/src/mlpack/core/util/cli.hpp
mlpack/trunk/src/mlpack/core/util/cli_impl.hpp
Log:
Did some refactoring on CLI, fixed a potential bug.
Also removed some references to PARAM_MODULE.
Modified: mlpack/trunk/src/mlpack/core/util/cli.cpp
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli.cpp 2011-12-14 17:23:59 UTC (rev 10787)
+++ mlpack/trunk/src/mlpack/core/util/cli.cpp 2011-12-14 17:37:52 UTC (rev 10788)
@@ -119,20 +119,18 @@
std::string tmp = TYPENAME(bool);
std::string path = identifier;
std::string stringAlias = alias;
- std::string prog_opt_id = path; // Use boost's syntax for aliasing.
+ // Must make use of boost option name syntax.
+ std::string prog_opt_id = stringAlias.length() ? path + "," + alias : path;
// Deal with a required alias.
- if (stringAlias.length()) {
- amap_t& amap = GetSingleton().aliasValues;
- amap[stringAlias] = path;
- prog_opt_id = path + "," + alias;
- }
+ AddAlias(stringAlias, path);
// Add the option to boost::program_options.
desc.add_options()(prog_opt_id.c_str(), description);
// Make sure the description, etc. ends up in gmap.
gmap_t& gmap = GetSingleton().globalValues;
+
ParamData data;
data.desc = description;
data.tname = "";
@@ -150,42 +148,113 @@
}
/*
+ * Adds an alias mapping for a given parameter.
+ *
+ * @param alias The alias we will use for the parameter.
+ * @param original The name of the actual parameter we will be mapping to.
+ */
+void CLI::AddAlias(std::string alias, std::string original) {
+ //Conduct the mapping
+ if (alias.length()) {
+ amap_t& amap = GetSingleton().aliasValues;
+ amap[alias] = original;
+ }
+}
+
+/*
* @brief Adds a flag parameter to CLI.
*/
void CLI::AddFlag(const char* identifier,
const char* description,
const char* alias)
{
- po::options_description& desc = CLI::GetSingleton().desc;
+ // Reuse functionality from add
+ Add(identifier, description, alias, false);
- std::string path = identifier;
- std::string stringAlias = alias;
- std::string prog_opt_id = path;
-
- //Deal with a required alias
- if (stringAlias.length()) {
- amap_t& amap = GetSingleton().aliasValues;
- amap[stringAlias] = path;
- prog_opt_id = path + "," + alias;
- }
-
- // Add the option to boost::program_options.
- desc.add_options()
- (prog_opt_id.c_str(), po::value<bool>()->implicit_value(true), description);
-
- // Add the proper metadata in gmap.
+ // Insert the proper metadata in gmap.
gmap_t& gmap = GetSingleton().globalValues;
+
ParamData data;
data.desc = description;
data.tname = TYPENAME(bool);
- data.name = path;
+ data.name = std::string(identifier);
data.isFlag = true;
data.wasPassed = false;
- gmap[path] = data;
+ gmap[data.name] = data;
}
+std::string CLI::AliasReverseLookup(std::string value)
+{
+ amap_t& amap = GetSingleton().aliasValues;
+ amap_t::iterator iter;
+ for (iter = amap.begin(); iter != amap.end(); iter++)
+ if (iter->second == value) // Found our match.
+ return iter->first;
+
+ return ""; // Nothing found.
+}
+
/**
+ * Parses the parameters for 'help' and 'info'
+ * If found, will print out the appropriate information
+ * and kill the program.
+ */
+void CLI::DefaultMessages()
+{
+ // Default help message
+ if (HasParam("help"))
+ {
+ Log::Info.ignoreInput = false;
+ PrintHelp();
+ exit(0); // The user doesn't want to run the program, he wants help.
+ }
+
+ if (HasParam("info"))
+ {
+ Log::Info.ignoreInput = false;
+ std::string str = GetParam<std::string>("info");
+
+ // The info node should always be there, but the user may not have specified
+ // anything.
+ if (str != "")
+ {
+ PrintHelp(str);
+ exit(0);
+ }
+
+ // Otherwise just print the generalized help.
+ PrintHelp();
+ exit(0);
+ }
+
+ if (GetParam<bool>("verbose"))
+ {
+ // Give [INFO ] output.
+ Log::Info.ignoreInput = false;
+ }
+
+ // Notify the user if we are debugging. This is not done in the constructor
+ // because the output streams may not be set up yet. We also don't want this
+ // message twice if the user just asked for help or information.
+ Log::Debug << "Compiled with debugging symbols." << std::endl;
+}
+
+/**
+ * Destroy the CLI object. This resets the pointer to the singleton, so in case
+ * someone tries to access it after destruction, a new one will be made (the
+ * program will not fail).
+ */
+void CLI::Destroy()
+{
+ if (singleton != NULL)
+ {
+ delete singleton;
+ singleton = NULL; // Reset pointer.
+ }
+}
+
+/**
* See if the specified flag was found while parsing.
*
* @param identifier The name of the parameter in question.
@@ -214,6 +283,54 @@
}
/**
+ * Hyphenate a string or split it onto multiple 80-character lines, with some
+ * amount of padding on each line. This is used for option output.
+ *
+ * @param str String to hyphenate (splits are on ' ').
+ * @param padding Amount of padding on the left for each new line.
+ */
+std::string CLI::HyphenateString(std::string str, int padding)
+{
+ size_t margin = 80 - padding;
+ if (str.length() < margin)
+ return str;
+ std::string out("");
+ unsigned int pos = 0;
+ // First try to look as far as possible.
+ while (pos < str.length() - 1)
+ {
+ size_t splitpos;
+ // Check that we don't have a newline first.
+ splitpos = str.find('\n', pos);
+ if (splitpos == std::string::npos || splitpos > (pos + margin))
+ {
+ // We did not find a newline.
+ if (str.length() - pos < margin)
+ {
+ splitpos = str.length(); // The rest fits on one line.
+ }
+ else
+ {
+ splitpos = str.rfind(' ', margin + pos); // Find nearest space.
+ if (splitpos <= pos || splitpos == std::string::npos) // Not found.
+ splitpos = pos + margin;
+ }
+ }
+ out += str.substr(pos, (splitpos - pos));
+ if (splitpos < str.length())
+ {
+ out += '\n';
+ out += std::string(padding, ' ');
+ }
+
+ pos = splitpos;
+ if (str[pos] == ' ' || str[pos] == '\n')
+ pos++;
+ }
+ return out;
+}
+
+/**
* Grab the description of the specified node.
*
* @param identifier Name of the node in question.
@@ -306,124 +423,6 @@
Timer::Start("total_time");
}
-/**
- * Parses the values given on the command line, overriding any default values.
- */
-void CLI::UpdateGmap()
-{
- gmap_t& gmap = GetSingleton().globalValues;
- po::variables_map& vmap = GetSingleton().vmap;
-
- // Iterate through vmap, and overwrite default values with anything found on
- // command line.
- po::variables_map::iterator i;
- for (i = vmap.begin(); i != vmap.end(); i++)
- {
- ParamData param;
- if (gmap.count(i->first)) // We need to preserve certain data
- param = gmap[i->first];
-
- param.value = vmap[i->first].value();
- param.wasPassed = true;
- gmap[i->first] = param;
- }
-}
-
-/**
- * Registers a ProgramDoc object, which contains documentation about the
- * program.
- *
- * @param doc Pointer to the ProgramDoc object.
- */
-void CLI::RegisterProgramDoc(ProgramDoc* doc)
-{
- // Only register the doc if it is not the dummy object we created at the
- // beginning of the file (as a default value in case this is never called).
- if (doc != &empty_program_doc)
- GetSingleton().doc = doc;
-}
-
-/**
- * Destroy the CLI object. This resets the pointer to the singleton, so in case
- * someone tries to access it after destruction, a new one will be made (the
- * program will not fail).
- */
-void CLI::Destroy()
-{
- if (singleton != NULL)
- {
- delete singleton;
- singleton = NULL; // Reset pointer.
- }
-}
-
-/**
- * Parses the parameters for 'help' and 'info'
- * If found, will print out the appropriate information
- * and kill the program.
- */
-void CLI::DefaultMessages()
-{
- // Default help message
- if (GetParam<bool>("help"))
- {
- Log::Info.ignoreInput = false;
- PrintHelp();
- exit(0); // The user doesn't want to run the program, he wants help.
- }
-
- if (HasParam("info"))
- {
- Log::Info.ignoreInput = false;
- std::string str = GetParam<std::string>("info");
-
- // The info node should always be there, but the user may not have specified
- // anything.
- if (str != "")
- {
- PrintHelp(str);
- exit(0);
- }
-
- // Otherwise just print the generalized help.
- PrintHelp();
- exit(0);
- }
-
- if (GetParam<bool>("verbose"))
- {
- // Give [INFO ] output.
- Log::Info.ignoreInput = false;
- }
-
- // Notify the user if we are debugging. This is not done in the constructor
- // because the output streams may not be set up yet. We also don't want this
- // message twice if the user just asked for help or information.
- Log::Debug << "Compiled with debugging symbols." << std::endl;
-}
-
-/**
- * Checks that all parameters specified as required have been specified on the
- * command line. If they havent, prints an error message and kills the program.
- */
-void CLI::RequiredOptions()
-{
- po::variables_map& vmap = GetSingleton().vmap;
- std::list<std::string> rOpt = GetSingleton().requiredOptions;
-
- // Now, warn the user if they missed any required options.
- std::list<std::string>::iterator iter;
- for (iter = rOpt.begin(); iter != rOpt.end(); iter++)
- {
- std::string str = *iter;
- if (!vmap.count(str))
- { // If a required option isn't there...
- Log::Fatal << "Required option --" << str.c_str() << " is undefined."
- << std::endl;
- }
- }
-}
-
/* Prints out the current hierarchy. */
void CLI::Print()
{
@@ -479,7 +478,6 @@
Log::Info << std::endl;
}
-
/* Prints the descriptions of the current hierarchy. */
void CLI::PrintHelp(std::string param)
{
@@ -618,62 +616,62 @@
}
/**
- * Hyphenate a string or split it onto multiple 80-character lines, with some
- * amount of padding on each line. This is used for option output.
- *
- * @param str String to hyphenate (splits are on ' ').
- * @param padding Amount of padding on the left for each new line.
- */
-std::string CLI::HyphenateString(std::string str, int padding)
+ * Registers a ProgramDoc object, which contains documentation about the
+ * program.
+ *
+ * @param doc Pointer to the ProgramDoc object.
+ */
+void CLI::RegisterProgramDoc(ProgramDoc* doc)
{
- size_t margin = 80 - padding;
- if (str.length() < margin)
- return str;
- std::string out("");
- unsigned int pos = 0;
- // First try to look as far as possible.
- while (pos < str.length() - 1)
+ // Only register the doc if it is not the dummy object we created at the
+ // beginning of the file (as a default value in case this is never called).
+ if (doc != &empty_program_doc)
+ GetSingleton().doc = doc;
+}
+
+/**
+ * Checks that all parameters specified as required have been specified on the
+ * command line. If they havent, prints an error message and kills the program.
+ */
+void CLI::RequiredOptions()
+{
+ po::variables_map& vmap = GetSingleton().vmap;
+ std::list<std::string> rOpt = GetSingleton().requiredOptions;
+
+ // Now, warn the user if they missed any required options.
+ std::list<std::string>::iterator iter;
+ for (iter = rOpt.begin(); iter != rOpt.end(); iter++)
{
- size_t splitpos;
- // Check that we don't have a newline first.
- splitpos = str.find('\n', pos);
- if (splitpos == std::string::npos || splitpos > (pos + margin))
- {
- // We did not find a newline.
- if (str.length() - pos < margin)
- {
- splitpos = str.length(); // The rest fits on one line.
- }
- else
- {
- splitpos = str.rfind(' ', margin + pos); // Find nearest space.
- if (splitpos <= pos || splitpos == std::string::npos) // Not found.
- splitpos = pos + margin;
- }
+ std::string str = *iter;
+ if (!vmap.count(str))
+ { // If a required option isn't there...
+ Log::Fatal << "Required option --" << str.c_str() << " is undefined."
+ << std::endl;
}
- out += str.substr(pos, (splitpos - pos));
- if (splitpos < str.length())
- {
- out += '\n';
- out += std::string(padding, ' ');
- }
-
- pos = splitpos;
- if (str[pos] == ' ' || str[pos] == '\n')
- pos++;
}
- return out;
}
-std::string CLI::AliasReverseLookup(std::string value)
+/**
+ * Parses the values given on the command line, overriding any default values.
+ */
+void CLI::UpdateGmap()
{
- amap_t& amap = GetSingleton().aliasValues;
- amap_t::iterator iter;
- for (iter = amap.begin(); iter != amap.end(); iter++)
- if (iter->second == value) // Found our match.
- return iter->first;
+ gmap_t& gmap = GetSingleton().globalValues;
+ po::variables_map& vmap = GetSingleton().vmap;
- return ""; // Nothing found.
+ // Iterate through vmap, and overwrite default values with anything found on
+ // command line.
+ po::variables_map::iterator i;
+ for (i = vmap.begin(); i != vmap.end(); i++)
+ {
+ ParamData param;
+ if (gmap.count(i->first)) // We need to preserve certain data
+ param = gmap[i->first];
+
+ param.value = vmap[i->first].value();
+ param.wasPassed = true;
+ gmap[i->first] = param;
+ }
}
// Add help parameter.
Modified: mlpack/trunk/src/mlpack/core/util/cli.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli.hpp 2011-12-14 17:23:59 UTC (rev 10787)
+++ mlpack/trunk/src/mlpack/core/util/cli.hpp 2011-12-14 17:37:52 UTC (rev 10788)
@@ -331,15 +331,6 @@
JOIN(__io_option_flag_object_, __COUNTER__) (ID, DESC, ALIAS);
/** @endcond */
- /**
- * Define a module.
- *
- * @param ID Name of the module.
- * @param DESC Description of the module (1-2 sentences).
- */
- #define PARAM_MODULE(ID, DESC) static mlpack::io::Option<int> \
- JOIN(io_option_module_dummy_object_, __COUNTER__) (true, 0, ID, DESC, \
- NULL);
#else
// We have to do some really bizarre stuff since __COUNTER__ isn't defined. I
// don't think we can absolutely guarantee success, but it should be "good
@@ -354,16 +345,6 @@
JOIN(__io_option_flag_object_, __LINE__) (ID, DESC, ALIAS);
/** @endcond */
- /**
- * Define a module.
- *
- * @param ID Name of the module.
- * @param DESC Description of the module (1-2 sentences).
- */
- #define PARAM_MODULE(ID, DESC) static mlpack::io::Option<int> \
- JOIN(JOIN(io_option_dummy_object_, __LINE__), mod) (true, 0, ID, DESC, \
- NULL);
-
#endif
/**
@@ -384,7 +365,7 @@
}; // namespace io
/**
- * Aids in the extensibility of OptionsHierarchy by focusing the potential
+ * Aids in the extensibility of CLI by focusing potential
* changes into one structure.
*/
struct ParamData
@@ -440,9 +421,6 @@
* optimizer (mlpack::optimizers::L_BFGS):
*
* @code
- * PARAM_MODULE("lbfgs", "Options for the L-BFGS optimizer, which uses a "
- * "back-tracing line search to determine the step size to take.");
- *
* PARAM_DOUBLE("armijo_constant", "Controls the accuracy of the line search "
* "routine for determining the Armijo condition.", "lbfgs", 1e-4);
* PARAM_DOUBLE("min_step", "The minimum step of the line search.", "lbfgs",
@@ -570,22 +548,21 @@
static void AddFlag(const char* identifier,
const char* description,
const char* alias = "");
-
+
/**
- * See if the specified flag was found while parsing.
- *
- * @param identifier The name of the parameter in question.
- */
- static bool HasParam(const char* identifier);
-
-
- /**
* Parses the parameters for 'help' and 'info'.
* If found, will print out the appropriate information and kill the program.
*/
static void DefaultMessages();
/**
+ * Destroy the CLI object. This resets the pointer to the singleton, so in
+ * case someone tries to access it after destruction, a new one will be made
+ * (the program will not fail).
+ */
+ static void Destroy();
+
+ /**
* Grab the value of type T found while parsing. You can set the value using
* this reference safely.
*
@@ -603,16 +580,36 @@
static std::string GetDescription(const char* identifier);
/**
- * Searches for unqualified paramters; when one is found, the default module
- * is prepended onto it (if necessary).
+ * Retrieve the singleton.
*
- * @param argc The number of parameters.
- * @param argv 2D array of the parameter strings.
- * @return Valid modified strings.
+ * Not exposed to the outside, so as to spare users some ungainly
+ * x.GetSingleton().foo() syntax.
+ *
+ * In this case, the singleton is used to store data for the static methods,
+ * as there is no point in defining static methods only to have users call
+ * private instance methods
+ *
+ * @return The singleton instance for use in the static methods.
*/
- static std::vector<std::string> InsertDefaultModule(int argc, char** argv);
+ static CLI& GetSingleton();
+
+ /**
+ * See if the specified flag was found while parsing.
+ *
+ * @param identifier The name of the parameter in question.
+ */
+ static bool HasParam(const char* identifier);
/**
+ * Hyphenate a string or split it onto multiple 80-character lines, with some
+ * amount of padding on each line. This is ued for option output.
+ *
+ * @param str String to hyphenate (splits are on ' ').
+ * @param padding Amount of padding on the left for each new line.
+ */
+ static std::string HyphenateString(std::string str, int padding);
+
+ /**
* Parses the commandline for arguments.
*
* @param argc The number of arguments on the commandline.
@@ -638,36 +635,6 @@
static void PrintHelp(std::string param="");
/**
- * Checks that all required parameters have been specified on the command
- * line. If any have not been specified, an error message is printed and the
- * program is terminated.
- */
- static void RequiredOptions();
-
- /**
- * Cleans up input pathnames, rendering strings such as /foo/bar
- * and foo/bar/ equivalent inputs.
- *
- * @param str Input string.
- * @return Sanitized string.
- */
- static std::string SanitizeString(const char* str);
-
- /**
- * Hyphenate a string or split it onto multiple 80-character lines, with some
- * amount of padding on each line. This is ued for option output.
- *
- * @param str String to hyphenate (splits are on ' ').
- * @param padding Amount of padding on the left for each new line.
- */
- static std::string HyphenateString(std::string str, int padding);
-
- /**
- * Parses the values given on the command line, overriding any default values.
- */
- static void UpdateGmap();
-
- /**
* Registers a ProgramDoc object, which contains documentation about the
* program. If this method has been called before (that is, if two
* ProgramDocs are instantiated in the program), a fatal error will occur.
@@ -677,13 +644,6 @@
static void RegisterProgramDoc(io::ProgramDoc* doc);
/**
- * Destroy the CLI object. This resets the pointer to the singleton, so in
- * case someone tries to access it after destruction, a new one will be made
- * (the program will not fail).
- */
- static void Destroy();
-
- /**
* Destructor.
*/
~CLI();
@@ -724,6 +684,14 @@
private:
+ /*
+ * Maps a given alias to a given parameter.
+ *
+ * @param alias The name of the alias to be mapped.
+ * @param original The name of the parameter to be mapped.
+ */
+ static void AddAlias(std::string alias, std::string original);
+
/**
* Returns an alias, if given the name of the original.
*
@@ -732,21 +700,7 @@
* @return The alias associated with value.
*/
static std::string AliasReverseLookup(std::string value);
-
- /**
- * Retrieve the singleton.
- *
- * Not exposed to the outside, so as to spare users some ungainly
- * x.GetSingleton().foo() syntax.
- *
- * In this case, the singleton is used to store data for the static methods,
- * as there is no point in defining static methods only to have users call
- * private instance methods
- *
- * @return The singleton instance for use in the static methods.
- */
- static CLI& GetSingleton();
-
+
#ifdef _WIN32
/**
* Converts a FILETIME structure to an equivalent timeval structure.
@@ -757,6 +711,27 @@
#endif
/**
+ * Checks that all required parameters have been specified on the command
+ * line. If any have not been specified, an error message is printed and the
+ * program is terminated.
+ */
+ static void RequiredOptions();
+
+ /**
+ * Cleans up input pathnames, rendering strings such as /foo/bar
+ * and foo/bar/ equivalent inputs.
+ *
+ * @param str Input string.
+ * @return Sanitized string.
+ */
+ static std::string SanitizeString(const char* str);
+
+ /**
+ * Parses the values given on the command line, overriding any default values.
+ */
+ static void UpdateGmap();
+
+ /**
* Make the constructor private, to preclude unauthorized instances.
*/
CLI();
Modified: mlpack/trunk/src/mlpack/core/util/cli_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/util/cli_impl.hpp 2011-12-14 17:23:59 UTC (rev 10787)
+++ mlpack/trunk/src/mlpack/core/util/cli_impl.hpp 2011-12-14 17:37:52 UTC (rev 10788)
@@ -38,14 +38,11 @@
po::options_description& desc = CLI::GetSingleton().desc;
std::string path = identifier;
std::string stringAlias = alias;
- std::string prog_opt_id = path;
+ // Must make use of boost syntax here.
+ std::string prog_opt_id = stringAlias.length() ? path + "," + alias : path;
// Add the alias, if necessary
- if (stringAlias.length()) {
- amap_t& amap = GetSingleton().aliasValues;
- amap[stringAlias] = path;
- prog_opt_id = path + "," + alias;
- }
+ AddAlias(stringAlias, path);
// Add the option to boost program_options.
desc.add_options()
@@ -62,6 +59,7 @@
data.tname = TYPENAME(T);
data.value = boost::any(tmp);
data.wasPassed = false;
+
gmap[path] = data;
// If the option is required, add it to the required options list.
More information about the mlpack-svn
mailing list