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 g_array_free(lttv_options_command_popt
,TRUE
) ;
67 g_array_free(lttv_options_command
,TRUE
) ;
69 lttv_attributes_set_pointer_pathname(lttv_global_attributes(),
70 "hooks/options/before", NULL
);
72 lttv_attributes_set_pointer_pathname(lttv_global_attributes(),
73 "hooks/options/after", NULL
);
75 lttv_hooks_destroy(hooks_options_before
);
76 lttv_hooks_destroy(hooks_options_after
);
81 static int poptToLTT
[] = {
82 POPT_ARG_NONE
, POPT_ARG_STRING
, POPT_ARG_INT
, POPT_ARG_LONG
86 void lttv_option_add(char *long_name
, char char_name
, char *description
,
87 char *argDescription
, lttv_option_type t
, void *p
,
88 lttv_option_hook h
, void *hook_data
)
90 struct poptOption poption
;
94 poption
.longName
= long_name
;
95 poption
.shortName
= char_name
;
96 poption
.descrip
= description
;
97 poption
.argDescrip
= argDescription
;
98 poption
.argInfo
= poptToLTT
[t
];
100 poption
.val
= lttv_options_command
->len
+ 1;
103 option
.hook_data
= hook_data
;
105 g_array_append_val(lttv_options_command_popt
,poption
);
106 g_array_append_val(lttv_options_command
,option
);
110 static struct poptOption endOption
= { NULL
, '\0', 0, NULL
, 0};
112 /* As we may load modules in the hooks called for argument processing,
113 * we have to recreate the argument context each time the
114 * lttv_options_command_popt is modified. This way we will be able to
115 * parse arguments defined by the modules
118 void lttv_options_command_parse(void *hook_data
, void *call_data
)
125 lttv_hooks_call(hooks_options_before
,NULL
);
126 /* Always add then remove the null option around the get context */
127 g_array_append_val(lttv_options_command_popt
, endOption
);
128 /* Compiler warning caused by const char ** for command_argv in header */
129 /* Nothing we can do about it. Header should not put it const. */
130 c
= poptGetContext("lttv", command_argc
, (const char**)command_argv
,
131 (struct poptOption
*)(lttv_options_command_popt
->data
),0);
133 /* We remove the null option here to be able to add options correctly */
134 g_array_remove_index(lttv_options_command_popt
,
135 lttv_options_command_popt
->len
- 1);
137 /* There is no last good offset */
140 /* Parse options while not end of options event */
141 while((rc
= poptGetNextOpt(c
)) != -1) {
143 if(rc
== POPT_ERROR_BADOPT
) {
144 /* We need to redo the context with information added by modules */
145 g_array_append_val(lttv_options_command_popt
, endOption
);
147 c
= poptGetContext("lttv", command_argc
, (const char**)command_argv
,
148 (struct poptOption
*)lttv_options_command_popt
->data
,0);
149 g_array_remove_index(lttv_options_command_popt
,
150 lttv_options_command_popt
->len
);
152 /* Cut out the already parsed elements */
154 while(poptGetNextOpt(c
) != lastrc
) { } ;
156 /* Get the same option once again */
157 g_assert(rc
= poptGetNextOpt(c
) != -1) ;
158 if(rc
== POPT_ERROR_BADOPT
) {
159 /* If here again we have a parsing error with all context info ok,
160 * then there is a problem in the arguments themself, give up */
161 g_critical("option %s: %s", poptBadOption(c
,0), poptStrerror(rc
));
166 /* Remember this offset as the last good option value */
169 /* Execute the hook registered with this option */
170 option
= ((lttv_option
*)lttv_options_command
->data
) + rc
- 1;
171 if(option
->hook
!= NULL
) option
->hook(option
->hook_data
);
177 lttv_hooks_call(hooks_options_after
,NULL
);