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