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