1 | /* 2 | * Copyright (c) 1987, 1993, 1994 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | /* This code has been modified from the original UC version by 35 | Marek Bukowy, RIPE NCC 36 | to be thread-safe 37 | */ 38 | 39 | #include <stdio.h> 40 | #include <stdlib.h> 41 | #include <string.h> 42 | 43 | #include "getopt.h" 44 | 45 | getopt_state_t * 46 | mg_new(int optind) 47 | { 48 | getopt_state_t *state; 49 | 50 | if( (state=calloc(1, sizeof(getopt_state_t))) != NULL ) { 51 | state->place = EMSG; 52 | state->optind = optind; 53 | state->optreset = 1; 54 | } 55 | return state; 56 | } 57 | 58 | 59 | /* 60 | * getopt -- 61 | * Parse argc/argv argument vector. 62 | */ 63 | int 64 | mg_getopt( int nargc, 65 | char * const *nargv, 66 | const char *ostr, 67 | getopt_state_t *state) 68 | { 69 | char *oli; /* option letter list index */ 70 | #ifdef __linux__ 71 | int optopt; 72 | #endif 73 | 74 | if (state->optreset || !*state->place) { /* update scanning pointer */ 75 | state->optreset = 0; 76 | 77 | /* handle wrongly tokenised space (grrrrr...) - skip empty fields */ 78 | while(state->optind < nargc && *(nargv[state->optind]) == '\0') { 79 | state->optind++; 80 | } 81 | if (state->optind >= nargc || *(state->place = nargv[state->optind]) != '-') { 82 | state->place = EMSG; 83 | return (-1); 84 | } 85 | if (state->place[1] && *++(state->place) == '-') { /* found "--" */ 86 | ++state->optind; 87 | state->place = EMSG; 88 | return (-1); 89 | } 90 | } /* option letter okay? */ 91 | if ((state->optopt = (int)*state->place++) == (int)':' || 92 | !(oli = strchr(ostr, state->optopt))) { 93 | /* 94 | * if the user didn't specify '-' as an option, 95 | * assume it means -1. 96 | */ 97 | if (state->optopt == (int)'-') 98 | return (-1); 99 | if (!*state->place) 100 | ++state->optind; 101 | return (BADCH); 102 | } 103 | if (*++oli != ':') { /* don't need argument */ 104 | state->optarg = NULL; 105 | if (!*state->place) 106 | ++state->optind; 107 | } 108 | else { /* need an argument */ 109 | if (*state->place) /* no white space */ 110 | state->optarg = state->place; 111 | else if (nargc <= ++state->optind) { /* no arg */ 112 | state->place = EMSG; 113 | if (*ostr == ':') 114 | return (BADARG); 115 | 116 | return (BADCH); 117 | } 118 | else /* white space */ 119 | state->optarg = nargv[state->optind]; 120 | state->place = EMSG; 121 | ++state->optind; 122 | } 123 | return (state->optopt); /* dump back option letter */ 124 | }