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