This source file includes following definitions.
- bump_verbosity
- pcmk__new_common_args
- free_common_args
- pcmk__build_arg_context
- pcmk__free_arg_context
- pcmk__add_main_args
- pcmk__add_arg_group
- pcmk__cmdline_preproc
- G_GNUC_PRINTF
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <ctype.h>
13 #include <glib.h>
14
15 #include <crm/crm.h>
16 #include <crm/common/cmdline_internal.h>
17 #include <crm/common/strings_internal.h>
18 #include <crm/common/util.h>
19
20 static gboolean
21 bump_verbosity(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) {
22 pcmk__common_args_t *common_args = (pcmk__common_args_t *) data;
23 common_args->verbosity++;
24 return TRUE;
25 }
26
27 pcmk__common_args_t *
28 pcmk__new_common_args(const char *summary)
29 {
30 pcmk__common_args_t *args = NULL;
31
32 args = calloc(1, sizeof(pcmk__common_args_t));
33 if (args == NULL) {
34 crm_exit(CRM_EX_OSERR);
35 }
36
37 args->summary = strdup(summary);
38 if (args->summary == NULL) {
39 free(args);
40 args = NULL;
41 crm_exit(CRM_EX_OSERR);
42 }
43
44 return args;
45 }
46
47 static void
48 free_common_args(gpointer data) {
49 pcmk__common_args_t *common_args = (pcmk__common_args_t *) data;
50
51 free(common_args->summary);
52 free(common_args->output_ty);
53 free(common_args->output_dest);
54
55 if (common_args->output_as_descr != NULL) {
56 free(common_args->output_as_descr);
57 }
58
59 free(common_args);
60 }
61
62 GOptionContext *
63 pcmk__build_arg_context(pcmk__common_args_t *common_args, const char *fmts,
64 GOptionGroup **output_group, const char *param_string) {
65 char *desc = crm_strdup_printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
66 GOptionContext *context;
67 GOptionGroup *main_group;
68
69 GOptionEntry main_entries[3] = {
70 { "version", '$', 0, G_OPTION_ARG_NONE, &(common_args->version),
71 "Display software version and exit",
72 NULL },
73 { "verbose", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, bump_verbosity,
74 "Increase debug output (may be specified multiple times)",
75 NULL },
76
77 { NULL }
78 };
79
80 main_group = g_option_group_new(NULL, "Application Options:", NULL, common_args, free_common_args);
81 g_option_group_add_entries(main_group, main_entries);
82
83 context = g_option_context_new(param_string);
84 g_option_context_set_summary(context, common_args->summary);
85 g_option_context_set_description(context, desc);
86 g_option_context_set_main_group(context, main_group);
87
88 if (fmts != NULL) {
89 GOptionEntry output_entries[3] = {
90 { "output-as", 0, 0, G_OPTION_ARG_STRING, &(common_args->output_ty),
91 NULL,
92 "FORMAT" },
93 { "output-to", 0, 0, G_OPTION_ARG_STRING, &(common_args->output_dest),
94 "Specify file name for output (or \"-\" for stdout)", "DEST" },
95
96 { NULL }
97 };
98
99 if (*output_group == NULL) {
100 *output_group = g_option_group_new("output", "Output Options:", "Show output help", NULL, NULL);
101 }
102
103 common_args->output_as_descr = crm_strdup_printf("Specify output format as one of: %s", fmts);
104 output_entries[0].description = common_args->output_as_descr;
105 g_option_group_add_entries(*output_group, output_entries);
106 g_option_context_add_group(context, *output_group);
107 }
108
109 free(desc);
110
111
112
113 return context;
114 }
115
116 void
117 pcmk__free_arg_context(GOptionContext *context) {
118 if (context == NULL) {
119 return;
120 }
121
122 g_option_context_free(context);
123 }
124
125 void
126 pcmk__add_main_args(GOptionContext *context, GOptionEntry entries[])
127 {
128 GOptionGroup *main_group = g_option_context_get_main_group(context);
129
130 g_option_group_add_entries(main_group, entries);
131 }
132
133 void
134 pcmk__add_arg_group(GOptionContext *context, const char *name,
135 const char *header, const char *desc,
136 GOptionEntry entries[])
137 {
138 GOptionGroup *group = NULL;
139
140 group = g_option_group_new(name, header, desc, NULL, NULL);
141 g_option_group_add_entries(group, entries);
142 g_option_context_add_group(context, group);
143
144
145 }
146
147 gchar **
148 pcmk__cmdline_preproc(char **argv, const char *special) {
149 GPtrArray *arr = NULL;
150 bool saw_dash_dash = false;
151 bool copy_option = false;
152
153 if (argv == NULL) {
154 return NULL;
155 }
156
157 if (g_get_prgname() == NULL && argv && *argv) {
158 gchar *basename = g_path_get_basename(*argv);
159
160 g_set_prgname(basename);
161 g_free(basename);
162 }
163
164 arr = g_ptr_array_new();
165
166 for (int i = 0; argv[i] != NULL; i++) {
167
168
169
170
171
172 if (saw_dash_dash == false && strcmp(argv[i], "--") == 0) {
173 saw_dash_dash = true;
174 }
175
176 if (saw_dash_dash == true) {
177 g_ptr_array_add(arr, g_strdup(argv[i]));
178 continue;
179 }
180
181 if (copy_option == true) {
182 g_ptr_array_add(arr, g_strdup(argv[i]));
183 copy_option = false;
184 continue;
185 }
186
187
188
189
190 if (pcmk__str_eq(argv[i], "-", pcmk__str_casei)) {
191 g_ptr_array_add(arr, g_strdup(argv[i]));
192 continue;
193 }
194
195
196
197
198 if (g_str_has_prefix(argv[i], "-") && !g_str_has_prefix(argv[i], "--")) {
199
200 char *ch = argv[i]+1;
201
202
203
204
205
206
207 if (*ch != '\0' && *ch >= '1' && *ch <= '9') {
208 bool is_numeric = true;
209
210 while (*ch != '\0') {
211 if (!isdigit(*ch)) {
212 is_numeric = false;
213 break;
214 }
215
216 ch++;
217 }
218
219 if (is_numeric) {
220 g_ptr_array_add(arr, g_strdup_printf("%s", argv[i]));
221 continue;
222 } else {
223
224
225
226 ch = argv[i]+1;
227 }
228 }
229
230 while (*ch != '\0') {
231
232
233
234
235
236 if (special != NULL && strchr(special, *ch) != NULL) {
237
238
239
240 if (*(ch+1) != '\0') {
241 g_ptr_array_add(arr, g_strdup_printf("-%c", *ch));
242 g_ptr_array_add(arr, g_strdup(ch+1));
243 break;
244
245
246
247
248
249 } else {
250 g_ptr_array_add(arr, g_strdup_printf("-%c", *ch));
251 copy_option = true;
252 ch++;
253 }
254
255
256 } else {
257 g_ptr_array_add(arr, g_strdup_printf("-%c", *ch));
258 ch++;
259 }
260 }
261
262
263
264
265
266 } else {
267 g_ptr_array_add(arr, g_strdup(argv[i]));
268 }
269 }
270
271 g_ptr_array_add(arr, NULL);
272
273 return (char **) g_ptr_array_free(arr, FALSE);
274 }
275
276 G_GNUC_PRINTF(3, 4)
277 gboolean
278 pcmk__force_args(GOptionContext *context, GError **error, const char *format, ...) {
279 int len = 0;
280 char *buf = NULL;
281 gchar **extra_args = NULL;
282 va_list ap;
283 gboolean retval = TRUE;
284
285 va_start(ap, format);
286 len = vasprintf(&buf, format, ap);
287 CRM_ASSERT(len > 0);
288 va_end(ap);
289
290 if (!g_shell_parse_argv(buf, NULL, &extra_args, error)) {
291 g_strfreev(extra_args);
292 free(buf);
293 return FALSE;
294 }
295
296 retval = g_option_context_parse_strv(context, &extra_args, error);
297
298 g_strfreev(extra_args);
299 free(buf);
300 return retval;
301 }