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
|
#include <string.h>
#include <getopt.h>
static void getopterror(int which) {
static char error1[]="Unknown option `-x'.\n";
static char error2[]="Missing argument for `-x'.\n";
if (opterr) {
if (which) {
error2[23]=optopt;
write(2,error2,28);
} else {
error1[17]=optopt;
write(2,error1,22);
}
}
}
int getopt_long(int argc, char * const argv[], const char *optstring,
const struct option *longopts, int *longindex) {
static int lastidx=0,lastofs=0;
char *tmp;
if (optind==0) optind=1; /* whoever started setting optind to 0 should be shot */
again:
if (optind>argc || !argv[optind] || *argv[optind]!='-' || argv[optind][1]==0)
return -1;
if (argv[optind][1]=='-' && argv[optind][2]==0) {
++optind;
return -1;
}
if (argv[optind][1]=='-') { /* long option */
char* arg=argv[optind]+2;
char* max=strchr(arg,'=');
const struct option* o;
if (!max) max=arg+strlen(arg);
for (o=longopts; o->name; ++o) {
if (!strncmp(o->name,arg,(size_t)(max-arg))) { /* match */
if (longindex) *longindex=o-longopts;
if (o->has_arg>0) {
if (*max=='=')
optarg=max+1;
else {
optarg=argv[optind+1];
if (!optarg && o->has_arg==1) { /* no argument there */
if (*optstring==':') return ':';
write(2,"argument required: `",20);
write(2,arg,(size_t)(max-arg));
write(2,"'.\n",3);
++optind;
return '?';
}
++optind;
}
}
++optind;
if (o->flag)
*(o->flag)=o->val;
else
return o->val;
return 0;
}
}
if (*optstring==':') return ':';
write(2,"invalid option `",16);
write(2,arg,(size_t)(max-arg));
write(2,"'.\n",3);
++optind;
return '?';
}
if (lastidx!=optind) {
lastidx=optind; lastofs=0;
}
optopt=argv[optind][lastofs+1];
if ((tmp=strchr(optstring,optopt))) {
if (*tmp==0) { /* apparently, we looked for \0, i.e. end of argument */
++optind;
goto again;
}
if (tmp[1]==':') { /* argument expected */
if (tmp[2]==':' || argv[optind][lastofs+2]) { /* "-foo", return "oo" as optarg */
if (!*(optarg=argv[optind]+lastofs+2)) optarg=0;
goto found;
}
optarg=argv[optind+1];
if (!optarg) { /* missing argument */
++optind;
if (*optstring==':') return ':';
getopterror(1);
return ':';
}
++optind;
} else {
++lastofs;
return optopt;
}
found:
++optind;
return optopt;
} else { /* not found */
getopterror(0);
++optind;
return '?';
}
}
|