ares_getopt.c (4166B)
1 /* 2 * Original file name getopt.c Initial import into the c-ares source tree 3 * on 2007-04-11. Lifted from version 5.2 of the 'Open Mash' project with 4 * the modified BSD license, BSD license without the advertising clause. 5 * 6 */ 7 8 /* 9 * getopt.c -- 10 * 11 * Standard UNIX getopt function. Code is from BSD. 12 * 13 * Copyright (c) 1987-2001 The Regents of the University of California. 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions are met: 18 * 19 * A. Redistributions of source code must retain the above copyright notice, 20 * this list of conditions and the following disclaimer. 21 * B. Redistributions in binary form must reproduce the above copyright notice, 22 * this list of conditions and the following disclaimer in the documentation 23 * and/or other materials provided with the distribution. 24 * C. Neither the names of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from this 26 * software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 29 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 30 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 * 40 * SPDX-License-Identifier: BSD-3-Clause 41 */ 42 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include "ares_getopt.h" 47 48 #define BADCH (int)'?' 49 #define BADARG (int)':' 50 #define EMSG "" 51 52 void ares_getopt_init(ares_getopt_state_t *state, int nargc, 53 const char * const *nargv) 54 { 55 memset(state, 0, sizeof(*state)); 56 state->opterr = 1; 57 state->optind = 1; 58 state->place = EMSG; 59 state->argc = nargc; 60 state->argv = nargv; 61 } 62 63 /* 64 * ares_getopt -- 65 * Parse argc/argv argument vector. 66 */ 67 int ares_getopt(ares_getopt_state_t *state, const char *ostr) 68 { 69 const char *oli; /* option letter list index */ 70 71 /* update scanning pointer */ 72 if (!*state->place) { 73 if (state->optind >= state->argc) { 74 return -1; 75 } 76 state->place = state->argv[state->optind]; 77 if (*(state->place) != '-') { 78 return -1; 79 } 80 state->place++; 81 82 /* found "--" */ 83 if (*(state->place) == '-') { 84 state->optind++; 85 return -1; 86 } 87 88 /* Found just - */ 89 if (!*(state->place)) { 90 state->optopt = 0; 91 return BADCH; 92 } 93 } 94 95 /* option letter okay? */ 96 state->optopt = *(state->place); 97 state->place++; 98 oli = strchr(ostr, state->optopt); 99 100 if (oli == NULL) { 101 if (!(*state->place)) { 102 ++state->optind; 103 } 104 if (state->opterr) { 105 (void)fprintf(stderr, "%s: illegal option -- %c\n", __FILE__, 106 state->optopt); 107 } 108 return BADCH; 109 } 110 111 /* don't need argument */ 112 if (*++oli != ':') { 113 state->optarg = NULL; 114 if (!*state->place) { 115 ++state->optind; 116 } 117 } else { 118 /* need an argument */ 119 if (*state->place) { /* no white space */ 120 state->optarg = state->place; 121 } else if (state->argc <= ++state->optind) { /* no arg */ 122 state->place = EMSG; 123 if (*ostr == ':') { 124 return BADARG; 125 } 126 if (state->opterr) { 127 (void)fprintf(stderr, "%s: option requires an argument -- %c\n", 128 __FILE__, state->optopt); 129 } 130 return BADARG; 131 } else { /* white space */ 132 state->optarg = state->argv[state->optind]; 133 } 134 state->place = EMSG; 135 ++state->optind; 136 } 137 return state->optopt; /* dump back option letter */ 138 }