MLPACK  1.0.4
cli.hpp
Go to the documentation of this file.
00001 
00024 #ifndef __MLPACK_CORE_UTIL_CLI_HPP
00025 #define __MLPACK_CORE_UTIL_CLI_HPP
00026 
00027 #include <list>
00028 #include <iostream>
00029 #include <map>
00030 #include <string>
00031 
00032 #include <boost/any.hpp>
00033 #include <boost/program_options.hpp>
00034 
00035 #include "timers.hpp"
00036 #include "cli_deleter.hpp" // To make sure we can delete the singleton.
00037 
00053 #define PROGRAM_INFO(NAME, DESC) static mlpack::util::ProgramDoc \
00054     io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, DESC);
00055 
00073 #define PARAM_FLAG(ID, DESC, ALIAS) \
00074     PARAM_FLAG_INTERNAL(ID, DESC, ALIAS);
00075 
00097 #define PARAM_INT(ID, DESC, ALIAS, DEF) \
00098     PARAM(int, ID, DESC, ALIAS, DEF, false)
00099 
00121 #define PARAM_FLOAT(ID, DESC, ALIAS, DEF) \
00122     PARAM(float, ID, DESC, ALIAS, DEF, false)
00123 
00145 #define PARAM_DOUBLE(ID, DESC, ALIAS, DEF) \
00146     PARAM(double, ID, DESC, ALIAS, DEF, false)
00147 
00170 #define PARAM_STRING(ID, DESC, ALIAS, DEF) \
00171     PARAM(std::string, ID, DESC, ALIAS, DEF, false)
00172 
00194 #define PARAM_VECTOR(T, ID, DESC, ALIAS) \
00195     PARAM(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), false)
00196 
00197 // A required flag doesn't make sense and isn't given here.
00198 
00219 #define PARAM_INT_REQ(ID, DESC, ALIAS) PARAM(int, ID, DESC, ALIAS, 0, true)
00220 
00243 #define PARAM_FLOAT_REQ(ID, DESC, ALIAS) PARAM(float, ID, DESC, ALIAS, 0.0f, \
00244     true)
00245 
00266 #define PARAM_DOUBLE_REQ(ID, DESC, ALIAS) PARAM(double, ID, DESC, ALIAS, \
00267     0.0f, true)
00268 
00289 #define PARAM_STRING_REQ(ID, DESC, ALIAS) PARAM(std::string, ID, DESC, \
00290     ALIAS, "", true);
00291 
00312 #define PARAM_VECTOR_REQ(T, ID, DESC, ALIAS) PARAM(std::vector<T>, ID, DESC, \
00313     ALIAS, std::vector<T>(), true);
00314 
00320 // These are ugly, but necessary utility functions we must use to generate a
00321 // unique identifier inside of the PARAM() module.
00322 #define JOIN(x, y) JOIN_AGAIN(x, y)
00323 #define JOIN_AGAIN(x, y) x ## y
00324 
00340 #ifdef __COUNTER__
00341   #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
00342       JOIN(io_option_dummy_object_, __COUNTER__) \
00343       (false, DEF, ID, DESC, ALIAS, REQ);
00344 
00346   #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
00347       mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __COUNTER__) \
00348       (ID, DESC, ALIAS);
00349 
00351 #else
00352   // We have to do some really bizarre stuff since __COUNTER__ isn't defined.  I
00353   // don't think we can absolutely guarantee success, but it should be "good
00354   // enough".  We use the __LINE__ macro and the type of the parameter to try
00355   // and get a good guess at something unique.
00356   #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
00357       JOIN(JOIN(io_option_dummy_object_, __LINE__), opt) (false, DEF, ID, \
00358       DESC, ALIAS, REQ);
00359 
00361   #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
00362       mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __LINE__) \
00363       (ID, DESC, ALIAS);
00364 
00366 #endif
00367 
00371 #define TYPENAME(x) (std::string(typeid(x).name()))
00372 
00373 namespace po = boost::program_options;
00374 
00375 namespace mlpack {
00376 
00377 namespace util {
00378 
00379 // Externally defined in option.hpp, this class holds information about the
00380 // program being run.
00381 class ProgramDoc;
00382 
00383 }; // namespace util
00384 
00389 struct ParamData
00390 {
00392   std::string name;
00394   std::string desc;
00396   std::string tname;
00398   boost::any value;
00400   bool wasPassed;
00402   bool isFlag;
00403 };
00404 
00530 class CLI
00531 {
00532  public:
00544   static void Add(const std::string& path,
00545                   const std::string& description,
00546                   const std::string& alias = "",
00547                   bool required = false);
00548 
00560   template<class T>
00561   static void Add(const std::string& identifier,
00562                   const std::string& description,
00563                   const std::string& alias = "",
00564                   bool required = false);
00565 
00573   static void AddFlag(const std::string& identifier,
00574                       const std::string& description,
00575                       const std::string& alias = "");
00576 
00581   static void DefaultMessages();
00582 
00588   static void Destroy();
00589 
00596   template<typename T>
00597   static T& GetParam(const std::string& identifier);
00598 
00605   static std::string GetDescription(const std::string& identifier);
00606 
00619   static CLI& GetSingleton();
00620 
00626   static bool HasParam(const std::string& identifier);
00627 
00635   static std::string HyphenateString(const std::string& str, int padding);
00636 
00643   static void ParseCommandLine(int argc, char** argv);
00644 
00650   static void RemoveDuplicateFlags(po::basic_parsed_options<char>& bpo);
00651 
00657   static void ParseStream(std::istream& stream);
00658 
00662   static void Print();
00663 
00667   static void PrintHelp(const std::string& param = "");
00668 
00676   static void RegisterProgramDoc(util::ProgramDoc* doc);
00677 
00681   ~CLI();
00682 
00683  private:
00685   po::options_description desc;
00686 
00688   po::variables_map vmap;
00689 
00691   std::list<std::string> requiredOptions;
00692 
00694   typedef std::map<std::string, ParamData> gmap_t;
00695   gmap_t globalValues;
00696 
00698   typedef std::map<std::string, std::string> amap_t;
00699   amap_t aliasValues;
00700 
00702   static CLI* singleton;
00703 
00705   bool didParse;
00706 
00708   Timers timer;
00709 
00711   friend class Timer;
00712 
00713  public:
00715   util::ProgramDoc *doc;
00716 
00717  private:
00724   static void AddAlias(const std::string& alias, const std::string& original);
00725 
00733   static std::string AliasReverseLookup(const std::string& value);
00734 
00735 #ifdef _WIN32
00736 
00741   void FileTimeToTimeVal(timeval* tv);
00742 #endif
00743 
00749   static void RequiredOptions();
00750 
00758   static std::string SanitizeString(const std::string& str);
00759 
00763   static void UpdateGmap();
00764 
00768   CLI();
00769 
00775   CLI(const std::string& optionsName);
00776 
00778   CLI(const CLI& other);
00779 };
00780 
00781 }; // namespace mlpack
00782 
00783 // Include the actual definitions of templated methods
00784 #include "cli_impl.hpp"
00785 
00786 #endif