xref: /freebsd/sys/contrib/dev/acpica/common/getopt.c (revision e14ddd1f16e7e5788392c50de21ea7c927e0690c)
1 /******************************************************************************
2  *
3  * Module Name: getopt
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 
45 #include <stdio.h>
46 #include <string.h>
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/acapps.h>
50 
51 #define ACPI_OPTION_ERROR(msg, badchar) \
52     if (AcpiGbl_Opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
53 
54 
55 int   AcpiGbl_Opterr = 1;
56 int   AcpiGbl_Optind = 1;
57 char  *AcpiGbl_Optarg;
58 
59 
60 /*******************************************************************************
61  *
62  * FUNCTION:    AcpiGetopt
63  *
64  * PARAMETERS:  argc, argv          - from main
65  *              opts                - options info list
66  *
67  * RETURN:      Option character or EOF
68  *
69  * DESCRIPTION: Get the next option
70  *
71  ******************************************************************************/
72 
73 int
74 AcpiGetopt(
75     int                     argc,
76     char                    **argv,
77     char                    *opts)
78 {
79     static int              CurrentCharPtr = 1;
80     int                     CurrentChar;
81     char                    *OptsPtr;
82 
83 
84     if (CurrentCharPtr == 1)
85     {
86         if (AcpiGbl_Optind >= argc ||
87             argv[AcpiGbl_Optind][0] != '-' ||
88             argv[AcpiGbl_Optind][1] == '\0')
89         {
90             return (EOF);
91         }
92         else if (strcmp (argv[AcpiGbl_Optind], "--") == 0)
93         {
94             AcpiGbl_Optind++;
95             return (EOF);
96         }
97     }
98 
99     /* Get the option */
100 
101     CurrentChar = argv[AcpiGbl_Optind][CurrentCharPtr];
102 
103     /* Make sure that the option is legal */
104 
105     if (CurrentChar == ':' ||
106        (OptsPtr = strchr (opts, CurrentChar)) == NULL)
107     {
108         ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar);
109 
110         if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
111         {
112             AcpiGbl_Optind++;
113             CurrentCharPtr = 1;
114         }
115 
116         return ('?');
117     }
118 
119     /* Option requires an argument? */
120 
121     if (*++OptsPtr == ':')
122     {
123         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
124         {
125             AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)];
126         }
127         else if (++AcpiGbl_Optind >= argc)
128         {
129             ACPI_OPTION_ERROR ("Option requires an argument: -", CurrentChar);
130 
131             CurrentCharPtr = 1;
132             return ('?');
133         }
134         else
135         {
136             AcpiGbl_Optarg = argv[AcpiGbl_Optind++];
137         }
138 
139         CurrentCharPtr = 1;
140     }
141 
142     /* Option has optional single-char arguments? */
143 
144     else if (*OptsPtr == '^')
145     {
146         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
147         {
148             AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
149         }
150         else
151         {
152             AcpiGbl_Optarg = "^";
153         }
154 
155         AcpiGbl_Optind++;
156         CurrentCharPtr = 1;
157     }
158 
159     /* Option has a required single-char argument? */
160 
161     else if (*OptsPtr == '|')
162     {
163         if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0')
164         {
165             AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)];
166         }
167         else
168         {
169             ACPI_OPTION_ERROR ("Option requires a single-character suboption: -", CurrentChar);
170 
171             CurrentCharPtr = 1;
172             return ('?');
173         }
174 
175         AcpiGbl_Optind++;
176         CurrentCharPtr = 1;
177     }
178 
179     /* Option with no arguments */
180 
181     else
182     {
183         if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0')
184         {
185             CurrentCharPtr = 1;
186             AcpiGbl_Optind++;
187         }
188 
189         AcpiGbl_Optarg = NULL;
190     }
191 
192     return (CurrentChar);
193 }
194