Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: getopt
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 /*
0011  * ACPICA getopt() implementation
0012  *
0013  * Option strings:
0014  *    "f"       - Option has no arguments
0015  *    "f:"      - Option requires an argument
0016  *    "f+"      - Option has an optional argument
0017  *    "f^"      - Option has optional single-char sub-options
0018  *    "f|"      - Option has required single-char sub-options
0019  */
0020 
0021 #include <acpi/acpi.h>
0022 #include "accommon.h"
0023 #include "acapps.h"
0024 
0025 #define ACPI_OPTION_ERROR(msg, badchar) \
0026     if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
0027 
0028 int acpi_gbl_opterr = 1;
0029 int acpi_gbl_optind = 1;
0030 int acpi_gbl_sub_opt_char = 0;
0031 char *acpi_gbl_optarg;
0032 
0033 static int current_char_ptr = 1;
0034 
0035 /*******************************************************************************
0036  *
0037  * FUNCTION:    acpi_getopt_argument
0038  *
0039  * PARAMETERS:  argc, argv          - from main
0040  *
0041  * RETURN:      0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
0042  *              to point to the next argument.
0043  *
0044  * DESCRIPTION: Get the next argument. Used to obtain arguments for the
0045  *              two-character options after the original call to acpi_getopt.
0046  *              Note: Either the argument starts at the next character after
0047  *              the option, or it is pointed to by the next argv entry.
0048  *              (After call to acpi_getopt, we need to backup to the previous
0049  *              argv entry).
0050  *
0051  ******************************************************************************/
0052 
0053 int acpi_getopt_argument(int argc, char **argv)
0054 {
0055 
0056     acpi_gbl_optind--;
0057     current_char_ptr++;
0058 
0059     if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
0060         acpi_gbl_optarg =
0061             &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
0062     } else if (++acpi_gbl_optind >= argc) {
0063         ACPI_OPTION_ERROR("\nOption requires an argument", 0);
0064 
0065         current_char_ptr = 1;
0066         return (-1);
0067     } else {
0068         acpi_gbl_optarg = argv[acpi_gbl_optind++];
0069     }
0070 
0071     current_char_ptr = 1;
0072     return (0);
0073 }
0074 
0075 /*******************************************************************************
0076  *
0077  * FUNCTION:    acpi_getopt
0078  *
0079  * PARAMETERS:  argc, argv          - from main
0080  *              opts                - options info list
0081  *
0082  * RETURN:      Option character or ACPI_OPT_END
0083  *
0084  * DESCRIPTION: Get the next option
0085  *
0086  ******************************************************************************/
0087 
0088 int acpi_getopt(int argc, char **argv, char *opts)
0089 {
0090     int current_char;
0091     char *opts_ptr;
0092 
0093     if (current_char_ptr == 1) {
0094         if (acpi_gbl_optind >= argc ||
0095             argv[acpi_gbl_optind][0] != '-' ||
0096             argv[acpi_gbl_optind][1] == '\0') {
0097             return (ACPI_OPT_END);
0098         } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
0099             acpi_gbl_optind++;
0100             return (ACPI_OPT_END);
0101         }
0102     }
0103 
0104     /* Get the option */
0105 
0106     current_char = argv[acpi_gbl_optind][current_char_ptr];
0107 
0108     /* Make sure that the option is legal */
0109 
0110     if (current_char == ':' ||
0111         (opts_ptr = strchr(opts, current_char)) == NULL) {
0112         ACPI_OPTION_ERROR("Illegal option: -", current_char);
0113 
0114         if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
0115             acpi_gbl_optind++;
0116             current_char_ptr = 1;
0117         }
0118 
0119         return ('?');
0120     }
0121 
0122     /* Option requires an argument? */
0123 
0124     if (*++opts_ptr == ':') {
0125         if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
0126             acpi_gbl_optarg =
0127                 &argv[acpi_gbl_optind++][(int)
0128                              (current_char_ptr + 1)];
0129         } else if (++acpi_gbl_optind >= argc) {
0130             ACPI_OPTION_ERROR("Option requires an argument: -",
0131                       current_char);
0132 
0133             current_char_ptr = 1;
0134             return ('?');
0135         } else {
0136             acpi_gbl_optarg = argv[acpi_gbl_optind++];
0137         }
0138 
0139         current_char_ptr = 1;
0140     }
0141 
0142     /* Option has an optional argument? */
0143 
0144     else if (*opts_ptr == '+') {
0145         if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
0146             acpi_gbl_optarg =
0147                 &argv[acpi_gbl_optind++][(int)
0148                              (current_char_ptr + 1)];
0149         } else if (++acpi_gbl_optind >= argc) {
0150             acpi_gbl_optarg = NULL;
0151         } else {
0152             acpi_gbl_optarg = argv[acpi_gbl_optind++];
0153         }
0154 
0155         current_char_ptr = 1;
0156     }
0157 
0158     /* Option has optional single-char arguments? */
0159 
0160     else if (*opts_ptr == '^') {
0161         if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
0162             acpi_gbl_optarg =
0163                 &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
0164         } else {
0165             acpi_gbl_optarg = "^";
0166         }
0167 
0168         acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
0169         acpi_gbl_optind++;
0170         current_char_ptr = 1;
0171     }
0172 
0173     /* Option has a required single-char argument? */
0174 
0175     else if (*opts_ptr == '|') {
0176         if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
0177             acpi_gbl_optarg =
0178                 &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
0179         } else {
0180             ACPI_OPTION_ERROR
0181                 ("Option requires a single-character suboption: -",
0182                  current_char);
0183 
0184             current_char_ptr = 1;
0185             return ('?');
0186         }
0187 
0188         acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
0189         acpi_gbl_optind++;
0190         current_char_ptr = 1;
0191     }
0192 
0193     /* Option with no arguments */
0194 
0195     else {
0196         if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
0197             current_char_ptr = 1;
0198             acpi_gbl_optind++;
0199         }
0200 
0201         acpi_gbl_optarg = NULL;
0202     }
0203 
0204     return (current_char);
0205 }