ArgParser.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /**
  2. * libdatachannel streamer example
  3. * Copyright (c) 2020 Filip Klembara (in2core)
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  8. */
  9. #include "ArgParser.hpp"
  10. #include <iostream>
  11. ArgParser::ArgParser(std::vector<std::pair<std::string, std::string>> options, std::vector<std::pair<std::string, std::string>> flags) {
  12. for(auto option: options) {
  13. this->options.insert(option.first);
  14. this->options.insert(option.second);
  15. shortToLongMap.emplace(option.first, option.second);
  16. shortToLongMap.emplace(option.second, option.second);
  17. }
  18. for(auto flag: flags) {
  19. this->flags.insert(flag.first);
  20. this->flags.insert(flag.second);
  21. shortToLongMap.emplace(flag.first, flag.second);
  22. shortToLongMap.emplace(flag.second, flag.second);
  23. }
  24. }
  25. std::optional<std::string> ArgParser::toKey(std::string prefixedKey) {
  26. if (prefixedKey.find("--") == 0) {
  27. return prefixedKey.substr(2, prefixedKey.length());
  28. } else if (prefixedKey.find("-") == 0) {
  29. return prefixedKey.substr(1, prefixedKey.length());
  30. } else {
  31. return std::nullopt;
  32. }
  33. }
  34. bool ArgParser::parse(int argc, char **argv, std::function<bool (std::string, std::string)> onOption, std::function<bool (std::string)> onFlag) {
  35. std::optional<std::string> currentOption = std::nullopt;
  36. for(int i = 1; i < argc; i++) {
  37. std::string current = argv[i];
  38. auto optKey = toKey(current);
  39. if (!currentOption.has_value() && optKey.has_value() && flags.find(optKey.value()) != flags.end()) {
  40. auto check = onFlag(shortToLongMap.at(optKey.value()));
  41. if (!check) {
  42. return false;
  43. }
  44. } else if (!currentOption.has_value() && optKey.has_value() && options.find(optKey.value()) != options.end()) {
  45. currentOption = optKey.value();
  46. } else if (currentOption.has_value()) {
  47. auto check = onOption(shortToLongMap.at(currentOption.value()), current);
  48. if (!check) {
  49. return false;
  50. }
  51. currentOption = std::nullopt;
  52. } else {
  53. std::cerr << "Unrecognized option " << current << std::endl;
  54. return false;
  55. }
  56. }
  57. if (currentOption.has_value()) {
  58. std::cerr << "Missing value for " << currentOption.value() << std::endl;
  59. return false;
  60. }
  61. return true;
  62. }