getopt.c revision 281075
11638Srgrimes/******************************************************************************
21638Srgrimes *
31638Srgrimes * Module Name: getopt
41638Srgrimes *
51638Srgrimes *****************************************************************************/
61638Srgrimes
71638Srgrimes/*
81638Srgrimes * Copyright (C) 2000 - 2015, Intel Corp.
91638Srgrimes * All rights reserved.
101638Srgrimes *
111638Srgrimes * Redistribution and use in source and binary forms, with or without
121638Srgrimes * modification, are permitted provided that the following conditions
131638Srgrimes * are met:
141638Srgrimes * 1. Redistributions of source code must retain the above copyright
151638Srgrimes *    notice, this list of conditions, and the following disclaimer,
161638Srgrimes *    without modification.
171638Srgrimes * 2. Redistributions in binary form must reproduce at minimum a disclaimer
181638Srgrimes *    substantially similar to the "NO WARRANTY" disclaimer below
191638Srgrimes *    ("Disclaimer") and any redistribution must be conditioned upon
201638Srgrimes *    including a substantially similar Disclaimer requirement for further
211638Srgrimes *    binary redistribution.
221638Srgrimes * 3. Neither the names of the above-listed copyright holders nor the names
231638Srgrimes *    of any contributors may be used to endorse or promote products derived
241638Srgrimes *    from this software without specific prior written permission.
251638Srgrimes *
261638Srgrimes * Alternatively, this software may be distributed under the terms of the
271638Srgrimes * GNU General Public License ("GPL") version 2 as published by the Free
281638Srgrimes * Software Foundation.
291638Srgrimes *
301638Srgrimes * NO WARRANTY
311638Srgrimes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
321638Srgrimes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3350476Speter * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
341638Srgrimes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35264589Sbrueffer * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
361638Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3779538Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
381638Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
391638Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40107788Sru * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
411638Srgrimes * POSSIBILITY OF SUCH DAMAGES.
4284306Sru */
431638Srgrimes
441638Srgrimes/*
4568962Sru * ACPICA getopt() implementation
461638Srgrimes *
471638Srgrimes * Option strings:
4868962Sru *    "f"       - Option has no arguments
491638Srgrimes *    "f:"      - Option requires an argument
5079727Sschweikh *    "f^"      - Option has optional single-char sub-options
511638Srgrimes *    "f|"      - Option has required single-char sub-options
52107788Sru */
531638Srgrimes
541638Srgrimes#include <contrib/dev/acpica/include/acpi.h>
5568962Sru#include <contrib/dev/acpica/include/accommon.h>
561638Srgrimes#include <contrib/dev/acpica/include/acapps.h>
571638Srgrimes
581638Srgrimes#define ACPI_OPTION_ERROR(msg, badchar) \
591638Srgrimes    if (AcpiGbl_Opterr) {AcpiLogError ("%s%c\n", msg, badchar);}
601638Srgrimes
611638Srgrimes
6268962Sruint                 AcpiGbl_Opterr = 1;
631638Srgrimesint                 AcpiGbl_Optind = 1;
641638Srgrimesint                 AcpiGbl_SubOptChar = 0;
651638Srgrimeschar                *AcpiGbl_Optarg;
661638Srgrimes
67176184Smppstatic int          CurrentCharPtr = 1;
68107788Sru
69241440Sstefanf
70241440Sstefanf/*******************************************************************************
71241440Sstefanf *
72241440Sstefanf * FUNCTION:    AcpiGetoptArgument
73241440Sstefanf *
741638Srgrimes * PARAMETERS:  argc, argv          - from main
751638Srgrimes *
761638Srgrimes * RETURN:      0 if an argument was found, -1 otherwise. Sets AcpiGbl_Optarg
77107788Sru *              to point to the next argument.
78222841Sdelphij *
79222841Sdelphij * DESCRIPTION: Get the next argument. Used to obtain arguments for the
80241440Sstefanf *              two-character options after the original call to AcpiGetopt.
81241440Sstefanf *              Note: Either the argument starts at the next character after
82241440Sstefanf *              the option, or it is pointed to by the next argv entry.
831638Srgrimes *              (After call to AcpiGetopt, we need to backup to the previous
841638Srgrimes *              argv entry).
851638Srgrimes *
86107788Sru ******************************************************************************/
87107788Sru
88107788Sruint
8979727SschweikhAcpiGetoptArgument (
9016952Swosch    int                     argc,
91131530Sru    char                    **argv)
92191994Simp{
93131530Sru    AcpiGbl_Optind--;
94107788Sru    CurrentCharPtr++;
951638Srgrimes
961638Srgrimes    if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
971638Srgrimes    {
98107788Sru        AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
991638Srgrimes    }
1001638Srgrimes    else if (++AcpiGbl_Optind >= argc)
1011638Srgrimes    {
102185217Skeramida        ACPI_OPTION_ERROR ("Option requires an argument: -", 'v');
103131530Sru
10447557Sghelmer        CurrentCharPtr = 1;
10547557Sghelmer        return (-1);
10647557Sghelmer    }
107107788Sru    else
10847557Sghelmer    {
10947557Sghelmer        AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
110185217Skeramida    }
111185217Skeramida
112185217Skeramida    CurrentCharPtr = 1;
113185217Skeramida    return (0);
114185217Skeramida}
115185217Skeramida
116185217Skeramida
117185217Skeramida/*******************************************************************************
118185217Skeramida *
119185217Skeramida * FUNCTION:    AcpiGetopt
120185217Skeramida *
121185217Skeramida * PARAMETERS:  argc, argv          - from main
122185217Skeramida *              opts                - options info list
123185217Skeramida *
124185217Skeramida * RETURN:      Option character or ACPI_OPT_END
125185217Skeramida *
126185217Skeramida * DESCRIPTION: Get the next option
127185217Skeramida *
1281638Srgrimes ******************************************************************************/
129185217Skeramida
130185217Skeramidaint
131185217SkeramidaAcpiGetopt(
132185217Skeramida    int                     argc,
133185217Skeramida    char                    **argv,
134185217Skeramida    char                    *opts)
135185217Skeramida{
136185217Skeramida    int                     CurrentChar;
137222841Sdelphij    char                    *OptsPtr;
138222841Sdelphij
139222841Sdelphij
140222841Sdelphij    if (CurrentCharPtr == 1)
141222841Sdelphij    {
142107788Sru        if (AcpiGbl_Optind >= argc ||
1431638Srgrimes            argv[AcpiGbl_Optind][0] != '-' ||
1441638Srgrimes            argv[AcpiGbl_Optind][1] == '\0')
1451638Srgrimes        {
1461638Srgrimes            return (ACPI_OPT_END);
147107788Sru        }
1481638Srgrimes        else if (ACPI_STRCMP (argv[AcpiGbl_Optind], "--") == 0)
1491638Srgrimes        {
1501638Srgrimes            AcpiGbl_Optind++;
151107788Sru            return (ACPI_OPT_END);
1521638Srgrimes        }
1531638Srgrimes    }
1541638Srgrimes
1551638Srgrimes    /* Get the option */
1561638Srgrimes
1571638Srgrimes    CurrentChar = argv[AcpiGbl_Optind][CurrentCharPtr];
1581638Srgrimes
1591638Srgrimes    /* Make sure that the option is legal */
1601638Srgrimes
1611638Srgrimes    if (CurrentChar == ':' ||
1621638Srgrimes       (OptsPtr = ACPI_STRCHR (opts, CurrentChar)) == NULL)
163222841Sdelphij    {
164222841Sdelphij        ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar);
165222841Sdelphij
166222832Sdelphij        if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
167222832Sdelphij        {
168222832Sdelphij            AcpiGbl_Optind++;
169222832Sdelphij            CurrentCharPtr = 1;
170222832Sdelphij        }
171222832Sdelphij
172222841Sdelphij        return ('?');
173222841Sdelphij    }
174222841Sdelphij
17510290Sdg    /* Option requires an argument? */
176107788Sru
17788677Ssheldonh    if (*++OptsPtr == ':')
178131530Sru    {
17988677Ssheldonh        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
18088677Ssheldonh        {
18188677Ssheldonh            AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
18289153Sru        }
18388677Ssheldonh        else if (++AcpiGbl_Optind >= argc)
18488677Ssheldonh        {
18588303Ssheldonh            ACPI_OPTION_ERROR ("Option requires an argument: -", CurrentChar);
186107788Sru
18710290Sdg            CurrentCharPtr = 1;
188252310Shrs            return ('?');
189252310Shrs        }
190252310Shrs        else
191252310Shrs        {
192252310Shrs            AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
193252310Shrs        }
194252310Shrs
195252310Shrs        CurrentCharPtr = 1;
196252310Shrs    }
1971638Srgrimes
1981638Srgrimes    /* Option has an optional argument? */
1991638Srgrimes
2001638Srgrimes    else if (*OptsPtr == '+')
2011638Srgrimes    {
2021638Srgrimes        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
2031638Srgrimes        {
2041638Srgrimes            AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
2051638Srgrimes        }
206222841Sdelphij        else if (++AcpiGbl_Optind >= argc)
207222841Sdelphij        {
208222841Sdelphij            AcpiGbl_Optarg = NULL;
209222841Sdelphij        }
210222841Sdelphij        else
2111638Srgrimes        {
2121638Srgrimes            AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
2131638Srgrimes        }
214252310Shrs
2151638Srgrimes        CurrentCharPtr = 1;
2161638Srgrimes    }
217222841Sdelphij
218222841Sdelphij    /* Option has optional single-char arguments? */
219222841Sdelphij
2201638Srgrimes    else if (*OptsPtr == '^')
2211638Srgrimes    {
2221638Srgrimes        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
223252310Shrs        {
224252310Shrs            AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
225252310Shrs        }
226252310Shrs        else
227252310Shrs        {
228252310Shrs            AcpiGbl_Optarg = "^";
229252310Shrs        }
230252310Shrs
231252310Shrs        AcpiGbl_SubOptChar = AcpiGbl_Optarg[0];
232252310Shrs        AcpiGbl_Optind++;
233252310Shrs        CurrentCharPtr = 1;
234252379Sjoel    }
235252310Shrs
236252310Shrs    /* Option has a required single-char argument? */
237252310Shrs
238252310Shrs    else if (*OptsPtr == '|')
239252310Shrs    {
240252310Shrs        if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
241252310Shrs        {
242253349Shrs            AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
243253349Shrs        }
244253349Shrs        else
245253349Shrs        {
246253349Shrs            ACPI_OPTION_ERROR ("Option requires a single-character suboption: -", CurrentChar);
247253349Shrs
248264589Sbrueffer            CurrentCharPtr = 1;
249253349Shrs            return ('?');
250253349Shrs        }
251253349Shrs
252253349Shrs        AcpiGbl_SubOptChar = AcpiGbl_Optarg[0];
253253349Shrs        AcpiGbl_Optind++;
2541638Srgrimes        CurrentCharPtr = 1;
2551638Srgrimes    }
2561638Srgrimes
2571638Srgrimes    /* Option with no arguments */
2581638Srgrimes
2591638Srgrimes    else
2601638Srgrimes    {
261222841Sdelphij        if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
262222841Sdelphij        {
263222841Sdelphij            CurrentCharPtr = 1;
2641638Srgrimes            AcpiGbl_Optind++;
2651638Srgrimes        }
2661638Srgrimes
2671638Srgrimes        AcpiGbl_Optarg = NULL;
268107788Sru    }
2691638Srgrimes
270107788Sru    return (CurrentChar);
2711638Srgrimes}
27215135Smpp