1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#define FOR_getopt
24#include "toys.h"
25
26GLOBALS(
27 struct arg_list *l;
28 char *o, *n;
29)
30
31static void out(char *s)
32{
33 if (FLAG(u)) printf(" %s", s);
34 else {
35 printf(" '");
36 for (; *s; s++) {
37 if (*s == '\'') printf("'\\''");
38 else putchar(*s);
39 }
40 printf("'");
41 }
42}
43
44static char *parse_long_opt(void *data, char *str, int len)
45{
46 struct option **lopt_ptr = data, *lopt = *lopt_ptr;
47
48
49
50 for (lopt->has_arg = 0; len>0 && str[len-1] == ':'; lopt->has_arg++) len--;
51 if (!len || lopt->has_arg>2) return str;
52
53 lopt->name = xstrndup(str, len);
54
55 (*lopt_ptr)++;
56 return 0;
57}
58
59void getopt_main(void)
60{
61 int argc = toys.optc+1;
62 char **argv = xzalloc(sizeof(char *)*(argc+1));
63 struct option *lopts = xzalloc(sizeof(struct option)*argc), *lopt = lopts;
64 int i = 0, j = 0, ch;
65
66 if (FLAG(T)) {
67 toys.exitval = 4;
68 return;
69 }
70
71 comma_args(TT.l, &lopt, "bad -l", parse_long_opt);
72 argv[j++] = TT.n ? TT.n : "getopt";
73
74
75 if (!FLAG(o)) {
76 toys.optflags |= FLAG_u;
77 TT.o = toys.optargs[i++];
78 if (!TT.o) error_exit("no OPTSTR");
79 --argc;
80 }
81
82 while (i<toys.optc) argv[j++] = toys.optargs[i++];
83
84
85 opterr = 0;
86 optind = 1;
87 while ((ch = (FLAG(a)?getopt_long_only:getopt_long)(argc, argv, TT.o,
88 lopts, &i)) != -1) {
89 if (ch == '?') {
90 fprintf(stderr, "%s: invalid option '%c'\n", argv[0], optopt);
91 toys.exitval = 1;
92 } else if (!ch) {
93 printf(" --%s", lopts[i].name);
94 if (lopts[i].has_arg) out(optarg ? optarg : "");
95 } else {
96 printf(" -%c", ch);
97 if (optarg) out(optarg);
98 }
99 }
100
101 printf(" --");
102 for (; optind<argc; optind++) out(argv[optind]);
103 printf("\n");
104}
105