1
2
3
4
5
6
7
8
9#define LOG_CATEGORY LOGC_CORE
10
11#include <common.h>
12#include <getopt.h>
13#include <log.h>
14
15void getopt_init_state(struct getopt_state *gs)
16{
17 gs->index = 1;
18 gs->arg_index = 1;
19}
20
21int __getopt(struct getopt_state *gs, int argc, char *const argv[],
22 const char *optstring, bool silent)
23{
24 char curopt;
25 const char *curoptp;
26
27 while (1) {
28 log_debug("arg_index: %d index: %d\n", gs->arg_index,
29 gs->index);
30
31
32 if (gs->arg_index == 1 && argv[gs->index] &&
33 !strcmp(argv[gs->index], "--")) {
34 gs->index++;
35 return -1;
36 }
37
38
39 if (gs->index >= argc)
40 return -1;
41
42
43 if (*argv[gs->index] != '-')
44 return -1;
45
46
47 curopt = argv[gs->index][gs->arg_index];
48 if (curopt)
49 break;
50
51
52
53 gs->index++;
54 gs->arg_index = 1;
55 }
56
57
58 curoptp = strchr(optstring, curopt);
59
60 if (!curoptp) {
61 if (!silent)
62 printf("%s: invalid option -- %c\n", argv[0], curopt);
63 gs->opt = curopt;
64 gs->arg_index++;
65 return '?';
66 }
67
68 if (*(curoptp + 1) != ':') {
69
70 gs->arg = NULL;
71 gs->arg_index++;
72 return curopt;
73 }
74
75 if (*(curoptp + 1) && *(curoptp + 2) == ':') {
76
77 if (argv[gs->index][gs->arg_index + 1]) {
78
79 gs->arg = argv[gs->index++] + gs->arg_index + 1;
80 gs->arg_index = 1;
81 return curopt;
82 }
83 if (gs->index + 1 == argc) {
84
85 gs->arg = NULL;
86 gs->index++;
87 return curopt;
88 }
89 if (*argv[gs->index + 1] != '-') {
90
91
92
93 gs->index++;
94 gs->arg = argv[gs->index++];
95 gs->arg_index = 1;
96 return curopt;
97 }
98
99
100 gs->arg = NULL;
101 gs->arg_index = 1;
102 gs->index++;
103 return curopt;
104 }
105
106 if (argv[gs->index][gs->arg_index + 1]) {
107
108 gs->arg = argv[gs->index++] + gs->arg_index + 1;
109 gs->arg_index = 1;
110 return curopt;
111 }
112
113 gs->index++;
114 gs->arg_index = 1;
115
116 if (gs->index >= argc || argv[gs->index][0] == '-') {
117 if (!silent)
118 printf("option requires an argument -- %c\n", curopt);
119 gs->opt = curopt;
120 return ':';
121 }
122
123 gs->arg = argv[gs->index++];
124 return curopt;
125}
126