您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

100 行
2.4 KiB

  1. #pragma once
  2. #include <cppargs/parser/parser.h>
  3. #include <cppargs/group/group.inl>
  4. #include <cppargs/misc/printing.inl>
  5. namespace cppargs
  6. {
  7. parser::parser(
  8. option_ptr_type&& p_default,
  9. group& p_group)
  10. : _default (std::move(p_default))
  11. , _group (p_group)
  12. { }
  13. void parser::add_to_map(const group& g)
  14. {
  15. for (auto& o : g._options)
  16. {
  17. if (!o)
  18. throw std::runtime_error("expectd option to not be null!");
  19. if (o->meta.short_name)
  20. {
  21. if (!_map.emplace(std::string("-") + o->meta.short_name, o.get()).second)
  22. throw std::runtime_error(std::string("duplicate option key: ") + o->meta.short_name);
  23. }
  24. if (!o->meta.long_name.empty())
  25. {
  26. if (!_map.emplace(std::string("--") + o->meta.long_name, o.get()).second)
  27. throw std::runtime_error(std::string("duplicate option key: ") + o->meta.long_name);
  28. }
  29. }
  30. for (auto& i : g._groups)
  31. {
  32. if (!i)
  33. throw std::runtime_error("expectd group to not be null!");
  34. add_to_map(*i);
  35. }
  36. }
  37. void parser::update_map()
  38. {
  39. _map.clear();
  40. add_to_map(_group);
  41. }
  42. void parser::handle_invalid_arg(context& c) const
  43. {
  44. if (_default)
  45. {
  46. _default->parse(c);
  47. }
  48. else
  49. {
  50. throw std::runtime_error(std::string("invalid or unknown argument: ") + c.arg);
  51. }
  52. }
  53. void parser::parse(int argc, char const * argv[]) const
  54. {
  55. if (argc <= 0) {
  56. return;
  57. }
  58. context c
  59. {
  60. argc,
  61. argv,
  62. argv[0],
  63. };
  64. next_result ret;
  65. std::string key;
  66. while ((ret = c.next(&key)) != next_result::finished)
  67. {
  68. /* move to next option */
  69. if ( ret != next_result::option_short
  70. && ret != next_result::option_long)
  71. handle_invalid_arg(c);
  72. /* find option */
  73. auto it = _map.find(key);
  74. if (it == _map.end())
  75. {
  76. handle_invalid_arg(c);
  77. }
  78. else
  79. {
  80. it->second->parse(c);
  81. }
  82. }
  83. }
  84. void parser::print_help(std::ostream& os) const
  85. { printing { } (os, _group); }
  86. }