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