opt2.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #pragma once
  2. #include <util/system/defaults.h>
  3. #include <util/generic/string.h>
  4. #include <util/generic/vector.h>
  5. // simplified options parser
  6. // No 'optional argument' (e.g. "a::" in spec.) support;
  7. // Supports '+' switch (see opt.h), does not support '-';
  8. /** Typical use
  9. Opt2 opt(argc, argv, "A:b:c", 3); <- 3 more arguments expected, opt.Pos[0], etc.
  10. ** Usage description for options is provided through functions that query values **
  11. const char *a = opt.Arg('A', "<var_name> - usage of -A"); <- This option is required
  12. int b = opt.Int('b', "<var_name> - usage of -b", 2); <- This option has default value, not required
  13. bool c = opt.Has('c', "- usage of -c"); <- switches are always optional
  14. ** Additional argument names are provided in AutoUsage call **
  15. ** AutoUsage generages 'USAGE' text automatically **
  16. if (opt.AutoUsage("<L> <M>")) <- Returns 1 if there was any error in getopt
  17. return 1;
  18. OR: opt.AutoUsageErr("<L> <M>"); <- Will terminate program for you :)
  19. */
  20. // Note: struct Opt2Param can be moved to cpp-file
  21. struct Opt2Param {
  22. char opt;
  23. bool HasArg;
  24. bool IsFound;
  25. bool IsNumeric;
  26. bool IsRequired;
  27. bool MultipleUse;
  28. const char* DefValue;
  29. TString DefValueStr;
  30. TString HelpUsage;
  31. TVector<const char*> ActualValue;
  32. const char* LongOptName;
  33. Opt2Param()
  34. : HasArg(false)
  35. , IsFound(0)
  36. , IsNumeric(0)
  37. , IsRequired(0)
  38. , MultipleUse(0)
  39. , DefValue(nullptr)
  40. , LongOptName(nullptr)
  41. {
  42. }
  43. };
  44. struct IntRange {
  45. int Left, Right;
  46. IntRange() = delete;
  47. IntRange(int both)
  48. : Left(both)
  49. , Right(both)
  50. {
  51. }
  52. IntRange(int left, int right)
  53. : Left(left)
  54. , Right(right)
  55. {
  56. }
  57. };
  58. class Opt2 {
  59. public:
  60. Opt2() = default;
  61. Opt2(int argc, char* const* argv, const char* optspec, IntRange free_args_num = -1, const char* long_alias = nullptr) {
  62. Init(argc, argv, optspec, free_args_num, long_alias);
  63. }
  64. // Init throws exception only in case of incorrect optspec.
  65. // In other cases, consult HasErrors or call AutoUsage()
  66. void Init(int argc, char* const* argv, const char* optspec, IntRange free_args_num = -1, const char* long_alias = nullptr);
  67. // In case of incorrect options, constructs and prints Usage text,
  68. // usually to stderr (however, to stdout if '-?' switch was used), and returns 1.
  69. int AutoUsage(const char* free_arg_names = "");
  70. // same as AutoUsage but calls exit(1) instead of error code
  71. void AutoUsageErr(const char* free_arg_names = "");
  72. // For options with parameters
  73. const char* Arg(char opt, const char* helpUsage, const char* defValue, bool required = false);
  74. const char* Arg(char opt, const char* helpUsage) {
  75. return Arg(opt, helpUsage, nullptr, true);
  76. }
  77. const char* Arg(char opt, const char* helpUsage, TString defValue, bool required = false);
  78. // Options with parameters that can be specified several times
  79. const TVector<const char*>& MArg(char opt, const char* helpUsage);
  80. // Get() + strtol, may set up HasErrors
  81. long Int(char opt, const char* helpUsage, long defValue, bool required = false);
  82. long Int(char opt, const char* helpUsage) {
  83. return Int(opt, helpUsage, 0, true);
  84. }
  85. // Get() + strtoul, may set up HasErrors
  86. unsigned long UInt(char opt, const char* helpUsage, unsigned long defValue, bool required = false);
  87. unsigned long UInt(char opt, const char* helpUsage) {
  88. return UInt(opt, helpUsage, 0, true);
  89. }
  90. // For options w/o parameters
  91. bool Has(char opt, const char* helpUsage);
  92. // Add user defined error message and set error flag
  93. void AddError(const char* message = nullptr);
  94. public:
  95. // non-option args
  96. TVector<char*> Pos;
  97. bool HasErrors;
  98. private:
  99. bool BadPosCount;
  100. char UnknownOption;
  101. char* UnknownLongOption;
  102. char OptionMissingArg;
  103. char OptionWrongArg;
  104. char RequiredOptionMissing;
  105. TVector<TString> UserErrorMessages;
  106. protected:
  107. int Argc;
  108. char* const* Argv;
  109. int MinArgs, MaxArgs;
  110. ui8 SpecsMap[256];
  111. TVector<Opt2Param> Specs;
  112. TString alias_copy;
  113. void EatArgv(const char* optspec, const char* long_alias);
  114. void Clear();
  115. Opt2Param& GetInternal(char opt, const char* defValue, const char* helpUsage, bool required);
  116. };