1 /****************************************************************************** 2 * 3 * Module Name: getopt 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 } 240