xref: /netbsd-src/sys/external/bsd/acpica/dist/common/getopt.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: getopt
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
44ff4a156dSchristos /*
45ff4a156dSchristos  * ACPICA getopt() implementation
46ff4a156dSchristos  *
47ff4a156dSchristos  * Option strings:
48ff4a156dSchristos  *    "f"       - Option has no arguments
49ff4a156dSchristos  *    "f:"      - Option requires an argument
5071e38f1dSchristos  *    "f+"      - Option has an optional argument
51ff4a156dSchristos  *    "f^"      - Option has optional single-char sub-options
52ff4a156dSchristos  *    "f|"      - Option has required single-char sub-options
53ff4a156dSchristos  */
5428c506b8Sjruoho 
5528c506b8Sjruoho #include "acpi.h"
5628c506b8Sjruoho #include "accommon.h"
5728c506b8Sjruoho #include "acapps.h"
5828c506b8Sjruoho 
59ff4a156dSchristos #define ACPI_OPTION_ERROR(msg, badchar) \
60d0e1da26Schristos     if (AcpiGbl_Opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
6128c506b8Sjruoho 
6228c506b8Sjruoho 
6328c506b8Sjruoho int                 AcpiGbl_Opterr = 1;
6428c506b8Sjruoho int                 AcpiGbl_Optind = 1;
65ff4a156dSchristos int                 AcpiGbl_SubOptChar = 0;
6628c506b8Sjruoho char                *AcpiGbl_Optarg;
6728c506b8Sjruoho 
68ff4a156dSchristos static int          CurrentCharPtr = 1;
69ff4a156dSchristos 
70ff4a156dSchristos 
71ff4a156dSchristos /*******************************************************************************
72ff4a156dSchristos  *
73ff4a156dSchristos  * FUNCTION:    AcpiGetoptArgument
74ff4a156dSchristos  *
75ff4a156dSchristos  * PARAMETERS:  argc, argv          - from main
76ff4a156dSchristos  *
77ff4a156dSchristos  * RETURN:      0 if an argument was found, -1 otherwise. Sets AcpiGbl_Optarg
78ff4a156dSchristos  *              to point to the next argument.
79ff4a156dSchristos  *
80ff4a156dSchristos  * DESCRIPTION: Get the next argument. Used to obtain arguments for the
81ff4a156dSchristos  *              two-character options after the original call to AcpiGetopt.
82ff4a156dSchristos  *              Note: Either the argument starts at the next character after
83ff4a156dSchristos  *              the option, or it is pointed to by the next argv entry.
84ff4a156dSchristos  *              (After call to AcpiGetopt, we need to backup to the previous
85ff4a156dSchristos  *              argv entry).
86ff4a156dSchristos  *
87ff4a156dSchristos  ******************************************************************************/
88ff4a156dSchristos 
89ff4a156dSchristos int
AcpiGetoptArgument(int argc,char ** argv)90ff4a156dSchristos AcpiGetoptArgument (
91ff4a156dSchristos     int                     argc,
92ff4a156dSchristos     char                    **argv)
93ff4a156dSchristos {
9471e38f1dSchristos 
95ff4a156dSchristos     AcpiGbl_Optind--;
96ff4a156dSchristos     CurrentCharPtr++;
97ff4a156dSchristos 
98ff4a156dSchristos     if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
99ff4a156dSchristos     {
100ff4a156dSchristos         AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
101ff4a156dSchristos     }
102ff4a156dSchristos     else if (++AcpiGbl_Optind >= argc)
103ff4a156dSchristos     {
104d0e1da26Schristos         ACPI_OPTION_ERROR ("\nOption requires an argument", 0);
105ff4a156dSchristos 
106ff4a156dSchristos         CurrentCharPtr = 1;
107ff4a156dSchristos         return (-1);
108ff4a156dSchristos     }
109ff4a156dSchristos     else
110ff4a156dSchristos     {
111ff4a156dSchristos         AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
112ff4a156dSchristos     }
113ff4a156dSchristos 
114ff4a156dSchristos     CurrentCharPtr = 1;
115ff4a156dSchristos     return (0);
116ff4a156dSchristos }
117ff4a156dSchristos 
11828c506b8Sjruoho 
11928c506b8Sjruoho /*******************************************************************************
12028c506b8Sjruoho  *
12128c506b8Sjruoho  * FUNCTION:    AcpiGetopt
12228c506b8Sjruoho  *
12328c506b8Sjruoho  * PARAMETERS:  argc, argv          - from main
12428c506b8Sjruoho  *              opts                - options info list
12528c506b8Sjruoho  *
126460301d4Schristos  * RETURN:      Option character or ACPI_OPT_END
12728c506b8Sjruoho  *
12828c506b8Sjruoho  * DESCRIPTION: Get the next option
12928c506b8Sjruoho  *
13028c506b8Sjruoho  ******************************************************************************/
13128c506b8Sjruoho 
13228c506b8Sjruoho int
AcpiGetopt(int argc,char ** argv,char * opts)13328c506b8Sjruoho AcpiGetopt(
13428c506b8Sjruoho     int                     argc,
13528c506b8Sjruoho     char                    **argv,
13628c506b8Sjruoho     char                    *opts)
13728c506b8Sjruoho {
13828c506b8Sjruoho     int                     CurrentChar;
13928c506b8Sjruoho     char                    *OptsPtr;
14028c506b8Sjruoho 
14128c506b8Sjruoho 
14228c506b8Sjruoho     if (CurrentCharPtr == 1)
14328c506b8Sjruoho     {
14428c506b8Sjruoho         if (AcpiGbl_Optind >= argc ||
14528c506b8Sjruoho             argv[AcpiGbl_Optind][0] != '-' ||
14628c506b8Sjruoho             argv[AcpiGbl_Optind][1] == '\0')
14728c506b8Sjruoho         {
148460301d4Schristos             return (ACPI_OPT_END);
14928c506b8Sjruoho         }
150c72da027Schristos         else if (strcmp (argv[AcpiGbl_Optind], "--") == 0)
15128c506b8Sjruoho         {
15228c506b8Sjruoho             AcpiGbl_Optind++;
153460301d4Schristos             return (ACPI_OPT_END);
15428c506b8Sjruoho         }
15528c506b8Sjruoho     }
15628c506b8Sjruoho 
15728c506b8Sjruoho     /* Get the option */
15828c506b8Sjruoho 
159124f4c82Sjruoho     CurrentChar = argv[AcpiGbl_Optind][CurrentCharPtr];
16028c506b8Sjruoho 
16128c506b8Sjruoho     /* Make sure that the option is legal */
16228c506b8Sjruoho 
16328c506b8Sjruoho     if (CurrentChar == ':' ||
164c72da027Schristos        (OptsPtr = strchr (opts, CurrentChar)) == NULL)
16528c506b8Sjruoho     {
166ff4a156dSchristos         ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar);
16728c506b8Sjruoho 
16828c506b8Sjruoho         if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
16928c506b8Sjruoho         {
17028c506b8Sjruoho             AcpiGbl_Optind++;
17128c506b8Sjruoho             CurrentCharPtr = 1;
17228c506b8Sjruoho         }
17328c506b8Sjruoho 
17428c506b8Sjruoho         return ('?');
17528c506b8Sjruoho     }
17628c506b8Sjruoho 
17728c506b8Sjruoho     /* Option requires an argument? */
17828c506b8Sjruoho 
17928c506b8Sjruoho     if (*++OptsPtr == ':')
18028c506b8Sjruoho     {
18128c506b8Sjruoho         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
18228c506b8Sjruoho         {
18328c506b8Sjruoho             AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
18428c506b8Sjruoho         }
18528c506b8Sjruoho         else if (++AcpiGbl_Optind >= argc)
18628c506b8Sjruoho         {
18771e38f1dSchristos             ACPI_OPTION_ERROR (
18871e38f1dSchristos                 "Option requires an argument: -", CurrentChar);
18928c506b8Sjruoho 
19028c506b8Sjruoho             CurrentCharPtr = 1;
19128c506b8Sjruoho             return ('?');
19228c506b8Sjruoho         }
19328c506b8Sjruoho         else
19428c506b8Sjruoho         {
19528c506b8Sjruoho             AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
19628c506b8Sjruoho         }
19728c506b8Sjruoho 
19828c506b8Sjruoho         CurrentCharPtr = 1;
19928c506b8Sjruoho     }
20028c506b8Sjruoho 
201ff4a156dSchristos     /* Option has an optional argument? */
202ff4a156dSchristos 
203ff4a156dSchristos     else if (*OptsPtr == '+')
204ff4a156dSchristos     {
205ff4a156dSchristos         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
206ff4a156dSchristos         {
207ff4a156dSchristos             AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
208ff4a156dSchristos         }
209ff4a156dSchristos         else if (++AcpiGbl_Optind >= argc)
210ff4a156dSchristos         {
211ff4a156dSchristos             AcpiGbl_Optarg = NULL;
212ff4a156dSchristos         }
213ff4a156dSchristos         else
214ff4a156dSchristos         {
215ff4a156dSchristos             AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
216ff4a156dSchristos         }
217ff4a156dSchristos 
218ff4a156dSchristos         CurrentCharPtr = 1;
219ff4a156dSchristos     }
220ff4a156dSchristos 
22128c506b8Sjruoho     /* Option has optional single-char arguments? */
22228c506b8Sjruoho 
22328c506b8Sjruoho     else if (*OptsPtr == '^')
22428c506b8Sjruoho     {
22528c506b8Sjruoho         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
22628c506b8Sjruoho         {
22728c506b8Sjruoho             AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
22828c506b8Sjruoho         }
22928c506b8Sjruoho         else
23028c506b8Sjruoho         {
23128c506b8Sjruoho             AcpiGbl_Optarg = "^";
23228c506b8Sjruoho         }
23328c506b8Sjruoho 
234ff4a156dSchristos         AcpiGbl_SubOptChar = AcpiGbl_Optarg[0];
235ff4a156dSchristos         AcpiGbl_Optind++;
236ff4a156dSchristos         CurrentCharPtr = 1;
237ff4a156dSchristos     }
238ff4a156dSchristos 
239ff4a156dSchristos     /* Option has a required single-char argument? */
240ff4a156dSchristos 
241ff4a156dSchristos     else if (*OptsPtr == '|')
242ff4a156dSchristos     {
243ff4a156dSchristos         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
244ff4a156dSchristos         {
245ff4a156dSchristos             AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
246ff4a156dSchristos         }
247ff4a156dSchristos         else
248ff4a156dSchristos         {
24971e38f1dSchristos             ACPI_OPTION_ERROR (
25071e38f1dSchristos                 "Option requires a single-character suboption: -",
25171e38f1dSchristos                 CurrentChar);
252ff4a156dSchristos 
253ff4a156dSchristos             CurrentCharPtr = 1;
254ff4a156dSchristos             return ('?');
255ff4a156dSchristos         }
256ff4a156dSchristos 
257ff4a156dSchristos         AcpiGbl_SubOptChar = AcpiGbl_Optarg[0];
25828c506b8Sjruoho         AcpiGbl_Optind++;
25928c506b8Sjruoho         CurrentCharPtr = 1;
26028c506b8Sjruoho     }
26128c506b8Sjruoho 
26228c506b8Sjruoho     /* Option with no arguments */
26328c506b8Sjruoho 
26428c506b8Sjruoho     else
26528c506b8Sjruoho     {
26628c506b8Sjruoho         if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
26728c506b8Sjruoho         {
26828c506b8Sjruoho             CurrentCharPtr = 1;
26928c506b8Sjruoho             AcpiGbl_Optind++;
27028c506b8Sjruoho         }
27128c506b8Sjruoho 
27228c506b8Sjruoho         AcpiGbl_Optarg = NULL;
27328c506b8Sjruoho     }
27428c506b8Sjruoho 
27528c506b8Sjruoho     return (CurrentChar);
27628c506b8Sjruoho }
277