1*5a6e8488SAndroid Build Coastguard Worker /* 2*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 3*5a6e8488SAndroid Build Coastguard Worker * 4*5a6e8488SAndroid Build Coastguard Worker * SPDX-License-Identifier: BSD-2-Clause 5*5a6e8488SAndroid Build Coastguard Worker * 6*5a6e8488SAndroid Build Coastguard Worker * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7*5a6e8488SAndroid Build Coastguard Worker * 8*5a6e8488SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 9*5a6e8488SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 10*5a6e8488SAndroid Build Coastguard Worker * 11*5a6e8488SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright notice, this 12*5a6e8488SAndroid Build Coastguard Worker * list of conditions and the following disclaimer. 13*5a6e8488SAndroid Build Coastguard Worker * 14*5a6e8488SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright notice, 15*5a6e8488SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation 16*5a6e8488SAndroid Build Coastguard Worker * and/or other materials provided with the distribution. 17*5a6e8488SAndroid Build Coastguard Worker * 18*5a6e8488SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*5a6e8488SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*5a6e8488SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*5a6e8488SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*5a6e8488SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*5a6e8488SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*5a6e8488SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*5a6e8488SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*5a6e8488SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*5a6e8488SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*5a6e8488SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE. 29*5a6e8488SAndroid Build Coastguard Worker * 30*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 31*5a6e8488SAndroid Build Coastguard Worker * 32*5a6e8488SAndroid Build Coastguard Worker * Adapted from https://github.com/skeeto/optparse 33*5a6e8488SAndroid Build Coastguard Worker * 34*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 35*5a6e8488SAndroid Build Coastguard Worker * 36*5a6e8488SAndroid Build Coastguard Worker * Definitions for getopt_long() replacement. 37*5a6e8488SAndroid Build Coastguard Worker * 38*5a6e8488SAndroid Build Coastguard Worker */ 39*5a6e8488SAndroid Build Coastguard Worker 40*5a6e8488SAndroid Build Coastguard Worker #ifndef BC_OPT_H 41*5a6e8488SAndroid Build Coastguard Worker #define BC_OPT_H 42*5a6e8488SAndroid Build Coastguard Worker 43*5a6e8488SAndroid Build Coastguard Worker #include <stdbool.h> 44*5a6e8488SAndroid Build Coastguard Worker #include <stdlib.h> 45*5a6e8488SAndroid Build Coastguard Worker 46*5a6e8488SAndroid Build Coastguard Worker /// The data required to parse command-line arguments. 47*5a6e8488SAndroid Build Coastguard Worker typedef struct BcOpt 48*5a6e8488SAndroid Build Coastguard Worker { 49*5a6e8488SAndroid Build Coastguard Worker /// The array of arguments. 50*5a6e8488SAndroid Build Coastguard Worker const char** argv; 51*5a6e8488SAndroid Build Coastguard Worker 52*5a6e8488SAndroid Build Coastguard Worker /// The index of the current argument. 53*5a6e8488SAndroid Build Coastguard Worker size_t optind; 54*5a6e8488SAndroid Build Coastguard Worker 55*5a6e8488SAndroid Build Coastguard Worker /// The actual parse option character. 56*5a6e8488SAndroid Build Coastguard Worker int optopt; 57*5a6e8488SAndroid Build Coastguard Worker 58*5a6e8488SAndroid Build Coastguard Worker /// Where in the option we are for multi-character single-character options. 59*5a6e8488SAndroid Build Coastguard Worker int subopt; 60*5a6e8488SAndroid Build Coastguard Worker 61*5a6e8488SAndroid Build Coastguard Worker /// The option argument. 62*5a6e8488SAndroid Build Coastguard Worker const char* optarg; 63*5a6e8488SAndroid Build Coastguard Worker 64*5a6e8488SAndroid Build Coastguard Worker } BcOpt; 65*5a6e8488SAndroid Build Coastguard Worker 66*5a6e8488SAndroid Build Coastguard Worker /// The types of arguments. This is specially adapted for bc. 67*5a6e8488SAndroid Build Coastguard Worker typedef enum BcOptType 68*5a6e8488SAndroid Build Coastguard Worker { 69*5a6e8488SAndroid Build Coastguard Worker /// No argument required. 70*5a6e8488SAndroid Build Coastguard Worker BC_OPT_NONE, 71*5a6e8488SAndroid Build Coastguard Worker 72*5a6e8488SAndroid Build Coastguard Worker /// An argument required. 73*5a6e8488SAndroid Build Coastguard Worker BC_OPT_REQUIRED, 74*5a6e8488SAndroid Build Coastguard Worker 75*5a6e8488SAndroid Build Coastguard Worker /// An option that is bc-only. 76*5a6e8488SAndroid Build Coastguard Worker BC_OPT_BC_ONLY, 77*5a6e8488SAndroid Build Coastguard Worker 78*5a6e8488SAndroid Build Coastguard Worker /// An option that is bc-only that requires an argument. 79*5a6e8488SAndroid Build Coastguard Worker BC_OPT_REQUIRED_BC_ONLY, 80*5a6e8488SAndroid Build Coastguard Worker 81*5a6e8488SAndroid Build Coastguard Worker /// An option that is dc-only. 82*5a6e8488SAndroid Build Coastguard Worker BC_OPT_DC_ONLY, 83*5a6e8488SAndroid Build Coastguard Worker 84*5a6e8488SAndroid Build Coastguard Worker } BcOptType; 85*5a6e8488SAndroid Build Coastguard Worker 86*5a6e8488SAndroid Build Coastguard Worker /// A struct to hold const data for long options. 87*5a6e8488SAndroid Build Coastguard Worker typedef struct BcOptLong 88*5a6e8488SAndroid Build Coastguard Worker { 89*5a6e8488SAndroid Build Coastguard Worker /// The name of the option. 90*5a6e8488SAndroid Build Coastguard Worker const char* name; 91*5a6e8488SAndroid Build Coastguard Worker 92*5a6e8488SAndroid Build Coastguard Worker /// The type of the option. 93*5a6e8488SAndroid Build Coastguard Worker BcOptType type; 94*5a6e8488SAndroid Build Coastguard Worker 95*5a6e8488SAndroid Build Coastguard Worker /// The character to return if the long option was parsed. 96*5a6e8488SAndroid Build Coastguard Worker int val; 97*5a6e8488SAndroid Build Coastguard Worker 98*5a6e8488SAndroid Build Coastguard Worker } BcOptLong; 99*5a6e8488SAndroid Build Coastguard Worker 100*5a6e8488SAndroid Build Coastguard Worker /** 101*5a6e8488SAndroid Build Coastguard Worker * Initialize data for parsing options. 102*5a6e8488SAndroid Build Coastguard Worker * @param o The option data to initialize. 103*5a6e8488SAndroid Build Coastguard Worker * @param argv The array of arguments. 104*5a6e8488SAndroid Build Coastguard Worker */ 105*5a6e8488SAndroid Build Coastguard Worker void 106*5a6e8488SAndroid Build Coastguard Worker bc_opt_init(BcOpt* o, const char** argv); 107*5a6e8488SAndroid Build Coastguard Worker 108*5a6e8488SAndroid Build Coastguard Worker /** 109*5a6e8488SAndroid Build Coastguard Worker * Parse an option. This returns a value the same way getopt() and getopt_long() 110*5a6e8488SAndroid Build Coastguard Worker * do, so it returns a character for the parsed option or -1 if done. 111*5a6e8488SAndroid Build Coastguard Worker * @param o The option data. 112*5a6e8488SAndroid Build Coastguard Worker * @param longopts The long options. 113*5a6e8488SAndroid Build Coastguard Worker * @return A character for the parsed option, or -1 if done. 114*5a6e8488SAndroid Build Coastguard Worker */ 115*5a6e8488SAndroid Build Coastguard Worker int 116*5a6e8488SAndroid Build Coastguard Worker bc_opt_parse(BcOpt* o, const BcOptLong* longopts); 117*5a6e8488SAndroid Build Coastguard Worker 118*5a6e8488SAndroid Build Coastguard Worker /** 119*5a6e8488SAndroid Build Coastguard Worker * Returns true if the option is `--` and not a long option. 120*5a6e8488SAndroid Build Coastguard Worker * @param a The argument to parse. 121*5a6e8488SAndroid Build Coastguard Worker * @return True if @a a is the `--` option, false otherwise. 122*5a6e8488SAndroid Build Coastguard Worker */ 123*5a6e8488SAndroid Build Coastguard Worker #define BC_OPT_ISDASHDASH(a) \ 124*5a6e8488SAndroid Build Coastguard Worker ((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] == '\0') 125*5a6e8488SAndroid Build Coastguard Worker 126*5a6e8488SAndroid Build Coastguard Worker /** 127*5a6e8488SAndroid Build Coastguard Worker * Returns true if the option is a short option. 128*5a6e8488SAndroid Build Coastguard Worker * @param a The argument to parse. 129*5a6e8488SAndroid Build Coastguard Worker * @return True if @a a is a short option, false otherwise. 130*5a6e8488SAndroid Build Coastguard Worker */ 131*5a6e8488SAndroid Build Coastguard Worker #define BC_OPT_ISSHORTOPT(a) \ 132*5a6e8488SAndroid Build Coastguard Worker ((a) != NULL && (a)[0] == '-' && (a)[1] != '-' && (a)[1] != '\0') 133*5a6e8488SAndroid Build Coastguard Worker 134*5a6e8488SAndroid Build Coastguard Worker /** 135*5a6e8488SAndroid Build Coastguard Worker * Returns true if the option has `--` at the beginning, i.e., is a long option. 136*5a6e8488SAndroid Build Coastguard Worker * @param a The argument to parse. 137*5a6e8488SAndroid Build Coastguard Worker * @return True if @a a is a long option, false otherwise. 138*5a6e8488SAndroid Build Coastguard Worker */ 139*5a6e8488SAndroid Build Coastguard Worker #define BC_OPT_ISLONGOPT(a) \ 140*5a6e8488SAndroid Build Coastguard Worker ((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] != '\0') 141*5a6e8488SAndroid Build Coastguard Worker 142*5a6e8488SAndroid Build Coastguard Worker #endif // BC_OPT_H 143