blob: d7b8d0dcae1563cdea10466fbdb5fb5e64f19b55 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* 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
27#ifdef __UCLIBC_MJN3_ONLY__
28#warning TODO: Enable gettext awareness.
29#endif /* __UCLIBC_MJN3_ONLY__ */
30
31#undef _
32#define _(X) X
33
34#ifdef __BCC__
35static const char missing[] = "option requires an argument";
36static const char illegal[] = "illegal option";
37#else
38static const char missing[] = "%s: option requires an argument -- %c\n";
39static const char illegal[] = "%s: illegal option -- %c\n";
40#endif
41
42int opterr = 1;
43int optind = 1;
44int optopt = 0;
45char *optarg = NULL;
46
47int getopt(int argc, char * const argv[], const char *optstring)
48{
49 static const char *o; /* multi opt position */
50 register const char *p;
51 register const char *s;
52 int retval = -1;
53
54 optopt = 0;
55 optarg = NULL;
56
57 if (!o) { /* Not in a multi-option arg. */
58 if ((optind >= argc) /* No more args? */
59 || ((p = argv[optind]) == NULL) /* Missing? */
60 || (*p != '-') /* Not an option? */
61 || (!*++p) /* "-" case? */
62 ) {
63 goto DONE;
64 }
65 if ((*p == '-') && (p[1] == 0)) { /* "--" case. */
66/* ++optind; */
67/* goto DONE; */
68 goto NEXTOPT; /* Less code generated... */
69 }
70 o = p;
71 }
72
73#ifdef __BCC__
74 p = o; /* Sigh... Help out bcc. */
75#define o p
76#endif
77 retval = (unsigned char) *o; /* Avoid problems for char val of -1. */
78
79 if ((*o == ':') || !(s = strchr(optstring, *o))) { /* Illegal option? */
80 s = illegal;
81 retval = '?';
82 goto BAD;
83 }
84
85 if (s[1] == ':') { /* Option takes an arg? */
86 if (o[1]) { /* No space between option and arg? */
87 optarg = (char *)(o + 1);
88 goto NEXTOPT;
89 }
90
91 if (optind + 1 < argc) { /* Space between option and arg? */
92 optarg = argv[++optind];
93 } else { /* Out of args! */
94 s = missing;
95 retval = ':';
96 BAD:
97 optopt = *o;
98 if (*optstring != ':') {
99 retval = '?';
100 if (opterr) {
101#ifdef __BCC__
102 fprintf(stderr, "%s: %s -- %c\n", argv[0], s, *o);
103#else
104 fprintf(stderr, _(s), argv[0], *o);
105#endif
106 }
107 }
108 }
109 }
110
111#ifdef __BCC__
112#undef o
113#endif
114
115 if (!*++o) {
116 NEXTOPT:
117 o = NULL;
118 ++optind;
119 }
120 DONE:
121 return retval;
122}
123libc_hidden_def(getopt)