4 #include <lttv/option.h>
6 typedef struct _LttvOption
{
10 char *arg_description
;
21 list_options(gpointer key
, gpointer value
, gpointer user_data
)
23 g_ptr_array_add((GPtrArray
*)user_data
, value
);
28 free_option(LttvOption
*option
)
30 g_free(option
->long_name
);
31 g_free(option
->description
);
32 g_free(option
->arg_description
);
37 void lttv_option_init(int argc
, char **argv
)
39 options
= g_hash_table_new(g_str_hash
, g_str_equal
);
43 void lttv_option_destroy()
47 GPtrArray
*list
= g_ptr_array_new();
51 g_hash_table_foreach(options
, list_options
, list
);
52 g_hash_table_destroy(options
);
54 for(i
= 0 ; i
< list
->len
; i
++) {
55 free_option((LttvOption
*)list
->pdata
[i
]);
57 g_ptr_array_free(list
, TRUE
);
61 void lttv_option_add(const char *long_name
, const char char_name
,
62 const char *description
, const char *arg_description
,
63 const LttvOptionType t
, void *p
,
64 const LttvOptionHook h
, void *hook_data
)
68 if(g_hash_table_lookup(options
, long_name
) != NULL
) {
69 g_warning("duplicate option");
73 option
= g_new(LttvOption
, 1);
74 option
->long_name
= g_strdup(long_name
);
75 option
->char_name
= char_name
;
76 option
->description
= g_strdup(description
);
77 option
->arg_description
= g_strdup(arg_description
);
81 option
->hook_data
= hook_data
;
82 g_hash_table_insert(options
, option
->long_name
, option
);
87 lttv_option_remove(const char *long_name
)
89 LttvOption
*option
= g_hash_table_lookup(options
, long_name
);
92 g_warning("trying to remove unknown option %s", long_name
);
95 g_hash_table_remove(options
, long_name
);
100 static int poptToLTT
[] = {
101 POPT_ARG_NONE
, POPT_ARG_STRING
, POPT_ARG_INT
, POPT_ARG_LONG
104 static struct poptOption endOption
= { NULL
, '\0', 0, NULL
, 0};
108 build_popts(GPtrArray
**plist
, struct poptOption
**ppopts
, poptContext
*pc
,
109 int argc
, char **argv
)
115 struct poptOption
*popts
;
121 list
= g_ptr_array_new();
123 g_hash_table_foreach(options
, list_options
, list
);
125 /* Build a popt options array from our list */
127 popts
= g_new(struct poptOption
, list
->len
+ 1);
129 for(i
= 0 ; i
< list
->len
; i
++) {
130 option
= (LttvOption
*)list
->pdata
[i
];
131 popts
[i
].longName
= option
->long_name
;
132 popts
[i
].shortName
= option
->char_name
;
133 popts
[i
].descrip
= option
->description
;
134 popts
[i
].argDescrip
= option
->arg_description
;
135 popts
[i
].argInfo
= poptToLTT
[option
->t
];
136 popts
[i
].arg
= option
->p
;
137 popts
[i
].val
= i
+ 1;
140 /* Terminate the array for popt and create the context */
142 popts
[list
->len
] = endOption
;
143 c
= poptGetContext(argv
[0], argc
, (const char**)argv
, popts
, 0);
152 destroy_popts(GPtrArray
**plist
, struct poptOption
**ppopts
, poptContext
*pc
)
154 g_ptr_array_free(*plist
, TRUE
); *plist
= NULL
;
155 g_free(*ppopts
); *ppopts
= NULL
;
156 poptFreeContext(*pc
);
160 void lttv_option_parse(int argc
, char **argv
)
166 int i
, rc
, first_arg
;
168 struct poptOption
*popts
;
176 build_popts(&list
, &popts
, &c
, argc
, argv
);
178 /* Parse options while not end of options event */
180 while((rc
= poptGetNextOpt(c
)) != -1) {
182 /* The option was recognized and the rc value returned is the argument
183 position in the array. Call the associated hook if present. */
186 option
= (LttvOption
*)(list
->pdata
[rc
- 1]);
187 if(option
->hook
!= NULL
) option
->hook(option
->hook_data
);
191 else if(rc
== POPT_ERROR_BADOPT
&& i
!= first_arg
) {
193 /* Perhaps this option is newly added, restart parsing */
195 destroy_popts(&list
, &popts
, &c
);
196 build_popts(&list
, &popts
, &c
, argc
, argv
);
198 /* Get back to the same argument */
201 for(i
= 0; i
< first_arg
; i
++) poptGetNextOpt(c
);
206 /* The option has some error and it is not because this is a newly
207 added option not recognized. */
209 g_error("option %s: %s", poptBadOption(c
,0), poptStrerror(rc
));
215 destroy_popts(&list
, &popts
, &c
);
This page took 0.037085 seconds and 4 git commands to generate.