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 extern lttv_attributes
*attributes_global
;
17 static GArray
*lttv_options_command
;
19 static GArray
*lttv_options_command_popt
;
21 // unneeded static lttv_key *key ;
23 static int command_argc
;
25 static char **command_argv
;
27 /* Lists of hooks to be called at different places */
30 *hooks_options_before
,
33 static gboolean init_done
= FALSE
;
35 void lttv_options_command_parse(void *hook_data
, void *call_data
);
38 void lttv_option_init(int argc
, char **argv
) {
40 lttv_hooks
*hooks_init_after
;
43 else init_done
= TRUE
;
48 hooks_options_before
= lttv_hooks_new();
49 hooks_options_after
= lttv_hooks_new();
51 lttv_attributes_set_pointer_pathname(attributes_global
,
52 "hooks/options/before", hooks_options_before
);
54 lttv_attributes_set_pointer_pathname(attributes_global
,
55 "hooks/options/after", hooks_options_after
);
57 lttv_options_command_popt
= g_array_new(0,0,sizeof(struct poptOption
));
58 lttv_options_command
= g_array_new(0,0,sizeof(lttv_option
));
60 hooks_init_after
= lttv_attributes_get_pointer_pathname(attributes_global
,
62 lttv_hooks_add(hooks_init_after
, lttv_options_command_parse
, NULL
);
66 void lttv_option_destroy() {
68 g_array_free(lttv_options_command_popt
,TRUE
) ;
69 g_array_free(lttv_options_command
,TRUE
) ;
71 lttv_attributes_set_pointer_pathname(attributes_global
,
72 "hooks/options/before", NULL
);
74 lttv_attributes_set_pointer_pathname(attributes_global
,
75 "hooks/options/after", NULL
);
77 lttv_hooks_destroy(hooks_options_before
);
78 lttv_hooks_destroy(hooks_options_after
);
83 static int poptToLTT
[] = {
84 POPT_ARG_NONE
, POPT_ARG_STRING
, POPT_ARG_INT
, POPT_ARG_LONG
88 void lttv_option_add(char *long_name
, char char_name
, char *description
,
89 char *argDescription
, lttv_option_type t
, void *p
,
90 lttv_option_hook h
, void *hook_data
)
92 struct poptOption poption
;
96 poption
.longName
= long_name
;
97 poption
.shortName
= char_name
;
98 poption
.descrip
= description
;
99 poption
.argDescrip
= argDescription
;
100 poption
.argInfo
= poptToLTT
[t
];
102 poption
.val
= lttv_options_command
->len
+ 1;
105 option
.hook_data
= hook_data
;
107 g_array_append_val(lttv_options_command_popt
,poption
);
108 g_array_append_val(lttv_options_command
,option
);
112 static struct poptOption endOption
= { NULL
, '\0', 0, NULL
, 0};
114 /* As we may load modules in the hooks called for argument processing,
115 * we have to recreate the argument context each time the
116 * lttv_options_command_popt is modified. This way we will be able to
117 * parse arguments defined by the modules
120 void lttv_options_command_parse(void *hook_data
, void *call_data
)
127 lttv_hooks_call(hooks_options_before
,NULL
);
128 /* Always add then remove the null option around the get context */
129 g_array_append_val(lttv_options_command_popt
, endOption
);
130 /* Compiler warning caused by const char ** for command_argv in header */
131 /* Nothing we can do about it. Header should not put it const. */
132 c
= poptGetContext("lttv", command_argc
, (const char**)command_argv
,
133 (struct poptOption
*)(lttv_options_command_popt
->data
),0);
135 /* We remove the null option here to be able to add options correctly */
136 g_array_remove_index(lttv_options_command_popt
,
137 lttv_options_command_popt
->len
- 1);
139 /* There is no last good offset */
142 /* Parse options while not end of options event */
143 while((rc
= poptGetNextOpt(c
)) != -1) {
145 if(rc
== POPT_ERROR_BADOPT
) {
146 /* We need to redo the context with information added by modules */
147 g_array_append_val(lttv_options_command_popt
, endOption
);
149 c
= poptGetContext("lttv", command_argc
, (const char**)command_argv
,
150 (struct poptOption
*)lttv_options_command_popt
->data
,0);
151 g_array_remove_index(lttv_options_command_popt
,
152 lttv_options_command_popt
->len
);
154 /* Cut out the already parsed elements */
156 while(poptGetNextOpt(c
) != lastrc
) { } ;
158 /* Get the same option once again */
159 g_assert(rc
= poptGetNextOpt(c
) != -1) ;
160 if(rc
== POPT_ERROR_BADOPT
) {
161 /* If here again we have a parsing error with all context info ok,
162 * then there is a problem in the arguments themself, give up */
163 g_critical("option %s: %s", poptBadOption(c
,0), poptStrerror(rc
));
168 /* Remember this offset as the last good option value */
171 /* Execute the hook registered with this option */
172 option
= ((lttv_option
*)lttv_options_command
->data
) + rc
- 1;
173 if(option
->hook
!= NULL
) option
->hook(option
->hook_data
);
179 lttv_hooks_call(hooks_options_after
,NULL
);