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