7 /* Extensible array of popt command line options. Modules add options as
8 they are loaded and initialized. */
10 typedef struct _lttv_option
{
11 lttv_option_hook hook
;
15 static GArray
*lttv_options_command
;
17 static GArray
*lttv_options_command_popt
;
19 // unneeded static lttv_key *key ;
21 static int command_argc
;
23 static char **command_argv
;
25 /* Lists of hooks to be called at different places */
28 *hooks_options_before
,
31 static gboolean init_done
= FALSE
;
33 void lttv_options_command_parse(void *hook_data
, void *call_data
);
36 void lttv_option_init(int argc
, char **argv
) {
38 lttv_hooks
*hooks_init_after
;
41 else init_done
= TRUE
;
46 hooks_options_before
= lttv_hooks_new();
47 hooks_options_after
= lttv_hooks_new();
49 lttv_attributes_set_pointer_pathname(lttv_global_attributes(),
50 "hooks/options/before", hooks_options_before
);
52 lttv_attributes_set_pointer_pathname(lttv_global_attributes(),
53 "hooks/options/after", hooks_options_after
);
55 lttv_options_command_popt
= g_array_new(0,0,sizeof(struct poptOption
));
56 lttv_options_command
= g_array_new(0,0,sizeof(lttv_option
));
58 hooks_init_after
= lttv_attributes_get_pointer_pathname(lttv_global_attributes(),
60 lttv_hooks_add(hooks_init_after
, lttv_options_command_parse
, NULL
);
64 void lttv_option_destroy() {
66 struct poptOption
*poption
;
68 for(i
=0; i
<lttv_options_command_popt
->len
,i
++) {
69 poption
= &g_array_index (lttv_options_command_popt
, struct poptOption
, i
);
71 g_free(poption
.longName
);
72 g_free(poption
.shortName
);
73 g_free(poption
.descrip
);
74 g_free(poption
.argDescrip
);
76 g_array_free(lttv_options_command_popt
,TRUE
) ;
77 g_array_free(lttv_options_command
,TRUE
) ;
79 lttv_attributes_set_pointer_pathname(lttv_global_attributes(),
80 "hooks/options/before", NULL
);
82 lttv_attributes_set_pointer_pathname(lttv_global_attributes(),
83 "hooks/options/after", NULL
);
85 lttv_hooks_destroy(hooks_options_before
);
86 lttv_hooks_destroy(hooks_options_after
);
91 static int poptToLTT
[] = {
92 POPT_ARG_NONE
, POPT_ARG_STRING
, POPT_ARG_INT
, POPT_ARG_LONG
96 void lttv_option_add(const char *long_name
, const char char_name
,
97 const char *description
, const char *argDescription
,
98 const lttv_option_type t
, const void *p
,
99 const lttv_option_hook h
, void *hook_data
)
101 struct poptOption poption
;
105 poption
.longName
= (char *)g_strdup(long_name
);
106 poption
.shortName
= char_name
;
107 poption
.descrip
= (char *)g_strdup(description
);
108 poption
.argDescrip
= (char *)g_strdup(argDescription
);
109 poption
.argInfo
= poptToLTT
[t
];
111 poption
.val
= lttv_options_command
->len
+ 1;
114 option
.hook_data
= hook_data
;
116 g_array_append_val(lttv_options_command_popt
,poption
);
117 g_array_append_val(lttv_options_command
,option
);
121 static struct poptOption endOption
= { NULL
, '\0', 0, NULL
, 0};
123 /* As we may load modules in the hooks called for argument processing,
124 * we have to recreate the argument context each time the
125 * lttv_options_command_popt is modified. This way we will be able to
126 * parse arguments defined by the modules
129 void lttv_options_command_parse(void *hook_data
, void *call_data
)
136 lttv_hooks_call(hooks_options_before
,NULL
);
137 /* Always add then remove the null option around the get context */
138 g_array_append_val(lttv_options_command_popt
, endOption
);
139 /* Compiler warning caused by const char ** for command_argv in header */
140 /* Nothing we can do about it. Header should not put it const. */
141 c
= poptGetContext("lttv", command_argc
, (const char**)command_argv
,
142 (struct poptOption
*)(lttv_options_command_popt
->data
),0);
144 /* We remove the null option here to be able to add options correctly */
145 g_array_remove_index(lttv_options_command_popt
,
146 lttv_options_command_popt
->len
- 1);
148 /* There is no last good offset */
151 /* Parse options while not end of options event */
152 while((rc
= poptGetNextOpt(c
)) != -1) {
154 if(rc
== POPT_ERROR_BADOPT
) {
155 /* We need to redo the context with information added by modules */
156 g_array_append_val(lttv_options_command_popt
, endOption
);
158 c
= poptGetContext("lttv", command_argc
, (const char**)command_argv
,
159 (struct poptOption
*)lttv_options_command_popt
->data
,0);
160 g_array_remove_index(lttv_options_command_popt
,
161 lttv_options_command_popt
->len
);
163 /* Cut out the already parsed elements */
165 while(poptGetNextOpt(c
) != lastrc
) { } ;
167 /* Get the same option once again */
168 g_assert(rc
= poptGetNextOpt(c
) != -1) ;
169 if(rc
== POPT_ERROR_BADOPT
) {
170 /* If here again we have a parsing error with all context info ok,
171 * then there is a problem in the arguments themself, give up */
172 g_critical("option %s: %s", poptBadOption(c
,0), poptStrerror(rc
));
177 /* Remember this offset as the last good option value */
180 /* Execute the hook registered with this option */
181 option
= ((lttv_option
*)lttv_options_command
->data
) + rc
- 1;
182 if(option
->hook
!= NULL
) option
->hook(option
->hook_data
);
188 lttv_hooks_call(hooks_options_after
,NULL
);