xref: /illumos-gate/usr/src/cmd/mdb/common/libstand/getopt.c (revision 45ede40b2394db7967e59f19288fae9b62efd4aa)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/salib.h>
28 
29 #define	EOF	(-1)
30 
31 int opterr = 1, optind = 1, optopt = 0;
32 char *optarg = NULL;
33 int _sp = 1;
34 
35 extern void warn(const char *, ...);
36 
37 void
38 getopt_reset(void)
39 {
40 	opterr = 1;
41 	optind = 1;
42 	optopt = 0;
43 	optarg = NULL;
44 	_sp = 1;
45 }
46 
47 int
48 getopt(int argc, char *const *argv, const char *opts)
49 {
50 	char c;
51 	char *cp;
52 
53 	if (_sp == 1) {
54 		if (optind >= argc || argv[optind][0] != '-' ||
55 		    argv[optind] == NULL || argv[optind][1] == '\0')
56 			return (EOF);
57 		else if (strcmp(argv[optind], "--") == 0) {
58 			optind++;
59 			return (EOF);
60 		}
61 	}
62 	optopt = c = (unsigned char)argv[optind][_sp];
63 	if (c == ':' || (cp = strchr(opts, c)) == NULL) {
64 		if (opts[0] != ':')
65 			warn("%s: illegal option -- %c\n", argv[0], c);
66 		if (argv[optind][++_sp] == '\0') {
67 			optind++;
68 			_sp = 1;
69 		}
70 		return ('?');
71 	}
72 
73 	if (*(cp + 1) == ':') {
74 		if (argv[optind][_sp+1] != '\0')
75 			optarg = &argv[optind++][_sp+1];
76 		else if (++optind >= argc) {
77 			if (opts[0] != ':') {
78 				warn("%s: option requires an argument"
79 				    " -- %c\n", argv[0], c);
80 			}
81 			_sp = 1;
82 			optarg = NULL;
83 			return (opts[0] == ':' ? ':' : '?');
84 		} else
85 			optarg = argv[optind++];
86 		_sp = 1;
87 	} else {
88 		if (argv[optind][++_sp] == '\0') {
89 			_sp = 1;
90 			optind++;
91 		}
92 		optarg = NULL;
93 	}
94 	return (c);
95 }
96