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 23 #ifndef ABSL_FLAGS_PARSE_H_ 24 #define ABSL_FLAGS_PARSE_H_ 25 26 #include <string> 27 #include <vector> 28 29 #include "absl/base/config.h" 30 #include "absl/flags/internal/parse.h" 31 32 namespace absl { 33 ABSL_NAMESPACE_BEGIN 34 35 // This type represent information about an unrecognized flag in the command 36 // line. 37 struct UnrecognizedFlag { 38 enum Source { kFromArgv, kFromFlagfile }; 39 UnrecognizedFlagUnrecognizedFlag40 explicit UnrecognizedFlag(Source s, absl::string_view f) 41 : source(s), flag_name(f) {} 42 // This field indicates where we found this flag: on the original command line 43 // or read in some flag file. 44 Source source; 45 // Name of the flag we did not recognize in --flag_name=value or --flag_name. 46 std::string flag_name; 47 }; 48 49 inline bool operator==(const UnrecognizedFlag& lhs, 50 const UnrecognizedFlag& rhs) { 51 return lhs.source == rhs.source && lhs.flag_name == rhs.flag_name; 52 } 53 54 namespace flags_internal { 55 56 HelpMode ParseAbseilFlagsOnlyImpl( 57 int argc, char* argv[], std::vector<char*>& positional_args, 58 std::vector<UnrecognizedFlag>& unrecognized_flags, 59 UsageFlagsAction usage_flag_action); 60 61 } // namespace flags_internal 62 63 // ParseAbseilFlagsOnly() 64 // 65 // Parses a list of command-line arguments, passed in the `argc` and `argv[]` 66 // parameters, into a set of Abseil Flag values, returning any unparsed 67 // arguments in `positional_args` and `unrecognized_flags` output parameters. 68 // 69 // This function classifies all the arguments (including content of the 70 // flagfiles, if any) into one of the following groups: 71 // 72 // * arguments specified as "--flag=value" or "--flag value" that match 73 // registered or built-in Abseil Flags. These are "Abseil Flag arguments." 74 // * arguments specified as "--flag" that are unrecognized as Abseil Flags 75 // * arguments that are not specified as "--flag" are positional arguments 76 // * arguments that follow the flag-terminating delimiter (`--`) are also 77 // treated as positional arguments regardless of their syntax. 78 // 79 // All of the deduced Abseil Flag arguments are then parsed into their 80 // corresponding flag values. If any syntax errors are found in these arguments, 81 // the binary exits with code 1. 82 // 83 // This function also handles Abseil Flags built-in usage flags (e.g. --help) 84 // if any were present on the command line. 85 // 86 // All the remaining positional arguments including original program name 87 // (argv[0]) are are returned in the `positional_args` output parameter. 88 // 89 // All unrecognized flags that are not otherwise ignored are returned in the 90 // `unrecognized_flags` output parameter. Note that the special `undefok` 91 // flag allows you to specify flags which can be safely ignored; `undefok` 92 // specifies these flags as a comma-separated list. Any unrecognized flags 93 // that appear within `undefok` will therefore be ignored and not included in 94 // the `unrecognized_flag` output parameter. 95 // 96 void ParseAbseilFlagsOnly(int argc, char* argv[], 97 std::vector<char*>& positional_args, 98 std::vector<UnrecognizedFlag>& unrecognized_flags); 99 100 // ReportUnrecognizedFlags() 101 // 102 // Reports an error to `stderr` for all non-ignored unrecognized flags in 103 // the provided `unrecognized_flags` list. 104 void ReportUnrecognizedFlags( 105 const std::vector<UnrecognizedFlag>& unrecognized_flags); 106 107 // ParseCommandLine() 108 // 109 // First parses Abseil Flags only from the command line according to the 110 // description in `ParseAbseilFlagsOnly`. In addition this function handles 111 // unrecognized and usage flags. 112 // 113 // If any unrecognized flags are located they are reported using 114 // `ReportUnrecognizedFlags`. 115 // 116 // If any errors detected during command line parsing, this routine reports a 117 // usage message and aborts the program. 118 // 119 // If any built-in usage flags were specified on the command line (e.g. 120 // `--help`), this function reports help messages and then gracefully exits the 121 // program. 122 // 123 // This function returns all the remaining positional arguments collected by 124 // `ParseAbseilFlagsOnly`. 125 std::vector<char*> ParseCommandLine(int argc, char* argv[]); 126 127 ABSL_NAMESPACE_END 128 } // namespace absl 129 130 #endif // ABSL_FLAGS_PARSE_H_ 131