parse.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //
  2. // Copyright 2019 The Abseil Authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // https://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. // -----------------------------------------------------------------------------
  17. // File: parse.h
  18. // -----------------------------------------------------------------------------
  19. //
  20. // This file defines the main parsing function for Abseil flags:
  21. // `absl::ParseCommandLine()`.
  22. #ifndef ABSL_FLAGS_PARSE_H_
  23. #define ABSL_FLAGS_PARSE_H_
  24. #include <string>
  25. #include <vector>
  26. #include "absl/base/config.h"
  27. #include "absl/flags/internal/parse.h"
  28. namespace absl {
  29. ABSL_NAMESPACE_BEGIN
  30. // This type represent information about an unrecognized flag in the command
  31. // line.
  32. struct UnrecognizedFlag {
  33. enum Source { kFromArgv, kFromFlagfile };
  34. explicit UnrecognizedFlag(Source s, absl::string_view f)
  35. : source(s), flag_name(f) {}
  36. // This field indicates where we found this flag: on the original command line
  37. // or read in some flag file.
  38. Source source;
  39. // Name of the flag we did not recognize in --flag_name=value or --flag_name.
  40. std::string flag_name;
  41. };
  42. inline bool operator==(const UnrecognizedFlag& lhs,
  43. const UnrecognizedFlag& rhs) {
  44. return lhs.source == rhs.source && lhs.flag_name == rhs.flag_name;
  45. }
  46. namespace flags_internal {
  47. HelpMode ParseAbseilFlagsOnlyImpl(
  48. int argc, char* argv[], std::vector<char*>& positional_args,
  49. std::vector<UnrecognizedFlag>& unrecognized_flags,
  50. UsageFlagsAction usage_flag_action);
  51. } // namespace flags_internal
  52. // ParseAbseilFlagsOnly()
  53. //
  54. // Parses a list of command-line arguments, passed in the `argc` and `argv[]`
  55. // parameters, into a set of Abseil Flag values, returning any unparsed
  56. // arguments in `positional_args` and `unrecognized_flags` output parameters.
  57. //
  58. // This function classifies all the arguments (including content of the
  59. // flagfiles, if any) into one of the following groups:
  60. //
  61. // * arguments specified as "--flag=value" or "--flag value" that match
  62. // registered or built-in Abseil Flags. These are "Abseil Flag arguments."
  63. // * arguments specified as "--flag" that are unrecognized as Abseil Flags
  64. // * arguments that are not specified as "--flag" are positional arguments
  65. // * arguments that follow the flag-terminating delimiter (`--`) are also
  66. // treated as positional arguments regardless of their syntax.
  67. //
  68. // All of the deduced Abseil Flag arguments are then parsed into their
  69. // corresponding flag values. If any syntax errors are found in these arguments,
  70. // the binary exits with code 1.
  71. //
  72. // This function also handles Abseil Flags built-in usage flags (e.g. --help)
  73. // if any were present on the command line.
  74. //
  75. // All the remaining positional arguments including original program name
  76. // (argv[0]) are are returned in the `positional_args` output parameter.
  77. //
  78. // All unrecognized flags that are not otherwise ignored are returned in the
  79. // `unrecognized_flags` output parameter. Note that the special `undefok`
  80. // flag allows you to specify flags which can be safely ignored; `undefok`
  81. // specifies these flags as a comma-separated list. Any unrecognized flags
  82. // that appear within `undefok` will therefore be ignored and not included in
  83. // the `unrecognized_flag` output parameter.
  84. //
  85. void ParseAbseilFlagsOnly(int argc, char* argv[],
  86. std::vector<char*>& positional_args,
  87. std::vector<UnrecognizedFlag>& unrecognized_flags);
  88. // ReportUnrecognizedFlags()
  89. //
  90. // Reports an error to `stderr` for all non-ignored unrecognized flags in
  91. // the provided `unrecognized_flags` list.
  92. void ReportUnrecognizedFlags(
  93. const std::vector<UnrecognizedFlag>& unrecognized_flags);
  94. // ParseCommandLine()
  95. //
  96. // First parses Abseil Flags only from the command line according to the
  97. // description in `ParseAbseilFlagsOnly`. In addition this function handles
  98. // unrecognized and usage flags.
  99. //
  100. // If any unrecognized flags are located they are reported using
  101. // `ReportUnrecognizedFlags`.
  102. //
  103. // If any errors detected during command line parsing, this routine reports a
  104. // usage message and aborts the program.
  105. //
  106. // If any built-in usage flags were specified on the command line (e.g.
  107. // `--help`), this function reports help messages and then gracefully exits the
  108. // program.
  109. //
  110. // This function returns all the remaining positional arguments collected by
  111. // `ParseAbseilFlagsOnly`.
  112. std::vector<char*> ParseCommandLine(int argc, char* argv[]);
  113. ABSL_NAMESPACE_END
  114. } // namespace absl
  115. #endif // ABSL_FLAGS_PARSE_H_