summaryrefslogtreecommitdiff
path: root/agent/filter/getopt.c
blob: 8beeab85863ae4f62c9fde115bf7e7c15b87d6fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * getopt.C -- A getopt implementation.
 */

/*
 * $Id$
 *
 *  Copyright (c) 1990-2006, Raphael Manfredi
 *  
 *  You may redistribute only under the terms of the Artistic License,
 *  as specified in the README file that comes with the distribution.
 *  You may reuse parts of this distribution only within the terms of
 *  that same Artistic License; a copy of which may be found at the root
 *  of the source tree for mailagent 3.0.
 *
 * Original Author: unknown, got this off net.sources
 *
 * $Log: getopt.c,v $
 * Revision 3.0.1.2  1999/07/12  13:43:07  ram
 * patch66: was missing a trailing colon in getopt() declaration
 *
 * Revision 3.0.1.1  1997/02/20  11:34:56  ram
 * patch55: created
 *
 * Revision 3.0.1.1  1994/01/24  13:58:40  ram
 * patch16: created
 *
 */

#include "config.h"

#ifndef HAS_GETOPT

#include <stdio.h>

#ifdef I_STRING
#include <string.h>
#else
#include <strings.h>
#endif

#include "confmagic.h"		/* Remove if not metaconfig -M */

/*
 * Get option letter from argument vector
 */

int	opterr = 1,		/* Useless, never set or used */
	optind = 1,		/* Index into parent argv vector */
	optopt;			/* Character checked for validity */
char *optarg;		/* Argument associated with option */

#define BADCH	(int) '?'
#define EMSG	""

#define tell(s)				\
do {						\
	fputs(*nargv, stderr);	\
	fputs(s, stderr);		\
	fputc(optopt, stderr);	\
	fputc('\n', stderr);	\
	return BADCH;			\
} while (0)

/*
 * getopt
 *
 * Parses command line flags and arguments. Given the original arguments
 * via the (nargc, nargv) tuple, and a list of flags via 'ostr', it returns
 * the next flag recognized, and sets the externally visible 'optarg'
 * variable to point to the start of the flags's parameter, if any expected.
 *
 * When facing an invalid flag, getopt() returns '?'.
 *
 * The 'ostr' string is a list of allowed flag characters, optionally by ':'
 * when the flag expects a parameter, which can immediately follow the
 * flag or come as the next word.
 *
 * In any case, the 'optopt' variable is set upon return to the flag being
 * looked at, whether it was a valid flag or not.
 */
V_FUNC(int getopt, (nargc, nargv, ostr),
	int	nargc		/* Argument count */ NXT_ARG
	char **nargv	/* Argument vector */ NXT_ARG
	char *ostr		/* String specifying options */)
{
	static char *place = EMSG;	/* Option letter processing */
	register1 char *oli;		/* Option letter list index */

	/*
	 * Update scanning pointer.
	 */

	if (!*place) {
		if(
			optind >= nargc ||
			*(place = nargv[optind]) != '-' ||
			!*++place
		)
			return EOF;
		if (*place == '-') {	/* Found "--", end option processing */
			++optind;
			return EOF;
		}
	}

	/*
	 * Is option letter OK?
	 */

	if (
		(optopt = (int)*place++) == (int)':' ||
		!(oli = index(ostr,optopt))
	) {
		if (!*place) ++optind;
		tell(": illegal option -- ");
	}

	/*
	 * Found a valid option, process it.
	 */

	if (*++oli != ':') {			/* Don't need argument */
		optarg = NULL;
		if (!*place) ++optind;
	} else {							/* Need an argument */
		if (*place) optarg = place;		/* No white space */
		else if (nargc <= ++optind) {	/* No argument */
			place = EMSG;
			tell(": option requires an argument -- ");
		} else
			optarg = nargv[optind];		/* White space */
		place = EMSG;
		++optind;
	}

	return optopt;			/* Dump back option letter */
}
#else
int getopt_variable_not_used = 1;	/* Avoid "empty file" */
#endif	/* HAS_GETOPT */