GNU Linux-libre 4.9.306-gnu1
[releases.git] / tools / power / acpi / common / getopt.c
1 /******************************************************************************
2  *
3  * Module Name: getopt
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2016, 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  * ACPICA getopt() implementation
46  *
47  * Option strings:
48  *    "f"       - Option has no arguments
49  *    "f:"      - Option requires an argument
50  *    "f+"      - Option has an optional argument
51  *    "f^"      - Option has optional single-char sub-options
52  *    "f|"      - Option has required single-char sub-options
53  */
54
55 #include <acpi/acpi.h>
56 #include "accommon.h"
57 #include "acapps.h"
58
59 #define ACPI_OPTION_ERROR(msg, badchar) \
60         if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
61
62 int acpi_gbl_opterr = 1;
63 int acpi_gbl_optind = 1;
64 int acpi_gbl_sub_opt_char = 0;
65 char *acpi_gbl_optarg;
66
67 static int current_char_ptr = 1;
68
69 /*******************************************************************************
70  *
71  * FUNCTION:    acpi_getopt_argument
72  *
73  * PARAMETERS:  argc, argv          - from main
74  *
75  * RETURN:      0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
76  *              to point to the next argument.
77  *
78  * DESCRIPTION: Get the next argument. Used to obtain arguments for the
79  *              two-character options after the original call to acpi_getopt.
80  *              Note: Either the argument starts at the next character after
81  *              the option, or it is pointed to by the next argv entry.
82  *              (After call to acpi_getopt, we need to backup to the previous
83  *              argv entry).
84  *
85  ******************************************************************************/
86
87 int acpi_getopt_argument(int argc, char **argv)
88 {
89
90         acpi_gbl_optind--;
91         current_char_ptr++;
92
93         if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
94                 acpi_gbl_optarg =
95                     &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
96         } else if (++acpi_gbl_optind >= argc) {
97                 ACPI_OPTION_ERROR("\nOption requires an argument", 0);
98
99                 current_char_ptr = 1;
100                 return (-1);
101         } else {
102                 acpi_gbl_optarg = argv[acpi_gbl_optind++];
103         }
104
105         current_char_ptr = 1;
106         return (0);
107 }
108
109 /*******************************************************************************
110  *
111  * FUNCTION:    acpi_getopt
112  *
113  * PARAMETERS:  argc, argv          - from main
114  *              opts                - options info list
115  *
116  * RETURN:      Option character or ACPI_OPT_END
117  *
118  * DESCRIPTION: Get the next option
119  *
120  ******************************************************************************/
121
122 int acpi_getopt(int argc, char **argv, char *opts)
123 {
124         int current_char;
125         char *opts_ptr;
126
127         if (current_char_ptr == 1) {
128                 if (acpi_gbl_optind >= argc ||
129                     argv[acpi_gbl_optind][0] != '-' ||
130                     argv[acpi_gbl_optind][1] == '\0') {
131                         return (ACPI_OPT_END);
132                 } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
133                         acpi_gbl_optind++;
134                         return (ACPI_OPT_END);
135                 }
136         }
137
138         /* Get the option */
139
140         current_char = argv[acpi_gbl_optind][current_char_ptr];
141
142         /* Make sure that the option is legal */
143
144         if (current_char == ':' ||
145             (opts_ptr = strchr(opts, current_char)) == NULL) {
146                 ACPI_OPTION_ERROR("Illegal option: -", current_char);
147
148                 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
149                         acpi_gbl_optind++;
150                         current_char_ptr = 1;
151                 }
152
153                 return ('?');
154         }
155
156         /* Option requires an argument? */
157
158         if (*++opts_ptr == ':') {
159                 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
160                         acpi_gbl_optarg =
161                             &argv[acpi_gbl_optind++][(int)
162                                                      (current_char_ptr + 1)];
163                 } else if (++acpi_gbl_optind >= argc) {
164                         ACPI_OPTION_ERROR("Option requires an argument: -",
165                                           current_char);
166
167                         current_char_ptr = 1;
168                         return ('?');
169                 } else {
170                         acpi_gbl_optarg = argv[acpi_gbl_optind++];
171                 }
172
173                 current_char_ptr = 1;
174         }
175
176         /* Option has an optional argument? */
177
178         else if (*opts_ptr == '+') {
179                 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
180                         acpi_gbl_optarg =
181                             &argv[acpi_gbl_optind++][(int)
182                                                      (current_char_ptr + 1)];
183                 } else if (++acpi_gbl_optind >= argc) {
184                         acpi_gbl_optarg = NULL;
185                 } else {
186                         acpi_gbl_optarg = argv[acpi_gbl_optind++];
187                 }
188
189                 current_char_ptr = 1;
190         }
191
192         /* Option has optional single-char arguments? */
193
194         else if (*opts_ptr == '^') {
195                 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
196                         acpi_gbl_optarg =
197                             &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
198                 } else {
199                         acpi_gbl_optarg = "^";
200                 }
201
202                 acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
203                 acpi_gbl_optind++;
204                 current_char_ptr = 1;
205         }
206
207         /* Option has a required single-char argument? */
208
209         else if (*opts_ptr == '|') {
210                 if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
211                         acpi_gbl_optarg =
212                             &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
213                 } else {
214                         ACPI_OPTION_ERROR
215                             ("Option requires a single-character suboption: -",
216                              current_char);
217
218                         current_char_ptr = 1;
219                         return ('?');
220                 }
221
222                 acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
223                 acpi_gbl_optind++;
224                 current_char_ptr = 1;
225         }
226
227         /* Option with no arguments */
228
229         else {
230                 if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
231                         current_char_ptr = 1;
232                         acpi_gbl_optind++;
233                 }
234
235                 acpi_gbl_optarg = NULL;
236         }
237
238         return (current_char);
239 }