1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
#define _BSD_SOURCE
#include <unistd.h>
#include <wchar.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include "locale_impl.h"
#include "stdio_impl.h"
char *optarg;
int optind=1, opterr=1, optopt, __optpos, __optreset=0;
#define optpos __optpos
weak_alias(__optreset, optreset);
void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
{
FILE *f = stderr;
b = __lctrans_cur(b);
FLOCK(f);
fputs(a, f)>=0
&& fwrite(b, strlen(b), 1, f)
&& fwrite(c, 1, l, f)==l
&& putc('\n', f);
FUNLOCK(f);
}
int getopt(int argc, char * const argv[], const char *optstring)
{
int i;
wchar_t c, d;
int k, l;
char *optchar;
if (!optind || __optreset) {
__optreset = 0;
__optpos = 0;
optind = 1;
}
if (optind >= argc || !argv[optind])
return -1;
if (argv[optind][0] != '-') {
if (optstring[0] == '-') {
optarg = argv[optind++];
return 1;
}
return -1;
}
if (!argv[optind][1])
return -1;
if (argv[optind][1] == '-' && !argv[optind][2])
return optind++, -1;
if (!optpos) optpos++;
if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
k = 1;
c = 0xfffd; /* replacement char */
}
optchar = argv[optind]+optpos;
optpos += k;
if (!argv[optind][optpos]) {
optind++;
optpos = 0;
}
if (optstring[0] == '-' || optstring[0] == '+')
optstring++;
i = 0;
d = 0;
do {
l = mbtowc(&d, optstring+i, MB_LEN_MAX);
if (l>0) i+=l; else i++;
} while (l && d != c);
if (d != c || c == ':') {
optopt = c;
if (optstring[0] != ':' && opterr)
__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
return '?';
}
if (optstring[i] == ':') {
optarg = 0;
if (optstring[i+1] != ':' || optpos) {
optarg = argv[optind++];
if (optpos) optarg += optpos;
optpos = 0;
}
if (optind > argc) {
optopt = c;
if (optstring[0] == ':') return ':';
if (opterr) __getopt_msg(argv[0],
": option requires an argument: ",
optchar, k);
return '?';
}
}
return c;
}
weak_alias(getopt, __posix_getopt);
|