ArgParser.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * libdatachannel streamer example
  3. * Copyright (c) 2020 Filip Klembara (in2core)
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "ArgParser.hpp"
  19. #include <iostream>
  20. ArgParser::ArgParser(std::vector<std::pair<std::string, std::string>> options, std::vector<std::pair<std::string, std::string>> flags) {
  21. for(auto option: options) {
  22. this->options.insert(option.first);
  23. this->options.insert(option.second);
  24. shortToLongMap.emplace(option.first, option.second);
  25. shortToLongMap.emplace(option.second, option.second);
  26. }
  27. for(auto flag: flags) {
  28. this->flags.insert(flag.first);
  29. this->flags.insert(flag.second);
  30. shortToLongMap.emplace(flag.first, flag.second);
  31. shortToLongMap.emplace(flag.second, flag.second);
  32. }
  33. }
  34. std::optional<std::string> ArgParser::toKey(std::string prefixedKey) {
  35. if (prefixedKey.find("--") == 0) {
  36. return prefixedKey.substr(2, prefixedKey.length());
  37. } else if (prefixedKey.find("-") == 0) {
  38. return prefixedKey.substr(1, prefixedKey.length());
  39. } else {
  40. return std::nullopt;
  41. }
  42. }
  43. bool ArgParser::parse(int argc, char **argv, std::function<bool (std::string, std::string)> onOption, std::function<bool (std::string)> onFlag) {
  44. std::optional<std::string> currentOption = std::nullopt;
  45. for(int i = 1; i < argc; i++) {
  46. std::string current = argv[i];
  47. auto optKey = toKey(current);
  48. if (!currentOption.has_value() && optKey.has_value() && flags.find(optKey.value()) != flags.end()) {
  49. auto check = onFlag(shortToLongMap.at(optKey.value()));
  50. if (!check) {
  51. return false;
  52. }
  53. } else if (!currentOption.has_value() && optKey.has_value() && options.find(optKey.value()) != options.end()) {
  54. currentOption = optKey.value();
  55. } else if (currentOption.has_value()) {
  56. auto check = onOption(shortToLongMap.at(currentOption.value()), current);
  57. if (!check) {
  58. return false;
  59. }
  60. currentOption = std::nullopt;
  61. } else {
  62. std::cerr << "Unrecognized option " << current << std::endl;
  63. return false;
  64. }
  65. }
  66. if (currentOption.has_value()) {
  67. std::cerr << "Missing value for " << currentOption.value() << std::endl;
  68. return false;
  69. }
  70. return true;
  71. }