1 /*  Copyright (C) 2003     Manuel Novoa III
2  *
3  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4  */
5 
6 /*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
7  *
8  *  Besides uClibc, I'm using this code in my libc for elks, which is
9  *  a 16-bit environment with a fairly limited compiler.  It would make
10  *  things much easier for me if this file isn't modified unnecessarily.
11  *  In particular, please put any new or replacement functions somewhere
12  *  else, and modify the makefile to use your version instead.
13  *  Thanks.  Manuel
14  *
15  *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
16 
17 /* Sep 7, 2003
18  *   Initial version of a SUSv3 compliant getopt().
19  */
20 
21 #include <unistd.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <getopt.h>
25 
26 #ifdef __BCC__
27 static const char missing[] = "option requires an argument";
28 static const char illegal[] = "illegal option";
29 #else
30 static const char missing[] = "%s: option requires an argument -- %c\n";
31 static const char illegal[] = "%s: illegal option -- %c\n";
32 #endif
33 
34 int opterr = 1;
35 int optind = 1;
36 int optopt = 0;
37 char *optarg = NULL;
38 
getopt(int argc,char * const argv[],const char * optstring)39 int getopt(int argc, char * const argv[], const char *optstring)
40 {
41 	static const char *o;		/* multi opt position */
42 	register const char *p;
43 	register const char *s;
44 	int retval = -1;
45 
46 	optopt = 0;
47 	optarg = NULL;
48 
49 	if (!o) {				/* Not in a multi-option arg. */
50 		if ((optind >= argc)	/* No more args? */
51 			|| ((p = argv[optind]) == NULL) /* Missing? */
52 			|| (*p != '-')		/* Not an option? */
53 			|| (!*++p)			/* "-" case? */
54 			) {
55 			goto DONE;
56 		}
57 		if ((*p == '-') && (p[1] == 0)) { /* "--" case. */
58 /* 			++optind; */
59 /* 			goto DONE; */
60 			goto NEXTOPT;		/* Less code generated... */
61 		}
62 		o = p;
63 	}
64 
65 #ifdef __BCC__
66 	p = o;						/* Sigh... Help out bcc. */
67 #define o p
68 #endif
69 	retval = (unsigned char) *o; /* Avoid problems for char val of -1. */
70 
71 	if ((*o == ':') || !(s = strchr(optstring, *o))) { /* Illegal option? */
72 		s = illegal;
73 		retval = '?';
74 		goto BAD;
75 	}
76 
77 	if (s[1] == ':') {			/* Option takes an arg? */
78 		if (o[1]) {					/* No space between option and arg? */
79 			optarg = (char *)(o + 1);
80 			goto NEXTOPT;
81 		}
82 
83 		if (optind + 1 < argc) {	/* Space between option and arg? */
84 			optarg = argv[++optind];
85 		} else {				/* Out of args! */
86 			s = missing;
87 			retval = ':';
88 		BAD:
89 			optopt = *o;
90 			if (*optstring != ':') {
91 				retval = '?';
92 				if (opterr) {
93 #ifdef __BCC__
94 					fprintf(stderr, "%s: %s -- %c\n", argv[0], s, *o);
95 #else
96 					fprintf(stderr, _(s), argv[0], *o);
97 #endif
98 				}
99 			}
100 		}
101 	}
102 
103 #ifdef __BCC__
104 #undef o
105 #endif
106 
107 	if (!*++o) {
108 	NEXTOPT:
109 		o = NULL;
110 		++optind;
111 	}
112  DONE:
113 	return retval;
114 }
115 libc_hidden_def(getopt)
116