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