3 ** Copyright (C) 2002 Martin Roesch <roesch@sourcefire.com>
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License Version 2 as
7 ** published by the Free Software Foundation. You may not use, modify or
8 ** distribute this program under any other version of the GNU General
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <stdio.h> /* for EOF */
23 #include <string.h> /* for strchr() */
27 /* static (global) variables that are specified as exported by getopt() */
28 char *optarg = NULL; /* pointer to the start of the option argument */
29 int optind = 1; /* number of the next argv[] to be evaluated */
30 int opterr = 1; /* non-zero if a question mark should be returned
31 when a non-valid option character is detected */
34 int getopt(int argc, char *argv[], char *opstring)
36 static char *pIndexPosition = NULL; /* place inside current argv string */
37 char *pArgString = NULL; /* where to start from next */
38 char *pOptString; /* the string in our program */
41 if (pIndexPosition != NULL) {
42 /* we last left off inside an argv string */
43 if (*(++pIndexPosition)) {
44 /* there is more to come in the most recent argv */
45 pArgString = pIndexPosition;
49 if (pArgString == NULL) {
50 /* we didn't leave off in the middle of an argv string */
52 /* more command-line arguments than the argument count */
53 pIndexPosition = NULL; /* not in the middle of anything */
54 return EOF; /* used up all command-line arguments */
57 /*---------------------------------------------------------------------
58 * If the next argv[] is not an option, there can be no more options.
59 *-------------------------------------------------------------------*/
60 pArgString = argv[optind++]; /* set this to the next argument ptr */
62 if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */
63 ('-' != *pArgString)) {
64 --optind; /* point to current arg once we're done */
65 optarg = NULL; /* no argument follows the option */
66 pIndexPosition = NULL; /* not in the middle of anything */
67 return EOF; /* used up all the command-line flags */
70 /* check for special end-of-flags markers */
71 if ((strcmp(pArgString, "-") == 0) ||
72 (strcmp(pArgString, "--") == 0)) {
73 optarg = NULL; /* no argument follows the option */
74 pIndexPosition = NULL; /* not in the middle of anything */
75 return EOF; /* encountered the special flag */
78 pArgString++; /* look past the / or - */
81 if (':' == *pArgString) { /* is it a colon? */
82 /*---------------------------------------------------------------------
83 * Rare case: if opterr is non-zero, return a question mark;
84 * otherwise, just return the colon we're on.
85 *-------------------------------------------------------------------*/
86 return (opterr ? (int)'?' : (int)':');
88 else if ((pOptString = strchr(opstring, *pArgString)) == 0) {
89 /*---------------------------------------------------------------------
90 * The letter on the command-line wasn't any good.
91 *-------------------------------------------------------------------*/
92 optarg = NULL; /* no argument follows the option */
93 pIndexPosition = NULL; /* not in the middle of anything */
94 return (opterr ? (int)'?' : (int)*pArgString);
97 /*---------------------------------------------------------------------
98 * The letter on the command-line matches one we expect to see
99 *-------------------------------------------------------------------*/
100 if (':' == _next_char(pOptString)) { /* is the next letter a colon? */
101 /* It is a colon. Look for an argument string. */
102 if ('\0' != _next_char(pArgString)) { /* argument in this argv? */
103 optarg = &pArgString[1]; /* Yes, it is */
106 /*-------------------------------------------------------------
107 * The argument string must be in the next argv.
108 * But, what if there is none (bad input from the user)?
109 * In that case, return the letter, and optarg as NULL.
110 *-----------------------------------------------------------*/
112 optarg = argv[optind++];
115 return (opterr ? (int)'?' : (int)*pArgString);
119 pIndexPosition = NULL; /* not in the middle of anything */
122 /* it's not a colon, so just return the letter */
123 optarg = NULL; /* no argument follows the option */
124 pIndexPosition = pArgString; /* point to the letter we're on */
126 return (int)*pArgString; /* return the letter that matched */