^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: getopt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * ACPICA getopt() implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Option strings:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * "f" - Option has no arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * "f:" - Option requires an argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * "f+" - Option has an optional argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * "f^" - Option has optional single-char sub-options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * "f|" - Option has required single-char sub-options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "acapps.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ACPI_OPTION_ERROR(msg, badchar) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int acpi_gbl_opterr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int acpi_gbl_optind = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int acpi_gbl_sub_opt_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) char *acpi_gbl_optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * FUNCTION: acpi_getopt_argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * PARAMETERS: argc, argv - from main
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * to point to the next argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * DESCRIPTION: Get the next argument. Used to obtain arguments for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * two-character options after the original call to acpi_getopt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Note: Either the argument starts at the next character after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * the option, or it is pointed to by the next argv entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * (After call to acpi_getopt, we need to backup to the previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * argv entry).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int acpi_getopt_argument(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) acpi_gbl_optind--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) current_char_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) acpi_gbl_optarg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } else if (++acpi_gbl_optind >= argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ACPI_OPTION_ERROR("\nOption requires an argument", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return (-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) acpi_gbl_optarg = argv[acpi_gbl_optind++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * FUNCTION: acpi_getopt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * PARAMETERS: argc, argv - from main
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * opts - options info list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * RETURN: Option character or ACPI_OPT_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * DESCRIPTION: Get the next option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int acpi_getopt(int argc, char **argv, char *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int current_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) char *opts_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (current_char_ptr == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (acpi_gbl_optind >= argc ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) argv[acpi_gbl_optind][0] != '-' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) argv[acpi_gbl_optind][1] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return (ACPI_OPT_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) acpi_gbl_optind++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return (ACPI_OPT_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Get the option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) current_char = argv[acpi_gbl_optind][current_char_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Make sure that the option is legal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (current_char == ':' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) (opts_ptr = strchr(opts, current_char)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ACPI_OPTION_ERROR("Illegal option: -", current_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) acpi_gbl_optind++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ('?');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Option requires an argument? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (*++opts_ptr == ':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) acpi_gbl_optarg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) &argv[acpi_gbl_optind++][(int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) (current_char_ptr + 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) } else if (++acpi_gbl_optind >= argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ACPI_OPTION_ERROR("Option requires an argument: -",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) current_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ('?');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) acpi_gbl_optarg = argv[acpi_gbl_optind++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Option has an optional argument? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) else if (*opts_ptr == '+') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) acpi_gbl_optarg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) &argv[acpi_gbl_optind++][(int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (current_char_ptr + 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) } else if (++acpi_gbl_optind >= argc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) acpi_gbl_optarg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) acpi_gbl_optarg = argv[acpi_gbl_optind++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Option has optional single-char arguments? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) else if (*opts_ptr == '^') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) acpi_gbl_optarg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) acpi_gbl_optarg = "^";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) acpi_gbl_optind++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Option has a required single-char argument? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) else if (*opts_ptr == '|') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) acpi_gbl_optarg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ACPI_OPTION_ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ("Option requires a single-character suboption: -",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) current_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return ('?');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) acpi_gbl_optind++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Option with no arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) current_char_ptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) acpi_gbl_optind++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) acpi_gbl_optarg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return (current_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }