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