xref: /original-bsd/lib/libc/stdlib/getsubopt.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)getsubopt.c	8.1 (Berkeley) 06/04/93";
10 #endif /* not lint */
11 
12 #include <unistd.h>
13 #include <stdlib.h>
14 
15 /*
16  * The SVID interface to getsubopt provides no way of figuring out which
17  * part of the suboptions list wasn't matched.  This makes error messages
18  * tricky...  The extern variable suboptarg is a pointer to the token
19  * which didn't match.
20  */
21 char *suboptarg;
22 
23 getsubopt(optionp, tokens, valuep)
24 	register char **optionp, **valuep;
25 	register char * const *tokens;
26 {
27 	register int cnt;
28 	register char *p;
29 
30 	suboptarg = *valuep = NULL;
31 
32 	if (!optionp || !*optionp)
33 		return(-1);
34 
35 	/* skip leading white-space, commas */
36 	for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
37 
38 	if (!*p) {
39 		*optionp = p;
40 		return(-1);
41 	}
42 
43 	/* save the start of the token, and skip the rest of the token. */
44 	for (suboptarg = p;
45 	    *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
46 
47 	if (*p) {
48 		/*
49 		 * If there's an equals sign, set the value pointer, and
50 		 * skip over the value part of the token.  Terminate the
51 		 * token.
52 		 */
53 		if (*p == '=') {
54 			*p = '\0';
55 			for (*valuep = ++p;
56 			    *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
57 			if (*p)
58 				*p++ = '\0';
59 		} else
60 			*p++ = '\0';
61 		/* Skip any whitespace or commas after this token. */
62 		for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
63 	}
64 
65 	/* set optionp for next round. */
66 	*optionp = p;
67 
68 	for (cnt = 0; *tokens; ++tokens, ++cnt)
69 		if (!strcmp(suboptarg, *tokens))
70 			return(cnt);
71 	return(-1);
72 }
73