/*1* *****************************************************************************2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2018-2025 Gavin D. Howard and contributors.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions are met:9*10* * Redistributions of source code must retain the above copyright notice, this11* list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright notice,14* this list of conditions and the following disclaimer in the documentation15* and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"18* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE21* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS24* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN25* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)26* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE27* POSSIBILITY OF SUCH DAMAGE.28*29* *****************************************************************************30*31* Adapted from https://github.com/skeeto/optparse32*33* *****************************************************************************34*35* Definitions for getopt_long() replacement.36*37*/3839#ifndef BC_OPT_H40#define BC_OPT_H4142#include <stdbool.h>43#include <stdlib.h>4445/// The data required to parse command-line arguments.46typedef struct BcOpt47{48/// The array of arguments.49const char** argv;5051/// The index of the current argument.52size_t optind;5354/// The actual parse option character.55int optopt;5657/// Where in the option we are for multi-character single-character options.58int subopt;5960/// The option argument.61const char* optarg;6263} BcOpt;6465/// The types of arguments. This is specially adapted for bc.66typedef enum BcOptType67{68/// No argument required.69BC_OPT_NONE,7071/// An argument required.72BC_OPT_REQUIRED,7374/// An option that is bc-only.75BC_OPT_BC_ONLY,7677/// An option that is bc-only that requires an argument.78BC_OPT_REQUIRED_BC_ONLY,7980/// An option that is dc-only.81BC_OPT_DC_ONLY,8283} BcOptType;8485/// A struct to hold const data for long options.86typedef struct BcOptLong87{88/// The name of the option.89const char* name;9091/// The type of the option.92BcOptType type;9394/// The character to return if the long option was parsed.95int val;9697} BcOptLong;9899/**100* Initialize data for parsing options.101* @param o The option data to initialize.102* @param argv The array of arguments.103*/104void105bc_opt_init(BcOpt* o, const char** argv);106107/**108* Parse an option. This returns a value the same way getopt() and getopt_long()109* do, so it returns a character for the parsed option or -1 if done.110* @param o The option data.111* @param longopts The long options.112* @return A character for the parsed option, or -1 if done.113*/114int115bc_opt_parse(BcOpt* o, const BcOptLong* longopts);116117/**118* Returns true if the option is `--` and not a long option.119* @param a The argument to parse.120* @return True if @a a is the `--` option, false otherwise.121*/122#define BC_OPT_ISDASHDASH(a) \123((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] == '\0')124125/**126* Returns true if the option is a short option.127* @param a The argument to parse.128* @return True if @a a is a short option, false otherwise.129*/130#define BC_OPT_ISSHORTOPT(a) \131((a) != NULL && (a)[0] == '-' && (a)[1] != '-' && (a)[1] != '\0')132133/**134* Returns true if the option has `--` at the beginning, i.e., is a long option.135* @param a The argument to parse.136* @return True if @a a is a long option, false otherwise.137*/138#define BC_OPT_ISLONGOPT(a) \139((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] != '\0')140141#endif // BC_OPT_H142143144