CommandLineParser.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #ifndef _TYP_COMMAND_LINE_PARSER_HPP
  2. #define _TYP_COMMAND_LINE_PARSER_HPP
  3. #include <string>
  4. #include <vector>
  5. #include <map>
  6. /// @brief command line arg item
  7. /// @tparam T context type
  8. template <class T>
  9. class TyCommandlineItem
  10. {
  11. public:
  12. TyCommandlineItem(const std::string &name = "",
  13. const std::string &describe = "",
  14. bool is_flag = false,
  15. const std::string &default_val = "")
  16. {
  17. this->name = name;
  18. this->describe = describe;
  19. this->default_val = default_val;
  20. this->is_flag = is_flag;
  21. has_set = false;
  22. curr_val = default_val;
  23. }
  24. std::string name, describe; ///< name and describe
  25. std::string default_val; ///< default value
  26. bool is_flag; ///< flag only, no value
  27. T ctx; ///< context
  28. bool has_set; ///< has set by command line
  29. std::string curr_val; ///< current arg value
  30. int get_int_val() const
  31. {
  32. return std::stoi(curr_val);
  33. }
  34. float get_float_val() const
  35. {
  36. return std::stof(curr_val);
  37. }
  38. double get_double_val() const
  39. {
  40. return std::stod(curr_val);
  41. }
  42. std::string get_str_val() const
  43. {
  44. return curr_val;
  45. }
  46. bool get_bool_val() const
  47. {
  48. return curr_val == "true" || curr_val == "1";
  49. }
  50. };
  51. ////--------------------
  52. /// @brief command line parser
  53. /// @tparam T context type
  54. template <class T>
  55. class TyCommandlineParser
  56. {
  57. public:
  58. std::map<std::string, TyCommandlineItem<T>> cmd_items; ///< command line items
  59. /// @brief add command line item
  60. /// @param name item name
  61. /// @param describe item describe
  62. /// @param is_flag is flag only
  63. /// @param default_val default value
  64. /// @param ctx context
  65. void addItem(const std::string &name,
  66. const std::string &describe,
  67. bool is_flag = false,
  68. const std::string &default_val = "0",
  69. T ctx = T())
  70. {
  71. TyCommandlineItem<T> item(name, describe, is_flag, default_val);
  72. item.ctx = ctx;
  73. cmd_items.emplace(name, item);
  74. }
  75. /// @brief clear all items
  76. void clear()
  77. {
  78. cmd_items.clear();
  79. }
  80. /// @brief parse command line
  81. /// @param argc arg count
  82. /// @param argv arg list
  83. /// @return 0: success, -1: failed
  84. int parse(int argc, char *argv[])
  85. {
  86. int idx = 1;
  87. while (idx < argc)
  88. {
  89. std::string arg = argv[idx];
  90. if (arg[0] != '-')
  91. {
  92. continue;
  93. }
  94. arg = arg.substr(1);
  95. auto find_res = cmd_items.find(arg);
  96. if (find_res== cmd_items.end()) {
  97. printf("TyCommandlineParser:ignore unknow param: %s\n", arg.c_str());
  98. idx++;
  99. continue;
  100. }
  101. auto& item = find_res->second;
  102. item.has_set = true;
  103. item.curr_val = item.default_val;
  104. if (idx + 1 < argc && !item.is_flag)
  105. {
  106. item.curr_val = argv[idx + 1];
  107. idx++;
  108. }
  109. idx++;
  110. }
  111. return 0;
  112. }
  113. /// @brief get command line item
  114. /// @param name item name
  115. /// @return item
  116. const TyCommandlineItem<T> *get(const std::string &name) const
  117. {
  118. auto find_res = cmd_items.find(name);
  119. if (find_res != cmd_items.end()) {
  120. return &find_res->second;
  121. }
  122. LOGE("ERROR: not find command argv by name %s ", name.c_str());
  123. return nullptr;
  124. }
  125. /// @brief get usage string
  126. /// @return usage string
  127. std::string getUsage() const
  128. {
  129. std::string usage = "Usage: \n";
  130. size_t max_name_len = 1;
  131. for (auto& kv : cmd_items) {
  132. max_name_len = std::max(kv.first.size(), max_name_len);
  133. }
  134. for (auto& kv : cmd_items)
  135. {
  136. const auto &cmd = kv.second;
  137. std::string name = cmd.name;
  138. if (name.size() < max_name_len) {
  139. name.append(max_name_len - name.size(), ' ');
  140. }
  141. usage += " -" + name + " ";
  142. if (!cmd.is_flag)
  143. {
  144. usage += "<value> ";
  145. }
  146. else {
  147. usage += " ";
  148. }
  149. usage += cmd.describe + " \n";
  150. }
  151. return usage;
  152. }
  153. };
  154. #endif // _TYP_COMMAND_LINE_PARSER_HPP