1118613Snjl/******************************************************************************
2118613Snjl *
3118613Snjl * Module Name: getopt
4118613Snjl *
5118613Snjl *****************************************************************************/
6118613Snjl
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9118613Snjl * All rights reserved.
10118613Snjl *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25118613Snjl *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29118613Snjl *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43118613Snjl
44250838Sjkim/*
45250838Sjkim * ACPICA getopt() implementation
46250838Sjkim *
47250838Sjkim * Option strings:
48250838Sjkim *    "f"       - Option has no arguments
49250838Sjkim *    "f:"      - Option requires an argument
50306536Sjkim *    "f+"      - Option has an optional argument
51250838Sjkim *    "f^"      - Option has optional single-char sub-options
52250838Sjkim *    "f|"      - Option has required single-char sub-options
53250838Sjkim */
54118613Snjl
55193529Sjkim#include <contrib/dev/acpica/include/acpi.h>
56193529Sjkim#include <contrib/dev/acpica/include/accommon.h>
57193529Sjkim#include <contrib/dev/acpica/include/acapps.h>
58118613Snjl
59233250Sjkim#define ACPI_OPTION_ERROR(msg, badchar) \
60281075Sdim    if (AcpiGbl_Opterr) {AcpiLogError ("%s%c\n", msg, badchar);}
61118613Snjl
62118613Snjl
63250838Sjkimint                 AcpiGbl_Opterr = 1;
64250838Sjkimint                 AcpiGbl_Optind = 1;
65250838Sjkimint                 AcpiGbl_SubOptChar = 0;
66250838Sjkimchar                *AcpiGbl_Optarg;
67118613Snjl
68250838Sjkimstatic int          CurrentCharPtr = 1;
69118613Snjl
70250838Sjkim
71118613Snjl/*******************************************************************************
72118613Snjl *
73250838Sjkim * FUNCTION:    AcpiGetoptArgument
74250838Sjkim *
75250838Sjkim * PARAMETERS:  argc, argv          - from main
76250838Sjkim *
77250838Sjkim * RETURN:      0 if an argument was found, -1 otherwise. Sets AcpiGbl_Optarg
78250838Sjkim *              to point to the next argument.
79250838Sjkim *
80250838Sjkim * DESCRIPTION: Get the next argument. Used to obtain arguments for the
81250838Sjkim *              two-character options after the original call to AcpiGetopt.
82250838Sjkim *              Note: Either the argument starts at the next character after
83250838Sjkim *              the option, or it is pointed to by the next argv entry.
84250838Sjkim *              (After call to AcpiGetopt, we need to backup to the previous
85250838Sjkim *              argv entry).
86250838Sjkim *
87250838Sjkim ******************************************************************************/
88250838Sjkim
89250838Sjkimint
90250838SjkimAcpiGetoptArgument (
91250838Sjkim    int                     argc,
92250838Sjkim    char                    **argv)
93250838Sjkim{
94306536Sjkim
95250838Sjkim    AcpiGbl_Optind--;
96250838Sjkim    CurrentCharPtr++;
97250838Sjkim
98250838Sjkim    if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
99250838Sjkim    {
100250838Sjkim        AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
101250838Sjkim    }
102250838Sjkim    else if (++AcpiGbl_Optind >= argc)
103250838Sjkim    {
104250838Sjkim        ACPI_OPTION_ERROR ("Option requires an argument: -", 'v');
105250838Sjkim
106250838Sjkim        CurrentCharPtr = 1;
107250838Sjkim        return (-1);
108250838Sjkim    }
109250838Sjkim    else
110250838Sjkim    {
111250838Sjkim        AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
112250838Sjkim    }
113250838Sjkim
114250838Sjkim    CurrentCharPtr = 1;
115250838Sjkim    return (0);
116250838Sjkim}
117250838Sjkim
118250838Sjkim
119250838Sjkim/*******************************************************************************
120250838Sjkim *
121118613Snjl * FUNCTION:    AcpiGetopt
122118613Snjl *
123118613Snjl * PARAMETERS:  argc, argv          - from main
124118613Snjl *              opts                - options info list
125118613Snjl *
126281075Sdim * RETURN:      Option character or ACPI_OPT_END
127118613Snjl *
128118613Snjl * DESCRIPTION: Get the next option
129118613Snjl *
130118613Snjl ******************************************************************************/
131118613Snjl
132118613Snjlint
133118613SnjlAcpiGetopt(
134118613Snjl    int                     argc,
135118613Snjl    char                    **argv,
136118613Snjl    char                    *opts)
137118613Snjl{
138118613Snjl    int                     CurrentChar;
139118613Snjl    char                    *OptsPtr;
140118613Snjl
141118613Snjl
142118613Snjl    if (CurrentCharPtr == 1)
143118613Snjl    {
144118613Snjl        if (AcpiGbl_Optind >= argc ||
145118613Snjl            argv[AcpiGbl_Optind][0] != '-' ||
146118613Snjl            argv[AcpiGbl_Optind][1] == '\0')
147118613Snjl        {
148281075Sdim            return (ACPI_OPT_END);
149118613Snjl        }
150306536Sjkim        else if (strcmp (argv[AcpiGbl_Optind], "--") == 0)
151118613Snjl        {
152118613Snjl            AcpiGbl_Optind++;
153281075Sdim            return (ACPI_OPT_END);
154118613Snjl        }
155118613Snjl    }
156118613Snjl
157118613Snjl    /* Get the option */
158118613Snjl
159212761Sjkim    CurrentChar = argv[AcpiGbl_Optind][CurrentCharPtr];
160118613Snjl
161118613Snjl    /* Make sure that the option is legal */
162118613Snjl
163118613Snjl    if (CurrentChar == ':' ||
164306536Sjkim       (OptsPtr = strchr (opts, CurrentChar)) == NULL)
165118613Snjl    {
166233250Sjkim        ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar);
167118613Snjl
168118613Snjl        if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
169118613Snjl        {
170118613Snjl            AcpiGbl_Optind++;
171118613Snjl            CurrentCharPtr = 1;
172118613Snjl        }
173118613Snjl
174118613Snjl        return ('?');
175118613Snjl    }
176118613Snjl
177118613Snjl    /* Option requires an argument? */
178118613Snjl
179118613Snjl    if (*++OptsPtr == ':')
180118613Snjl    {
181198237Sjkim        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
182118613Snjl        {
183198237Sjkim            AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
184118613Snjl        }
185118613Snjl        else if (++AcpiGbl_Optind >= argc)
186118613Snjl        {
187306536Sjkim            ACPI_OPTION_ERROR (
188306536Sjkim                "Option requires an argument: -", CurrentChar);
189118613Snjl
190118613Snjl            CurrentCharPtr = 1;
191118613Snjl            return ('?');
192118613Snjl        }
193118613Snjl        else
194118613Snjl        {
195118613Snjl            AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
196118613Snjl        }
197118613Snjl
198118613Snjl        CurrentCharPtr = 1;
199118613Snjl    }
200118613Snjl
201253690Sjkim    /* Option has an optional argument? */
202253690Sjkim
203253690Sjkim    else if (*OptsPtr == '+')
204253690Sjkim    {
205253690Sjkim        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
206253690Sjkim        {
207253690Sjkim            AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
208253690Sjkim        }
209253690Sjkim        else if (++AcpiGbl_Optind >= argc)
210253690Sjkim        {
211253690Sjkim            AcpiGbl_Optarg = NULL;
212253690Sjkim        }
213253690Sjkim        else
214253690Sjkim        {
215253690Sjkim            AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
216253690Sjkim        }
217253690Sjkim
218253690Sjkim        CurrentCharPtr = 1;
219253690Sjkim    }
220253690Sjkim
221118613Snjl    /* Option has optional single-char arguments? */
222118613Snjl
223118613Snjl    else if (*OptsPtr == '^')
224118613Snjl    {
225198237Sjkim        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
226118613Snjl        {
227198237Sjkim            AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
228118613Snjl        }
229118613Snjl        else
230118613Snjl        {
231118613Snjl            AcpiGbl_Optarg = "^";
232118613Snjl        }
233118613Snjl
234250838Sjkim        AcpiGbl_SubOptChar = AcpiGbl_Optarg[0];
235118613Snjl        AcpiGbl_Optind++;
236118613Snjl        CurrentCharPtr = 1;
237118613Snjl    }
238118613Snjl
239233250Sjkim    /* Option has a required single-char argument? */
240233250Sjkim
241233250Sjkim    else if (*OptsPtr == '|')
242233250Sjkim    {
243233250Sjkim        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
244233250Sjkim        {
245233250Sjkim            AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
246233250Sjkim        }
247233250Sjkim        else
248233250Sjkim        {
249306536Sjkim            ACPI_OPTION_ERROR (
250306536Sjkim                "Option requires a single-character suboption: -",
251306536Sjkim                CurrentChar);
252233250Sjkim
253233250Sjkim            CurrentCharPtr = 1;
254233250Sjkim            return ('?');
255233250Sjkim        }
256233250Sjkim
257250838Sjkim        AcpiGbl_SubOptChar = AcpiGbl_Optarg[0];
258233250Sjkim        AcpiGbl_Optind++;
259233250Sjkim        CurrentCharPtr = 1;
260233250Sjkim    }
261233250Sjkim
262118613Snjl    /* Option with no arguments */
263118613Snjl
264118613Snjl    else
265118613Snjl    {
266118613Snjl        if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
267118613Snjl        {
268118613Snjl            CurrentCharPtr = 1;
269118613Snjl            AcpiGbl_Optind++;
270118613Snjl        }
271118613Snjl
272118613Snjl        AcpiGbl_Optarg = NULL;
273118613Snjl    }
274118613Snjl
275118613Snjl    return (CurrentChar);
276118613Snjl}
277