Added options to run different tests in module batchtest
[lttv.git] / ltt / branches / poly / lttv / main / option.c
CommitLineData
9c312311 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
eccb5352 19
ffd54a90 20#include <popt.h>
21#include <glib.h>
fcdf0ec2 22#include <lttv/option.h>
eccb5352 23
dc877563 24typedef struct _LttvOption {
ffd54a90 25 char *long_name;
dc877563 26 char char_name;
ffd54a90 27 char *description;
28 char *arg_description;
dc877563 29 LttvOptionType t;
30 gpointer p;
ffd54a90 31 LttvOptionHook hook;
dc877563 32 gpointer hook_data;
33} LttvOption;
eccb5352 34
dc877563 35GHashTable *options;
eccb5352 36
eccb5352 37
dc877563 38static void
39list_options(gpointer key, gpointer value, gpointer user_data)
40{
41 g_ptr_array_add((GPtrArray *)user_data, value);
42}
eccb5352 43
eccb5352 44
dc877563 45static void
46free_option(LttvOption *option)
47{
48 g_free(option->long_name);
49 g_free(option->description);
50 g_free(option->arg_description);
51 g_free(option);
52}
eccb5352 53
eccb5352 54
dc877563 55void lttv_option_init(int argc, char **argv)
56{
2a2fa4f0 57 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init option.c");
dc877563 58 options = g_hash_table_new(g_str_hash, g_str_equal);
59}
eccb5352 60
eccb5352 61
dc877563 62void lttv_option_destroy()
63{
64 LttvOption option;
eccb5352 65
ffd54a90 66 GPtrArray *list = g_ptr_array_new();
eccb5352 67
dc877563 68 int i;
eccb5352 69
2a2fa4f0 70 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy option.c");
dc877563 71 g_hash_table_foreach(options, list_options, list);
72 g_hash_table_destroy(options);
eccb5352 73
dc877563 74 for(i = 0 ; i < list->len ; i++) {
75 free_option((LttvOption *)list->pdata[i]);
76 }
77 g_ptr_array_free(list, TRUE);
78}
eccb5352 79
eccb5352 80
dc877563 81void lttv_option_add(const char *long_name, const char char_name,
82 const char *description, const char *arg_description,
83 const LttvOptionType t, void *p,
84 const LttvOptionHook h, void *hook_data)
85{
86 LttvOption *option;
eccb5352 87
2a2fa4f0 88 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add option %s", long_name);
dc877563 89 if(g_hash_table_lookup(options, long_name) != NULL) {
90 g_warning("duplicate option");
91 return;
92 }
eccb5352 93
dc877563 94 option = g_new(LttvOption, 1);
95 option->long_name = g_strdup(long_name);
96 option->char_name = char_name;
97 option->description = g_strdup(description);
98 option->arg_description = g_strdup(arg_description);
99 option->t = t;
100 option->p = p;
ffd54a90 101 option->hook = h;
dc877563 102 option->hook_data = hook_data;
103 g_hash_table_insert(options, option->long_name, option);
104}
eccb5352 105
eccb5352 106
dc877563 107void
108lttv_option_remove(const char *long_name)
109{
110 LttvOption *option = g_hash_table_lookup(options, long_name);
eccb5352 111
2a2fa4f0 112 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Remove option %s", long_name);
dc877563 113 if(option == NULL) {
114 g_warning("trying to remove unknown option %s", long_name);
115 return;
116 }
117 g_hash_table_remove(options, long_name);
118 free_option(option);
eccb5352 119}
120
eccb5352 121
dc877563 122static int poptToLTT[] = {
123 POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG
124};
150ef81a 125
dc877563 126static struct poptOption endOption = { NULL, '\0', 0, NULL, 0};
f68ad60d 127
eccb5352 128
dc877563 129static void
130build_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc,
ffd54a90 131 int argc, char **argv)
dc877563 132{
133 LttvOption *option;
eccb5352 134
dc877563 135 GPtrArray *list;
eccb5352 136
dc877563 137 struct poptOption *popts;
eccb5352 138
dc877563 139 poptContext c;
eccb5352 140
dc877563 141 guint i;
eccb5352 142
dc877563 143 list = g_ptr_array_new();
eccb5352 144
dc877563 145 g_hash_table_foreach(options, list_options, list);
eccb5352 146
dc877563 147 /* Build a popt options array from our list */
eccb5352 148
dc877563 149 popts = g_new(struct poptOption, list->len + 1);
eccb5352 150
dc877563 151 for(i = 0 ; i < list->len ; i++) {
152 option = (LttvOption *)list->pdata[i];
153 popts[i].longName = option->long_name;
154 popts[i].shortName = option->char_name;
155 popts[i].descrip = option->description;
156 popts[i].argDescrip = option->arg_description;
157 popts[i].argInfo = poptToLTT[option->t];
158 popts[i].arg = option->p;
159 popts[i].val = i + 1;
160 }
161
162 /* Terminate the array for popt and create the context */
eccb5352 163
dc877563 164 popts[list->len] = endOption;
165 c = poptGetContext(argv[0], argc, (const char**)argv, popts, 0);
eccb5352 166
dc877563 167 *plist = list;
168 *ppopts = popts;
169 *pc = c;
eccb5352 170}
171
172
dc877563 173static void
174destroy_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc)
175{
176 g_ptr_array_free(*plist, TRUE); *plist = NULL;
177 g_free(*ppopts); *ppopts = NULL;
ffd54a90 178 poptFreeContext(*pc);
dc877563 179}
eccb5352 180
eccb5352 181
dc877563 182void lttv_option_parse(int argc, char **argv)
eccb5352 183{
dc877563 184 GPtrArray *list;
185
186 LttvOption *option;
187
188 int i, rc, first_arg;
189
190 struct poptOption *popts;
191
eccb5352 192 poptContext c;
eccb5352 193
dc877563 194 i = 0;
eccb5352 195
dc877563 196 first_arg = 0;
eccb5352 197
dc877563 198 build_popts(&list, &popts, &c, argc, argv);
eccb5352 199
200 /* Parse options while not end of options event */
dc877563 201
eccb5352 202 while((rc = poptGetNextOpt(c)) != -1) {
dc877563 203
204 /* The option was recognized and the rc value returned is the argument
205 position in the array. Call the associated hook if present. */
206
207 if(rc > 0) {
208 option = (LttvOption *)(list->pdata[rc - 1]);
2a2fa4f0 209 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Option %s encountered",
210 option->long_name);
b445142a 211 if(option->hook != NULL) {
2a2fa4f0 212 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s hook called",
213 option->long_name);
b445142a 214 option->hook(option->hook_data);
215 }
dc877563 216 i++;
217 }
218
219 else if(rc == POPT_ERROR_BADOPT && i != first_arg) {
2a2fa4f0 220 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
221 "Option %s not recognized, rescan options with new additions",
222 poptBadOption(c,0));
dc877563 223
224 /* Perhaps this option is newly added, restart parsing */
225
226 destroy_popts(&list, &popts, &c);
227 build_popts(&list, &popts, &c, argc, argv);
228
229 /* Get back to the same argument */
230
231 first_arg = i;
b445142a 232 for(i = 0; i < first_arg; i++) {
233 rc = poptGetNextOpt(c);
234 option = (LttvOption *)(list->pdata[rc - 1]);
2a2fa4f0 235 g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped",
236 option->long_name);
b445142a 237 }
eccb5352 238 }
eccb5352 239
dc877563 240 else {
eccb5352 241
dc877563 242 /* The option has some error and it is not because this is a newly
243 added option not recognized. */
eccb5352 244
dc877563 245 g_error("option %s: %s", poptBadOption(c,0), poptStrerror(rc));
246 break;
247 }
248
249 }
250
251 destroy_popts(&list, &popts, &c);
eccb5352 252}
253
d888c9c8 254static void show_help(LttvOption *option)
255{
256 printf("--%s -%c argument: %s\n" , option->long_name,
257 option->char_name,
258 option->arg_description);
259 printf(" %s\n" , option->description);
260
261}
262
263void lttv_option_show_help(void)
264{
265 LttvOption option;
266
267 GPtrArray *list = g_ptr_array_new();
268
269 int i;
270
271 g_hash_table_foreach(options, list_options, list);
272
273 printf("Built-in commands available:\n");
274 printf("\n");
275
276 for(i = 0 ; i < list->len ; i++) {
277 show_help((LttvOption *)list->pdata[i]);
278 }
279 g_ptr_array_free(list, TRUE);
280
281
282}
b445142a 283
This page took 0.040954 seconds and 4 git commands to generate.