1 /*---------------------------------------------------------------------------*\
2 This code has been adapted from the original AT&T public domain
3 implementation of getopt(3). The following comment comes from the original
4 source, as posted to a newsgroup in 1987.
5
6 The original SCCS ID attached to this code was:
7
8 @(#)getopt.c 2.5 (smail) 9/15/87
9
10 I have ANSI-fied this code and remove the #define of the `index' macro.
11 In all other respects, it is identical to the original, posted source.
12
13 This source file is not subject to the license in this directory; it is in
14 the public domain.
15 \*---------------------------------------------------------------------------*/
16
17 /*
18 * Here's something you've all been waiting for: the AT&T public domain
19 * source for getopt(3). It is the code which was given out at the 1985
20 * UNIFORUM conference in Dallas. I obtained it by electronic mail
21 * directly from AT&T. The people there assure me that it is indeed
22 * in the public domain.
23 *
24 * There is no manual page. That is because the one they gave out at
25 * UNIFORUM was slightly different from the current System V Release 2
26 * manual page. The difference apparently involved a note about the
27 * famous rules 5 and 6, recommending using white space between an option
28 * and its first argument, and not grouping options that have arguments.
29 * Getopt itself is currently lenient about both of these things White
30 * space is allowed, but not mandatory, and the last option in a group can
31 * have an argument. That particular version of the man page evidently
32 * has no official existence, and my source at AT&T did not send a copy.
33 * The current SVR2 man page reflects the actual behavor of this getopt.
34 * However, I am not about to post a copy of anything licensed by AT&T.
35 *
36 * ----
37 * NOTE: To avoid conflicts with existing system getopt routines, I've
38 * changed the names of the function and external variables from getopt(),
39 * optind, etc., to x_getopt(), x_optind, etc.
40 *
41 */
42
43 #include <stdio.h>
44 /* We're ANSI now; we're guaranteed to have strchr(). */
45 #include <string.h>
46
47 #define ERR(s, c) if(x_opterr){\
48 extern int write();\
49 char errbuf[2];\
50 errbuf[0] = c; errbuf[1] = '\n';\
51 (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
52 (void) write(2, s, (unsigned)strlen(s));\
53 (void) write(2, errbuf, 2);}
54
55 int x_opterr = 1;
56 int x_optind = 1;
57 int x_optopt;
58 char *x_optarg;
59
60 int
x_getopt(int argc,char ** argv,const char * opts)61 x_getopt(int argc, char **argv, const char *opts)
62 {
63 static int sp = 1;
64 register int c;
65 register char *cp;
66
67 if(sp == 1) {
68 if(x_optind >= argc ||
69 argv[x_optind][0] != '-' || argv[x_optind][1] == '\0') {
70 return(EOF);
71 } else if(strcmp(argv[x_optind], "--") == 0) {
72 x_optind++;
73 return(EOF);
74 }
75 }
76 x_optopt = c = argv[x_optind][sp];
77 if(c == ':' || (cp=strchr(opts, c)) == NULL) {
78 ERR(": illegal option -- ", c);
79 if(argv[x_optind][++sp] == '\0') {
80 x_optind++;
81 sp = 1;
82 }
83 return('?');
84 }
85 if(*++cp == ':') {
86 if(argv[x_optind][sp+1] != '\0')
87 x_optarg = &argv[x_optind++][sp+1];
88 else if(++x_optind >= argc) {
89 ERR(": option requires an argument -- ", c);
90 sp = 1;
91 return('?');
92 } else
93 x_optarg = argv[x_optind++];
94 sp = 1;
95 } else {
96 if(argv[x_optind][++sp] == '\0') {
97 sp = 1;
98 x_optind++;
99 }
100 x_optarg = NULL;
101 }
102 return(c);
103 }
104