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 #include "version.hpp"
00038 
00054 #define PROGRAM_INFO(NAME, DESC) static mlpack::util::ProgramDoc \
00055     io_programdoc_dummy_object = mlpack::util::ProgramDoc(NAME, DESC);
00056 
00074 #define PARAM_FLAG(ID, DESC, ALIAS) \
00075     PARAM_FLAG_INTERNAL(ID, DESC, ALIAS);
00076 
00098 #define PARAM_INT(ID, DESC, ALIAS, DEF) \
00099     PARAM(int, ID, DESC, ALIAS, DEF, false)
00100 
00122 #define PARAM_FLOAT(ID, DESC, ALIAS, DEF) \
00123     PARAM(float, ID, DESC, ALIAS, DEF, false)
00124 
00146 #define PARAM_DOUBLE(ID, DESC, ALIAS, DEF) \
00147     PARAM(double, ID, DESC, ALIAS, DEF, false)
00148 
00171 #define PARAM_STRING(ID, DESC, ALIAS, DEF) \
00172     PARAM(std::string, ID, DESC, ALIAS, DEF, false)
00173 
00195 #define PARAM_VECTOR(T, ID, DESC, ALIAS) \
00196     PARAM(std::vector<T>, ID, DESC, ALIAS, std::vector<T>(), false)
00197 
00198 // A required flag doesn't make sense and isn't given here.
00199 
00220 #define PARAM_INT_REQ(ID, DESC, ALIAS) PARAM(int, ID, DESC, ALIAS, 0, true)
00221 
00244 #define PARAM_FLOAT_REQ(ID, DESC, ALIAS) PARAM(float, ID, DESC, ALIAS, 0.0f, \
00245     true)
00246 
00267 #define PARAM_DOUBLE_REQ(ID, DESC, ALIAS) PARAM(double, ID, DESC, ALIAS, \
00268     0.0f, true)
00269 
00290 #define PARAM_STRING_REQ(ID, DESC, ALIAS) PARAM(std::string, ID, DESC, \
00291     ALIAS, "", true);
00292 
00313 #define PARAM_VECTOR_REQ(T, ID, DESC, ALIAS) PARAM(std::vector<T>, ID, DESC, \
00314     ALIAS, std::vector<T>(), true);
00315 
00321 // These are ugly, but necessary utility functions we must use to generate a
00322 // unique identifier inside of the PARAM() module.
00323 #define JOIN(x, y) JOIN_AGAIN(x, y)
00324 #define JOIN_AGAIN(x, y) x ## y
00325 
00341 #ifdef __COUNTER__
00342   #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
00343       JOIN(io_option_dummy_object_, __COUNTER__) \
00344       (false, DEF, ID, DESC, ALIAS, REQ);
00345 
00347   #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
00348       mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __COUNTER__) \
00349       (ID, DESC, ALIAS);
00350 
00352 #else
00353   // We have to do some really bizarre stuff since __COUNTER__ isn't defined.  I
00354   // don't think we can absolutely guarantee success, but it should be "good
00355   // enough".  We use the __LINE__ macro and the type of the parameter to try
00356   // and get a good guess at something unique.
00357   #define PARAM(T, ID, DESC, ALIAS, DEF, REQ) static mlpack::util::Option<T> \
00358       JOIN(JOIN(io_option_dummy_object_, __LINE__), opt) (false, DEF, ID, \
00359       DESC, ALIAS, REQ);
00360 
00362   #define PARAM_FLAG_INTERNAL(ID, DESC, ALIAS) static \
00363       mlpack::util::Option<bool> JOIN(__io_option_flag_object_, __LINE__) \
00364       (ID, DESC, ALIAS);
00365 
00367 #endif
00368 
00372 #define TYPENAME(x) (std::string(typeid(x).name()))
00373 
00374 namespace po = boost::program_options;
00375 
00376 namespace mlpack {
00377 
00378 namespace util {
00379 
00380 // Externally defined in option.hpp, this class holds information about the
00381 // program being run.
00382 class ProgramDoc;
00383 
00384 }; // namespace util
00385 
00390 struct ParamData
00391 {
00393   std::string name;
00395   std::string desc;
00397   std::string tname;
00399   boost::any value;
00401   bool wasPassed;
00403   bool isFlag;
00404 };
00405 
00531 class CLI
00532 {
00533  public:
00545   static void Add(const std::string& path,
00546                   const std::string& description,
00547                   const std::string& alias = "",
00548                   bool required = false);
00549 
00561   template<class T>
00562   static void Add(const std::string& identifier,
00563                   const std::string& description,
00564                   const std::string& alias = "",
00565                   bool required = false);
00566 
00574   static void AddFlag(const std::string& identifier,
00575                       const std::string& description,
00576                       const std::string& alias = "");
00577 
00582   static void DefaultMessages();
00583 
00589   static void Destroy();
00590 
00597   template<typename T>
00598   static T& GetParam(const std::string& identifier);
00599 
00606   static std::string GetDescription(const std::string& identifier);
00607 
00620   static CLI& GetSingleton();
00621 
00627   static bool HasParam(const std::string& identifier);
00628 
00636   static std::string HyphenateString(const std::string& str, int padding);
00637 
00644   static void ParseCommandLine(int argc, char** argv);
00645 
00651   static void RemoveDuplicateFlags(po::basic_parsed_options<char>& bpo);
00652 
00658   static void ParseStream(std::istream& stream);
00659 
00663   static void Print();
00664 
00668   static void PrintHelp(const std::string& param = "");
00669 
00677   static void RegisterProgramDoc(util::ProgramDoc* doc);
00678 
00682   ~CLI();
00683 
00684  private:
00686   po::options_description desc;
00687 
00689   po::variables_map vmap;
00690 
00692   std::list<std::string> requiredOptions;
00693 
00695   typedef std::map<std::string, ParamData> gmap_t;
00696   gmap_t globalValues;
00697 
00699   typedef std::map<std::string, std::string> amap_t;
00700   amap_t aliasValues;
00701 
00703   static CLI* singleton;
00704 
00706   bool didParse;
00707 
00709   std::string programName;
00710 
00712   Timers timer;
00713 
00715   friend class Timer;
00716 
00717  public:
00719   util::ProgramDoc *doc;
00720 
00721  private:
00728   static void AddAlias(const std::string& alias, const std::string& original);
00729 
00737   static std::string AliasReverseLookup(const std::string& value);
00738 
00739 #ifdef _WIN32
00740 
00745   void FileTimeToTimeVal(timeval* tv);
00746 #endif
00747 
00753   static void RequiredOptions();
00754 
00762   static std::string SanitizeString(const std::string& str);
00763 
00767   static void UpdateGmap();
00768 
00772   CLI();
00773 
00779   CLI(const std::string& optionsName);
00780 
00782   CLI(const CLI& other);
00783 };
00784 
00785 }; // namespace mlpack
00786 
00787 // Include the actual definitions of templated methods
00788 #include "cli_impl.hpp"
00789 
00790 #endif

Generated on 13 Aug 2014 for MLPACK by  doxygen 1.6.1