1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
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;
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.
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,
22 #include <lttv/option.h>
24 #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format)
25 #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format)
27 typedef struct _LttvOption
{
31 char *arg_description
;
42 list_options(gpointer key
, gpointer value
, gpointer user_data
)
44 g_ptr_array_add((GPtrArray
*)user_data
, value
);
49 free_option(LttvOption
*option
)
51 g_free(option
->long_name
);
52 g_free(option
->description
);
53 g_free(option
->arg_description
);
58 void lttv_option_init(int argc
, char **argv
)
60 g_info("Init option.c");
61 options
= g_hash_table_new(g_str_hash
, g_str_equal
);
65 void lttv_option_destroy()
69 GPtrArray
*list
= g_ptr_array_new();
73 g_info("Destroy option.c");
74 g_hash_table_foreach(options
, list_options
, list
);
75 g_hash_table_destroy(options
);
77 for(i
= 0 ; i
< list
->len
; i
++) {
78 free_option((LttvOption
*)list
->pdata
[i
]);
80 g_ptr_array_free(list
, TRUE
);
84 void lttv_option_add(const char *long_name
, const char char_name
,
85 const char *description
, const char *arg_description
,
86 const LttvOptionType t
, void *p
,
87 const LttvOptionHook h
, void *hook_data
)
91 g_info("Add option %s", long_name
);
92 if(g_hash_table_lookup(options
, long_name
) != NULL
) {
93 g_warning("duplicate option");
97 option
= g_new(LttvOption
, 1);
98 option
->long_name
= g_strdup(long_name
);
99 option
->char_name
= char_name
;
100 option
->description
= g_strdup(description
);
101 option
->arg_description
= g_strdup(arg_description
);
105 option
->hook_data
= hook_data
;
106 g_hash_table_insert(options
, option
->long_name
, option
);
111 lttv_option_remove(const char *long_name
)
113 LttvOption
*option
= g_hash_table_lookup(options
, long_name
);
115 g_info("Remove option %s", long_name
);
117 g_warning("trying to remove unknown option %s", long_name
);
120 g_hash_table_remove(options
, long_name
);
125 static int poptToLTT
[] = {
126 POPT_ARG_NONE
, POPT_ARG_STRING
, POPT_ARG_INT
, POPT_ARG_LONG
129 static struct poptOption endOption
= { NULL
, '\0', 0, NULL
, 0};
133 build_popts(GPtrArray
**plist
, struct poptOption
**ppopts
, poptContext
*pc
,
134 int argc
, char **argv
)
140 struct poptOption
*popts
;
146 list
= g_ptr_array_new();
148 g_hash_table_foreach(options
, list_options
, list
);
150 /* Build a popt options array from our list */
152 popts
= g_new(struct poptOption
, list
->len
+ 1);
154 for(i
= 0 ; i
< list
->len
; i
++) {
155 option
= (LttvOption
*)list
->pdata
[i
];
156 popts
[i
].longName
= option
->long_name
;
157 popts
[i
].shortName
= option
->char_name
;
158 popts
[i
].descrip
= option
->description
;
159 popts
[i
].argDescrip
= option
->arg_description
;
160 popts
[i
].argInfo
= poptToLTT
[option
->t
];
161 popts
[i
].arg
= option
->p
;
162 popts
[i
].val
= i
+ 1;
165 /* Terminate the array for popt and create the context */
167 popts
[list
->len
] = endOption
;
168 c
= poptGetContext(argv
[0], argc
, (const char**)argv
, popts
, 0);
177 destroy_popts(GPtrArray
**plist
, struct poptOption
**ppopts
, poptContext
*pc
)
179 g_ptr_array_free(*plist
, TRUE
); *plist
= NULL
;
180 g_free(*ppopts
); *ppopts
= NULL
;
181 poptFreeContext(*pc
);
185 void lttv_option_parse(int argc
, char **argv
)
191 int i
, rc
, first_arg
;
193 struct poptOption
*popts
;
201 build_popts(&list
, &popts
, &c
, argc
, argv
);
203 /* Parse options while not end of options event */
205 while((rc
= poptGetNextOpt(c
)) != -1) {
207 /* The option was recognized and the rc value returned is the argument
208 position in the array. Call the associated hook if present. */
211 option
= (LttvOption
*)(list
->pdata
[rc
- 1]);
212 g_info("Option %s encountered", option
->long_name
);
213 if(option
->hook
!= NULL
) {
214 g_info("Option %s hook called", option
->long_name
);
215 option
->hook(option
->hook_data
);
220 else if(rc
== POPT_ERROR_BADOPT
&& i
!= first_arg
) {
221 g_info("Option %s not recognized, rescan options with new additions",
224 /* Perhaps this option is newly added, restart parsing */
226 destroy_popts(&list
, &popts
, &c
);
227 build_popts(&list
, &popts
, &c
, argc
, argv
);
229 /* Get back to the same argument */
232 for(i
= 0; i
< first_arg
; i
++) {
233 rc
= poptGetNextOpt(c
);
234 option
= (LttvOption
*)(list
->pdata
[rc
- 1]);
235 g_info("Option %s rescanned, skipped", option
->long_name
);
241 /* The option has some error and it is not because this is a newly
242 added option not recognized. */
244 g_error("option %s: %s", poptBadOption(c
,0), poptStrerror(rc
));
250 destroy_popts(&list
, &popts
, &c
);
253 static void show_help(LttvOption
*option
)
255 printf("--%s -%c argument: %s\n" , option
->long_name
,
257 option
->arg_description
);
258 printf(" %s\n" , option
->description
);
262 void lttv_option_show_help(void)
266 GPtrArray
*list
= g_ptr_array_new();
270 g_hash_table_foreach(options
, list_options
, list
);
272 printf("Built-in commands available:\n");
275 for(i
= 0 ; i
< list
->len
; i
++) {
276 show_help((LttvOption
*)list
->pdata
[i
]);
278 g_ptr_array_free(list
, TRUE
);
This page took 0.084438 seconds and 4 git commands to generate.