parse_options.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /**
  2. \file parse_options.cpp
  3. \author michael.zohner@ec-spride.de
  4. \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
  5. Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Lesser General Public License as published
  8. by the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. ABY 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 Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. \brief Parse Options Implementation
  17. */
  18. #include "parse_options.h"
  19. #include <cstring>
  20. #include <iostream>
  21. /**
  22. * takes a string in the Format "c i i i ..."
  23. * (1 char followed by potentially many integers) and returns a vector of all i
  24. * @param str the string to tokenize
  25. * @param tokens the result vector of wire id
  26. */
  27. void tokenize_verilog(const std::string& str, std::vector<uint32_t>& tokens, const std::string& delimiters) {
  28. tokens.clear();
  29. // Skip delimiters at beginning. Skip first two characters (1 Char + 1 Space)
  30. std::string::size_type lastPos = str.find_first_not_of(delimiters, 2);
  31. // Find first "non-delimiter".
  32. std::string::size_type pos = str.find_first_of(delimiters, lastPos);
  33. while (std::string::npos != pos || std::string::npos != lastPos) {
  34. // Found a token, add it to the vector.
  35. tokens.push_back(atoi(str.substr(lastPos, pos - lastPos).c_str()));
  36. // Skip delimiters. Note the "not_of"
  37. lastPos = str.find_first_not_of(delimiters, pos);
  38. // Find next "non-delimiter"
  39. pos = str.find_first_of(delimiters, lastPos);
  40. }
  41. }
  42. /**
  43. * takes a string in the Format "i|i|i|..."
  44. * (integers separated by '|') and returns a vector of all integers
  45. * @param str the string to tokenize
  46. * @param tokens the result vector of wire id
  47. */
  48. void tokenize(const std::string& str, std::vector<uint32_t>& tokens, const std::string& delimiters) {
  49. tokens.clear();
  50. // Skip delimiters at beginning
  51. std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  52. // Find first "non-delimiter".
  53. std::string::size_type pos = str.find_first_of(delimiters, lastPos);
  54. while (std::string::npos != pos || std::string::npos != lastPos) {
  55. // Found a token, add it to the vector.
  56. tokens.push_back(atoi(str.substr(lastPos, pos - lastPos).c_str()));
  57. // Skip delimiters. Note the "not_of"
  58. lastPos = str.find_first_not_of(delimiters, pos);
  59. // Find next "non-delimiter"
  60. pos = str.find_first_of(delimiters, lastPos);
  61. }
  62. }
  63. int32_t parse_options(int32_t* argcp, char*** argvp, parsing_ctx* options, uint32_t nops) {
  64. int result = 0;
  65. bool skip;
  66. uint32_t i;
  67. if(*argcp < 2)
  68. return 0;
  69. while ((*argcp) > 1) {
  70. if ((*argvp)[1][0] != '-' || (*argvp)[1][1] == '\0' || (*argvp)[1][2] != '\0'){
  71. return result;
  72. }
  73. skip=false;
  74. for (i = 0, skip = false; i < nops && !skip; i++) {
  75. if (strncmp(&((*argvp)[1][1]), options[i].opt_name.c_str(), options[i].opt_name.size()) == 0
  76. && (strlen((*argvp)[1])-1 == options[i].opt_name.size())) {
  77. switch (options[i].type) {
  78. case T_NUM:
  79. if (isdigit((*argvp)[2][0])) {
  80. ++*argvp;
  81. --*argcp;
  82. *((uint32_t*) options[i].val) = atoi((*argvp)[1]);
  83. } else {
  84. std::cerr << "Argument for parameter wrong. " << std::endl;
  85. return 0;
  86. }
  87. break;
  88. case T_DOUBLE:
  89. ++*argvp;
  90. --*argcp;
  91. *((double*) options[i].val) = atof((*argvp)[1]);
  92. break;
  93. case T_STR:
  94. ++*argvp;
  95. --*argcp;
  96. *((std::string*) options[i].val) = (*argvp)[1];
  97. break;
  98. case T_FLAG:
  99. *((bool*) options[i].val) = true;
  100. break;
  101. }
  102. ++result;
  103. ++*argvp;
  104. --*argcp;
  105. options[i].set = true;
  106. skip = true;
  107. }
  108. }
  109. if(skip == false) {
  110. std::cerr << "Parameter not recognized. " << std::endl;
  111. return 0;
  112. }
  113. }
  114. for (i = 0; i < nops; i++) {
  115. if (options[i].required && !options[i].set)
  116. return 0;
  117. }
  118. return 1;
  119. }
  120. void print_usage(std::string progname, parsing_ctx* options, uint32_t nops) {
  121. uint32_t i;
  122. std::cout << "Usage: " << progname << std::endl;
  123. for (i = 0; i < nops; i++) {
  124. std::cout << " -" << options[i].opt_name << " [" << options[i].help_str << (options[i].required ? ", required" : ", optional") << "]" << std::endl;
  125. }
  126. std::cout << std::endl << "Program exiting" << std::endl;
  127. }