linux/tools/power/acpi/common/getopt.c
<<
>>
Prefs
   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
  62int acpi_gbl_opterr = 1;
  63int acpi_gbl_optind = 1;
  64int acpi_gbl_sub_opt_char = 0;
  65char *acpi_gbl_optarg;
  66
  67static 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
  87int 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
 122int 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