getsubopt.c revision 1573
1322810Shselasky/*-
2322810Shselasky * Copyright (c) 1990, 1993
3322810Shselasky *	The Regents of the University of California.  All rights reserved.
4322810Shselasky *
5322810Shselasky * Redistribution and use in source and binary forms, with or without
6322810Shselasky * modification, are permitted provided that the following conditions
7322810Shselasky * are met:
8322810Shselasky * 1. Redistributions of source code must retain the above copyright
9322810Shselasky *    notice, this list of conditions and the following disclaimer.
10322810Shselasky * 2. Redistributions in binary form must reproduce the above copyright
11322810Shselasky *    notice, this list of conditions and the following disclaimer in the
12322810Shselasky *    documentation and/or other materials provided with the distribution.
13322810Shselasky * 3. All advertising materials mentioning features or use of this software
14322810Shselasky *    must display the following acknowledgement:
15322810Shselasky *	This product includes software developed by the University of
16322810Shselasky *	California, Berkeley and its contributors.
17322810Shselasky * 4. Neither the name of the University nor the names of its contributors
18322810Shselasky *    may be used to endorse or promote products derived from this software
19322810Shselasky *    without specific prior written permission.
20322810Shselasky *
21322810Shselasky * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22322810Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23322810Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24322810Shselasky * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25322810Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26322810Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27322810Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28331769Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29322810Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30322810Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31322810Shselasky * SUCH DAMAGE.
32322810Shselasky */
33331769Shselasky
34331769Shselasky#ifndef lint
35331769Shselaskystatic char sccsid[] = "@(#)getsubopt.c	8.1 (Berkeley) 6/4/93";
36322810Shselasky#endif /* not lint */
37331769Shselasky
38322810Shselasky#include <unistd.h>
39322810Shselasky#include <stdlib.h>
40322810Shselasky
41331769Shselasky/*
42331769Shselasky * The SVID interface to getsubopt provides no way of figuring out which
43331769Shselasky * part of the suboptions list wasn't matched.  This makes error messages
44331769Shselasky * tricky...  The extern variable suboptarg is a pointer to the token
45331769Shselasky * which didn't match.
46322810Shselasky */
47322810Shselaskychar *suboptarg;
48331769Shselasky
49331769Shselaskygetsubopt(optionp, tokens, valuep)
50331769Shselasky	register char **optionp, **valuep;
51322810Shselasky	register char * const *tokens;
52322810Shselasky{
53341948Shselasky	register int cnt;
54337101Shselasky	register char *p;
55353268Shselasky
56337101Shselasky	suboptarg = *valuep = NULL;
57353268Shselasky
58322810Shselasky	if (!optionp || !*optionp)
59322810Shselasky		return(-1);
60322810Shselasky
61322810Shselasky	/* skip leading white-space, commas */
62322810Shselasky	for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
63322810Shselasky
64322810Shselasky	if (!*p) {
65322810Shselasky		*optionp = p;
66337101Shselasky		return(-1);
67337101Shselasky	}
68331769Shselasky
69331769Shselasky	/* save the start of the token, and skip the rest of the token. */
70322810Shselasky	for (suboptarg = p;
71331769Shselasky	    *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
72322810Shselasky
73322810Shselasky	if (*p) {
74331769Shselasky		/*
75331769Shselasky		 * If there's an equals sign, set the value pointer, and
76331769Shselasky		 * skip over the value part of the token.  Terminate the
77331769Shselasky		 * token.
78331769Shselasky		 */
79331769Shselasky		if (*p == '=') {
80331769Shselasky			*p = '\0';
81331769Shselasky			for (*valuep = ++p;
82331769Shselasky			    *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
83331769Shselasky			if (*p)
84331769Shselasky				*p++ = '\0';
85331769Shselasky		} else
86322810Shselasky			*p++ = '\0';
87331769Shselasky		/* Skip any whitespace or commas after this token. */
88331769Shselasky		for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
89331769Shselasky	}
90331769Shselasky
91331769Shselasky	/* set optionp for next round. */
92322810Shselasky	*optionp = p;
93331769Shselasky
94331769Shselasky	for (cnt = 0; *tokens; ++tokens, ++cnt)
95331769Shselasky		if (!strcmp(suboptarg, *tokens))
96331769Shselasky			return(cnt);
97331769Shselasky	return(-1);
98331769Shselasky}
99322810Shselasky