1d4afb5ceSopenharmony_ci 2d4afb5ceSopenharmony_ci/* 3d4afb5ceSopenharmony_ci * Copyright (c) 1987, 1993, 1994, 1996 4d4afb5ceSopenharmony_ci * The Regents of the University of California. All rights reserved. 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Redistribution and use in source and binary forms, with or without 7d4afb5ceSopenharmony_ci * modification, are permitted provided that the following conditions 8d4afb5ceSopenharmony_ci * are met: 9d4afb5ceSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 10d4afb5ceSopenharmony_ci * notice, this list of conditions and the following disclaimer. 11d4afb5ceSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 12d4afb5ceSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 13d4afb5ceSopenharmony_ci * documentation and/or other materials provided with the distribution. 14d4afb5ceSopenharmony_ci * 3. All advertising materials mentioning features or use of this software 15d4afb5ceSopenharmony_ci * must display the following acknowledgement: 16d4afb5ceSopenharmony_ci * This product includes software developed by the University of 17d4afb5ceSopenharmony_ci * California, Berkeley and its contributors. 18d4afb5ceSopenharmony_ci * 4. Neither the name of the University nor the names of its contributors 19d4afb5ceSopenharmony_ci * may be used to endorse or promote products derived from this software 20d4afb5ceSopenharmony_ci * without specific prior written permission. 21d4afb5ceSopenharmony_ci * 22d4afb5ceSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23d4afb5ceSopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24d4afb5ceSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25d4afb5ceSopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26d4afb5ceSopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27d4afb5ceSopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28d4afb5ceSopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29d4afb5ceSopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30d4afb5ceSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31d4afb5ceSopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32d4afb5ceSopenharmony_ci * SUCH DAMAGE. 33d4afb5ceSopenharmony_ci */ 34d4afb5ceSopenharmony_ci#include <assert.h> 35d4afb5ceSopenharmony_ci#include <errno.h> 36d4afb5ceSopenharmony_ci#include <stdio.h> 37d4afb5ceSopenharmony_ci#include <stdlib.h> 38d4afb5ceSopenharmony_ci#include <string.h> 39d4afb5ceSopenharmony_ci#include "getopt.h" 40d4afb5ceSopenharmony_ci 41d4afb5ceSopenharmony_ci#define lws_ptr_diff(head, tail) \ 42d4afb5ceSopenharmony_ci ((int)((char *)(head) - (char *)(tail))) 43d4afb5ceSopenharmony_ci 44d4afb5ceSopenharmony_ciextern int opterr; /* if error message should be printed */ 45d4afb5ceSopenharmony_ciextern int optind; /* index into parent argv vector */ 46d4afb5ceSopenharmony_ciextern int optopt; /* character checked for validity */ 47d4afb5ceSopenharmony_ciextern int optreset; /* reset getopt */ 48d4afb5ceSopenharmony_ciextern char *optarg; /* argument associated with option */ 49d4afb5ceSopenharmony_ci 50d4afb5ceSopenharmony_ci#define __P(x) x 51d4afb5ceSopenharmony_ci#define _DIAGASSERT(x) assert(x) 52d4afb5ceSopenharmony_ci 53d4afb5ceSopenharmony_cistatic char * __progname __P((char *)); 54d4afb5ceSopenharmony_ciint getopt_internal __P((int, char * const *, const char *)); 55d4afb5ceSopenharmony_ci 56d4afb5ceSopenharmony_cistatic char * 57d4afb5ceSopenharmony_ci__progname(nargv0) 58d4afb5ceSopenharmony_ci char * nargv0; 59d4afb5ceSopenharmony_ci{ 60d4afb5ceSopenharmony_ci char * tmp; 61d4afb5ceSopenharmony_ci 62d4afb5ceSopenharmony_ci _DIAGASSERT(nargv0 != NULL); 63d4afb5ceSopenharmony_ci 64d4afb5ceSopenharmony_ci tmp = strrchr(nargv0, '/'); 65d4afb5ceSopenharmony_ci if (tmp) 66d4afb5ceSopenharmony_ci tmp++; 67d4afb5ceSopenharmony_ci else 68d4afb5ceSopenharmony_ci tmp = nargv0; 69d4afb5ceSopenharmony_ci return(tmp); 70d4afb5ceSopenharmony_ci} 71d4afb5ceSopenharmony_ci 72d4afb5ceSopenharmony_ci#define BADCH (int)'?' 73d4afb5ceSopenharmony_ci#define BADARG (int)':' 74d4afb5ceSopenharmony_ci#define EMSG "" 75d4afb5ceSopenharmony_ci 76d4afb5ceSopenharmony_ci/* 77d4afb5ceSopenharmony_ci * getopt -- 78d4afb5ceSopenharmony_ci * Parse argc/argv argument vector. 79d4afb5ceSopenharmony_ci */ 80d4afb5ceSopenharmony_ciint 81d4afb5ceSopenharmony_cigetopt_internal(nargc, nargv, ostr) 82d4afb5ceSopenharmony_ci int nargc; 83d4afb5ceSopenharmony_ci char * const *nargv; 84d4afb5ceSopenharmony_ci const char *ostr; 85d4afb5ceSopenharmony_ci{ 86d4afb5ceSopenharmony_ci static char *place = EMSG; /* option letter processing */ 87d4afb5ceSopenharmony_ci char *oli; /* option letter list index */ 88d4afb5ceSopenharmony_ci 89d4afb5ceSopenharmony_ci _DIAGASSERT(nargv != NULL); 90d4afb5ceSopenharmony_ci _DIAGASSERT(ostr != NULL); 91d4afb5ceSopenharmony_ci 92d4afb5ceSopenharmony_ci if (optreset || !*place) { /* update scanning pointer */ 93d4afb5ceSopenharmony_ci optreset = 0; 94d4afb5ceSopenharmony_ci if (optind >= nargc || *(place = nargv[optind]) != '-') { 95d4afb5ceSopenharmony_ci place = EMSG; 96d4afb5ceSopenharmony_ci return (-1); 97d4afb5ceSopenharmony_ci } 98d4afb5ceSopenharmony_ci if (place[1] && *++place == '-') { /* found "--" */ 99d4afb5ceSopenharmony_ci /* ++optind; */ 100d4afb5ceSopenharmony_ci place = EMSG; 101d4afb5ceSopenharmony_ci return (-2); 102d4afb5ceSopenharmony_ci } 103d4afb5ceSopenharmony_ci } /* option letter okay? */ 104d4afb5ceSopenharmony_ci if ((optopt = (int)*place++) == (int)':' || 105d4afb5ceSopenharmony_ci !(oli = strchr(ostr, optopt))) { 106d4afb5ceSopenharmony_ci /* 107d4afb5ceSopenharmony_ci * if the user didn't specify '-' as an option, 108d4afb5ceSopenharmony_ci * assume it means -1. 109d4afb5ceSopenharmony_ci */ 110d4afb5ceSopenharmony_ci if (optopt == (int)'-') 111d4afb5ceSopenharmony_ci return (-1); 112d4afb5ceSopenharmony_ci if (!*place) 113d4afb5ceSopenharmony_ci ++optind; 114d4afb5ceSopenharmony_ci if (opterr && *ostr != ':') 115d4afb5ceSopenharmony_ci (void)fprintf(stderr, 116d4afb5ceSopenharmony_ci "%s: illegal option -- %c\n", __progname(nargv[0]), optopt); 117d4afb5ceSopenharmony_ci return (BADCH); 118d4afb5ceSopenharmony_ci } 119d4afb5ceSopenharmony_ci if (*++oli != ':') { /* don't need argument */ 120d4afb5ceSopenharmony_ci optarg = NULL; 121d4afb5ceSopenharmony_ci if (!*place) 122d4afb5ceSopenharmony_ci ++optind; 123d4afb5ceSopenharmony_ci } else { /* need an argument */ 124d4afb5ceSopenharmony_ci if (*place) /* no white space */ 125d4afb5ceSopenharmony_ci optarg = place; 126d4afb5ceSopenharmony_ci else if (nargc <= ++optind) { /* no arg */ 127d4afb5ceSopenharmony_ci place = EMSG; 128d4afb5ceSopenharmony_ci if ((opterr) && (*ostr != ':')) 129d4afb5ceSopenharmony_ci (void)fprintf(stderr, 130d4afb5ceSopenharmony_ci "%s: option requires an argument -- %c\n", 131d4afb5ceSopenharmony_ci __progname(nargv[0]), optopt); 132d4afb5ceSopenharmony_ci return (BADARG); 133d4afb5ceSopenharmony_ci } else /* white space */ 134d4afb5ceSopenharmony_ci optarg = nargv[optind]; 135d4afb5ceSopenharmony_ci place = EMSG; 136d4afb5ceSopenharmony_ci ++optind; 137d4afb5ceSopenharmony_ci } 138d4afb5ceSopenharmony_ci return (optopt); /* dump back option letter */ 139d4afb5ceSopenharmony_ci} 140d4afb5ceSopenharmony_ci 141d4afb5ceSopenharmony_ci#if 0 142d4afb5ceSopenharmony_ci/* 143d4afb5ceSopenharmony_ci * getopt -- 144d4afb5ceSopenharmony_ci * Parse argc/argv argument vector. 145d4afb5ceSopenharmony_ci */ 146d4afb5ceSopenharmony_ciint 147d4afb5ceSopenharmony_cigetopt2(nargc, nargv, ostr) 148d4afb5ceSopenharmony_ci int nargc; 149d4afb5ceSopenharmony_ci char * const *nargv; 150d4afb5ceSopenharmony_ci const char *ostr; 151d4afb5ceSopenharmony_ci{ 152d4afb5ceSopenharmony_ci int retval; 153d4afb5ceSopenharmony_ci 154d4afb5ceSopenharmony_ci if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) { 155d4afb5ceSopenharmony_ci retval = -1; 156d4afb5ceSopenharmony_ci ++optind; 157d4afb5ceSopenharmony_ci } 158d4afb5ceSopenharmony_ci return(retval); 159d4afb5ceSopenharmony_ci} 160d4afb5ceSopenharmony_ci#endif 161d4afb5ceSopenharmony_ci 162d4afb5ceSopenharmony_ci/* 163d4afb5ceSopenharmony_ci * getopt_long -- 164d4afb5ceSopenharmony_ci * Parse argc/argv argument vector. 165d4afb5ceSopenharmony_ci */ 166d4afb5ceSopenharmony_ciint 167d4afb5ceSopenharmony_cigetopt_long(nargc, nargv, options, long_options, index) 168d4afb5ceSopenharmony_ci int nargc; 169d4afb5ceSopenharmony_ci char ** nargv; 170d4afb5ceSopenharmony_ci char * options; 171d4afb5ceSopenharmony_ci struct option * long_options; 172d4afb5ceSopenharmony_ci int * index; 173d4afb5ceSopenharmony_ci{ 174d4afb5ceSopenharmony_ci int retval; 175d4afb5ceSopenharmony_ci 176d4afb5ceSopenharmony_ci _DIAGASSERT(nargv != NULL); 177d4afb5ceSopenharmony_ci _DIAGASSERT(options != NULL); 178d4afb5ceSopenharmony_ci _DIAGASSERT(long_options != NULL); 179d4afb5ceSopenharmony_ci /* index may be NULL */ 180d4afb5ceSopenharmony_ci 181d4afb5ceSopenharmony_ci if ((retval = getopt_internal(nargc, nargv, options)) == -2) { 182d4afb5ceSopenharmony_ci char *current_argv = nargv[optind++] + 2, *has_equal; 183d4afb5ceSopenharmony_ci int i, current_argv_len, match = -1; 184d4afb5ceSopenharmony_ci 185d4afb5ceSopenharmony_ci if (*current_argv == '\0') { 186d4afb5ceSopenharmony_ci return(-1); 187d4afb5ceSopenharmony_ci } 188d4afb5ceSopenharmony_ci if ((has_equal = strchr(current_argv, '=')) != NULL) { 189d4afb5ceSopenharmony_ci current_argv_len = lws_ptr_diff(has_equal, current_argv); 190d4afb5ceSopenharmony_ci has_equal++; 191d4afb5ceSopenharmony_ci } else 192d4afb5ceSopenharmony_ci current_argv_len = (int)strlen(current_argv); 193d4afb5ceSopenharmony_ci 194d4afb5ceSopenharmony_ci for (i = 0; long_options[i].name; i++) { 195d4afb5ceSopenharmony_ci if (strncmp(current_argv, long_options[i].name, current_argv_len)) 196d4afb5ceSopenharmony_ci continue; 197d4afb5ceSopenharmony_ci 198d4afb5ceSopenharmony_ci if (strlen(long_options[i].name) == (unsigned)current_argv_len) { 199d4afb5ceSopenharmony_ci match = i; 200d4afb5ceSopenharmony_ci break; 201d4afb5ceSopenharmony_ci } 202d4afb5ceSopenharmony_ci if (match == -1) 203d4afb5ceSopenharmony_ci match = i; 204d4afb5ceSopenharmony_ci } 205d4afb5ceSopenharmony_ci if (match != -1) { 206d4afb5ceSopenharmony_ci if (long_options[match].has_arg == required_argument || 207d4afb5ceSopenharmony_ci long_options[match].has_arg == optional_argument) { 208d4afb5ceSopenharmony_ci if (has_equal) 209d4afb5ceSopenharmony_ci optarg = has_equal; 210d4afb5ceSopenharmony_ci else 211d4afb5ceSopenharmony_ci optarg = nargv[optind++]; 212d4afb5ceSopenharmony_ci } 213d4afb5ceSopenharmony_ci if ((long_options[match].has_arg == required_argument) 214d4afb5ceSopenharmony_ci && (optarg == NULL)) { 215d4afb5ceSopenharmony_ci /* 216d4afb5ceSopenharmony_ci * Missing argument, leading : 217d4afb5ceSopenharmony_ci * indicates no error should be generated 218d4afb5ceSopenharmony_ci */ 219d4afb5ceSopenharmony_ci if ((opterr) && (*options != ':')) 220d4afb5ceSopenharmony_ci (void)fprintf(stderr, 221d4afb5ceSopenharmony_ci "%s: option requires an argument -- %s\n", 222d4afb5ceSopenharmony_ci __progname(nargv[0]), current_argv); 223d4afb5ceSopenharmony_ci return (BADARG); 224d4afb5ceSopenharmony_ci } 225d4afb5ceSopenharmony_ci } else { /* No matching argument */ 226d4afb5ceSopenharmony_ci if ((opterr) && (*options != ':')) 227d4afb5ceSopenharmony_ci (void)fprintf(stderr, 228d4afb5ceSopenharmony_ci "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv); 229d4afb5ceSopenharmony_ci return (BADCH); 230d4afb5ceSopenharmony_ci } 231d4afb5ceSopenharmony_ci if (long_options[match].flag) { 232d4afb5ceSopenharmony_ci *long_options[match].flag = long_options[match].val; 233d4afb5ceSopenharmony_ci retval = 0; 234d4afb5ceSopenharmony_ci } else 235d4afb5ceSopenharmony_ci retval = long_options[match].val; 236d4afb5ceSopenharmony_ci if (index) 237d4afb5ceSopenharmony_ci *index = match; 238d4afb5ceSopenharmony_ci } 239d4afb5ceSopenharmony_ci return(retval); 240d4afb5ceSopenharmony_ci} 241