1 /****************************************************************\
2 * *
3 * Library for command line argument processing *
4 * *
5 * Guy St.C. Slater.. mailto:guy@ebi.ac.uk *
6 * Copyright (C) 2000-2009. All Rights Reserved. *
7 * *
8 * This source code is distributed under the terms of the *
9 * GNU General Public License, version 3. See the file COPYING *
10 * or http://www.gnu.org/licenses/gpl.txt for details *
11 * *
12 * If you use this code, please keep this notice intact. *
13 * *
14 \****************************************************************/
15
16 #include "argument.h"
17 #include <stdio.h> /* For fprintf() */
18 #include <stdlib.h> /* For exit() */
19 #include <string.h> /* For strlen() */
20 #include <ctype.h> /* For isalnum() */
21 #include <unistd.h> /* For gethostname() */
22
ArgumentOption_create(ArgumentSet * as,gchar symbol,gchar * option,gchar * type,gchar * desc,gchar * default_string,ArgumentHandler handler,gpointer handler_data)23 static ArgumentOption *ArgumentOption_create(ArgumentSet *as,
24 gchar symbol,
25 gchar *option,
26 gchar *type,
27 gchar *desc,
28 gchar *default_string,
29 ArgumentHandler handler,
30 gpointer handler_data){
31 register ArgumentOption *ao= g_new(ArgumentOption, 1);
32 ao->as = as;
33 ao->symbol = symbol;
34 ao->option = g_strdup(option);
35 ao->arg_value = NULL;
36 ao->desc = g_strdup(desc);
37 ao->type = g_strdup(type);
38 ao->default_string = g_strdup(default_string);
39 ao->handler = handler;
40 ao->handler_data = handler_data;
41 ao->env_var = NULL;
42 if(handler)
43 ao->arg_list = NULL;
44 else
45 ao->arg_list = g_ptr_array_new();
46 return ao;
47 }
48
ArgumentOption_destroy(ArgumentOption * ao)49 static void ArgumentOption_destroy(ArgumentOption *ao){
50 g_free(ao->option);
51 g_free(ao->desc);
52 g_free(ao->type);
53 g_free(ao->default_string);
54 g_free(ao->env_var);
55 if(ao->arg_list)
56 g_ptr_array_free(ao->arg_list, TRUE);
57 g_free(ao);
58 return;
59 }
60
ArgumentSet_destroy(ArgumentSet * as)61 static void ArgumentSet_destroy(ArgumentSet *as){
62 register gint i;
63 register ArgumentOption *ao;
64 for(i = 0; i < as->arg_option->len; i++){
65 ao = as->arg_option->pdata[i];
66 ArgumentOption_destroy(ao);
67 }
68 g_ptr_array_free(as->arg_option, TRUE);
69 g_free(as->desc);
70 g_free(as);
71 return;
72 }
73
ArgumentOption_print_values(ArgumentOption * ao,gint use_long)74 static void ArgumentOption_print_values(ArgumentOption *ao,
75 gint use_long){
76 register gint i;
77 if(ao->arg_list){
78 if(ao->arg_list->len){
79 if((!ao->default_string)
80 || ((ao->arg_list->len == 1)
81 && strcmp(ao->default_string,
82 ao->arg_list->pdata[0]))){
83 g_print("{%s", (gchar*)ao->arg_list->pdata[0]);
84 for(i = 1; i < ao->arg_list->len; i++)
85 g_print(":%s", (gchar*)ao->arg_list->pdata[i]);
86 g_print("}");
87 }
88 } else {
89 g_print(" <*** empty list ***>");
90 }
91 } else {
92 if(ao->arg_value){
93 if((!ao->default_string)
94 || strcmp(ao->default_string, ao->arg_value)){
95 if(use_long)
96 g_print("Using: ");
97 g_print("<%s>", ao->arg_value);
98 }
99 } else {
100 g_print(" <*** not set ***>");
101 }
102 }
103 return;
104 }
105
ArgumentOption_is_set(ArgumentOption * ao)106 static gboolean ArgumentOption_is_set(ArgumentOption *ao){
107 if(ao->arg_list)
108 return ao->arg_list->len?TRUE:FALSE;
109 return ao->arg_value?TRUE:FALSE;
110 }
111
ArgumentOption_add_value(ArgumentOption * ao,GPtrArray * error_queue,gchar * value)112 static void ArgumentOption_add_value(ArgumentOption *ao,
113 GPtrArray *error_queue, gchar *value){
114 if(ao->arg_list){
115 g_ptr_array_add(ao->arg_list, value);
116 } else {
117 if(ao->arg_value)
118 g_ptr_array_add(error_queue,
119 g_strdup_printf("Already set --%s to \"%s\"",
120 ao->option, ao->arg_value));
121 else
122 ao->arg_value = value;
123 }
124 return;
125 }
126
ArgumentOption_is_mandatory(ArgumentOption * ao)127 static gboolean ArgumentOption_is_mandatory(ArgumentOption *ao){
128 return ao->default_string?FALSE:TRUE;
129 }
130
131 /**/
132
ArgumentParse_boolean(gchar * arg_string)133 static gboolean ArgumentParse_boolean(gchar *arg_string){
134 register gint i;
135 gchar *true_string[6] = {"Y", "T", "TRUE", "YES", "ON", "1"},
136 *false_string[6] = {"N", "F", "FALSE", "NO", "OFF", "0"};
137 for(i = 0; i < 6; i++){
138 if(!g_strcasecmp(arg_string, true_string[i]))
139 return TRUE;
140 if(!g_strcasecmp(arg_string, false_string[i]))
141 return FALSE;
142 }
143 g_error("Cannot parse boolean \"%s\"", arg_string);
144 return FALSE;
145 }
146 /* FIXME: change to work with error listing
147 */
148
ArgumentHandler_short_help_func(gchar * arg_string,gpointer data)149 static gchar *ArgumentHandler_short_help_func(gchar *arg_string,
150 gpointer data){
151 register Argument *arg = (Argument*)data;
152 if(ArgumentParse_boolean(arg_string))
153 arg->show_short_help = TRUE;
154 return NULL;
155 }
156
ArgumentHandler_long_help_func(gchar * arg_string,gpointer data)157 static gchar *ArgumentHandler_long_help_func(gchar *arg_string,
158 gpointer data){
159 register Argument *arg = (Argument*)data;
160 if(ArgumentParse_boolean(arg_string))
161 arg->show_long_help = TRUE;
162 return NULL;
163 }
164
Argument_show_version(Argument * arg)165 static void Argument_show_version(Argument *arg){
166 register gchar *branch = "$Name: $";
167 g_print("%s from %s version %s\n",
168 arg->name, PACKAGE, VERSION);
169 g_print("Using glib version %d.%d.%d\n",
170 GLIB_MAJOR_VERSION,
171 GLIB_MINOR_VERSION,
172 GLIB_MICRO_VERSION);
173 g_print("Built on %s\n", __DATE__);
174 if(strlen(branch) >= 10)
175 g_print("Branch: %.*s\n", (gint)(strlen(branch)-9), branch+7);
176 return;
177 }
178
ArgumentHandler_version_func(gchar * arg_string,gpointer data)179 static gchar *ArgumentHandler_version_func(gchar *arg_string,
180 gpointer data){
181 register Argument *arg = (Argument*)data;
182 if(ArgumentParse_boolean(arg_string)){
183 Argument_show_version(arg);
184 exit(1);
185 }
186 return NULL;
187 }
188
Argument_add_standard_options(Argument * arg)189 static void Argument_add_standard_options(Argument *arg){
190 register ArgumentSet *as = ArgumentSet_create("General Options");
191 ArgumentSet_add_option(as, 'h', "shorthelp", NULL,
192 "Display compact help text",
193 "FALSE", ArgumentHandler_short_help_func, arg);
194 ArgumentSet_add_option(as, '\0', "help", NULL,
195 "Displays verbose help text",
196 "FALSE", ArgumentHandler_long_help_func, arg);
197 ArgumentSet_add_option(as, 'v', "version", NULL,
198 "Show version number for this program",
199 "FALSE", ArgumentHandler_version_func, arg);
200 Argument_absorb_ArgumentSet(arg, as);
201 return;
202 }
203
204 /**/
205
206 typedef struct {
207 Argument_Cleanup_Func cleanup_func;
208 gpointer user_data;
209 } Argument_Cleanup;
210
Argument_add_cleanup(Argument * arg,Argument_Cleanup_Func cleanup_func,gpointer user_data)211 void Argument_add_cleanup(Argument *arg,
212 Argument_Cleanup_Func cleanup_func,
213 gpointer user_data){
214 register Argument_Cleanup *cleanup = g_new(Argument_Cleanup, 1);
215 cleanup->cleanup_func = cleanup_func;
216 cleanup->user_data = user_data;
217 g_ptr_array_add(arg->cleanup_list, cleanup);
218 return;
219 }
220
Argument_cleanup(Argument * arg)221 static void Argument_cleanup(Argument *arg){
222 register Argument_Cleanup *cleanup;
223 register gint i;
224 for(i = 0; i < arg->cleanup_list->len; i++){
225 cleanup = arg->cleanup_list->pdata[i];
226 cleanup->cleanup_func(cleanup->user_data);
227 g_free(cleanup);
228 }
229 return;
230 }
231
232 /**/
233
Argument_strcmp_compare(gconstpointer a,gconstpointer b)234 static gint Argument_strcmp_compare(gconstpointer a, gconstpointer b){
235 return strcmp((gchar*)a, (gchar*)b);
236 }
237
Argument_create(gint argc,gchar ** argv)238 static Argument *Argument_create(gint argc, gchar **argv){
239 register Argument *arg = g_new0(Argument, 1);
240 arg->arg_set = g_ptr_array_new();
241 arg->mandatory_set = g_ptr_array_new();
242 arg->cleanup_list = g_ptr_array_new();
243 arg->option_registry = g_tree_new(Argument_strcmp_compare);
244 arg->argc = argc;
245 arg->argv = argv;
246 Argument_add_standard_options(arg);
247 return arg;
248 }
249
Argument_destroy(Argument * arg)250 static void Argument_destroy(Argument *arg){
251 register ArgumentSet *as;
252 register gint i;
253 for(i = 0; i < arg->arg_set->len; i++){
254 as = arg->arg_set->pdata[i];
255 ArgumentSet_destroy(as);
256 }
257 Argument_cleanup(arg);
258 g_ptr_array_free(arg->cleanup_list, TRUE);
259 g_ptr_array_free(arg->mandatory_set, TRUE);
260 g_ptr_array_free(arg->arg_set, TRUE);
261 g_tree_destroy(arg->option_registry);
262 g_free(arg->name);
263 g_free(arg->desc);
264 g_free(arg);
265 return;
266 }
267
Argument_assertion_warning(void)268 static gboolean Argument_assertion_warning(void){
269 g_warning("Compiled with assertion checking - will run slowly");
270 return TRUE;
271 }
272
Argument_error_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer user_data)273 static void Argument_error_handler(const gchar *log_domain,
274 GLogLevelFlags log_level,
275 const gchar *message,
276 gpointer user_data){
277 register Argument *arg = user_data;
278 register gchar
279 *stack_trace_str = (gchar*)g_getenv("EXONERATE_DEBUG_STACK_TRACE"),
280 *debug_str = (gchar*)g_getenv("EXONERATE_DEBUG");
281 fprintf(stderr, "** FATAL ERROR **: %s\n", message);
282 if(stack_trace_str
283 && ArgumentParse_boolean(stack_trace_str)){
284 fprintf(stderr, "Generating stack trace ...\n");
285 g_on_error_stack_trace(arg->name);
286 }
287 if(debug_str
288 && ArgumentParse_boolean(debug_str)){
289 fprintf(stderr, "Calling abort...\n");
290 abort();
291 }
292 fprintf(stderr, "exiting ...\n");
293 Argument_destroy(arg);
294 exit(1);
295 return;
296 }
297 /* This is probably not what one is supposed to do with glib,
298 * but it is to stop g_error() calling abort() and core dumping.
299 * Maybe switch to g_critical() after glib-2 migration.
300 */
301
main(int argc,char ** argv)302 int main(int argc, char **argv){
303 register Argument *arg;
304 register gint retval;
305 #ifdef USE_PTHREADS
306 if(!g_thread_supported())
307 g_thread_init(NULL);
308 #endif /* USE_PTHREADS */
309 arg = Argument_create(argc, argv);
310 g_log_set_handler(NULL, G_LOG_LEVEL_ERROR|G_LOG_FLAG_FATAL,
311 Argument_error_handler, arg);
312 g_assert(Argument_assertion_warning());
313 retval = Argument_main(arg);
314 Argument_destroy(arg);
315 return retval;
316 }
317
Argument_usage(Argument * arg,gchar * synopsis)318 static void Argument_usage(Argument *arg, gchar *synopsis){
319 register ArgumentOption *ao;
320 register gint i;
321 Argument_show_version(arg);
322 g_print("\n%s: %s\n", arg->name, arg->desc);
323 if(synopsis){
324 g_print("%s\n", synopsis);
325 } else {
326 g_print("Synopsis:\n--------\n%s", arg->name);
327 for(i = 0; i < arg->mandatory_set->len; i++){
328 ao = arg->mandatory_set->pdata[i];
329 g_print(" <%s>", ao->type);
330 }
331 g_print("\n\n");
332 }
333 return;
334 }
335
Argument_short_help(Argument * arg)336 static void Argument_short_help(Argument *arg){
337 register ArgumentSet *as;
338 register ArgumentOption *ao;
339 register gint i, j;
340 for(i = 0; i < arg->arg_set->len; i++){
341 as = arg->arg_set->pdata[i];
342 if(as->arg_option->len){
343 g_print("%s:\n", as->desc);
344 for(j = strlen(as->desc); j > 0; j--)
345 g_print("-");
346 g_print("\n");
347 for(j = 0; j < as->arg_option->len; j++){
348 ao = as->arg_option->pdata[j];
349 if(ao->symbol)
350 g_print("-%c ", ao->symbol);
351 else
352 g_print(" ");
353 g_print("--%s", ao->option);
354 if(ao->default_string)
355 g_print(" [%s]", ao->default_string);
356 else
357 g_print(" [mandatory]");
358 g_print(" ");
359 ArgumentOption_print_values(ao, FALSE);
360 g_print("\n");
361 }
362 g_print("\n");
363 }
364 }
365 g_print("--\n");
366 return;
367 }
368
Argument_long_help(Argument * arg)369 static void Argument_long_help(Argument *arg){
370 register ArgumentSet *as;
371 register ArgumentOption *ao;
372 register gint i, j;
373 register gchar *env_value;
374 for(i = 0; i < arg->arg_set->len; i++){
375 as = arg->arg_set->pdata[i];
376 if(as->arg_option->len){
377 g_print("%s:\n", as->desc);
378 for(j = strlen(as->desc); j > 0; j--)
379 g_print("-");
380 g_print("\n\n");
381 for(j = 0; j < as->arg_option->len; j++){
382 ao = as->arg_option->pdata[j];
383 if(ao->symbol)
384 g_print("-%c ", ao->symbol);
385 g_print("--%s", ao->option);
386 if(ao->type)
387 g_print(" <%s>", ao->type);
388 g_print("\n%s\n", ao->desc);
389 g_print("Environment variable: $%s", ao->env_var);
390 env_value = (gchar*)g_getenv(ao->env_var);
391 if(env_value){
392 g_print(" (Set to \"%s\")\n", env_value);
393 } else {
394 g_print(" (Not set)\n");
395 }
396 if(ao->default_string)
397 g_print("Default: \"%s\"\n", ao->default_string);
398 else
399 g_print("*** This argument is mandatory ***\n");
400 ArgumentOption_print_values(ao, TRUE);
401 g_print("\n");
402 }
403 }
404 }
405 g_print("--\n");
406 return;
407 }
408
Argument_set_env_var_func(gpointer key,gpointer value,gpointer data)409 static gint Argument_set_env_var_func(gpointer key,
410 gpointer value,
411 gpointer data){
412 register ArgumentOption *ao = (ArgumentOption*)value;
413 register gchar *name = (gchar*)data;
414 register gint i;
415 ao->env_var = g_strdup_printf("%s_%s_%s",
416 PACKAGE, name, ao->option);
417 for(i = strlen(ao->env_var)-1; i >= 0; i--)
418 if(isalnum(ao->env_var[i]))
419 ao->env_var[i] = toupper(ao->env_var[i]);
420 else
421 ao->env_var[i] = '_';
422 return FALSE;
423 }
424
Argument_traverse_registry_func(gpointer key,gpointer value,gpointer data)425 static gint Argument_traverse_registry_func(gpointer key,
426 gpointer value,
427 gpointer data){
428 register ArgumentOption *ao = (ArgumentOption*)value;
429 register GPtrArray *error_queue = (GPtrArray*)data;
430 register gchar *err_msg, *env_var;
431 if(!ArgumentOption_is_set(ao)){
432 env_var = (gchar*)g_getenv(ao->env_var);
433 if(env_var)
434 ArgumentOption_add_value(ao, error_queue, env_var);
435 }
436 if(!ArgumentOption_is_set(ao)){
437 if(ArgumentOption_is_mandatory(ao)){
438 g_ptr_array_add(error_queue,
439 g_strdup_printf(
440 "No value set for mandatory argument --%s <%s>",
441 ao->option, ao->type));
442 return FALSE;
443 } else {
444 ArgumentOption_add_value(ao, error_queue,
445 ao->default_string);
446 }
447 }
448 if(ao->handler){
449 err_msg = ao->handler(ao->arg_value, ao->handler_data);
450 if(err_msg)
451 g_ptr_array_add(error_queue, err_msg);
452 } else { /* List */
453 (*((GPtrArray**)ao->handler_data)) = ao->arg_list;
454 }
455 return FALSE;
456 }
457
Argument_process_get_option(Argument * arg,gchar * string,GPtrArray * error_queue)458 static ArgumentOption *Argument_process_get_option(Argument *arg,
459 gchar *string, GPtrArray *error_queue){
460 register ArgumentOption *ao = NULL;
461 register gint i;
462 if(string[0] == '-'){
463 if(string[1] == '-'){
464 ao = g_tree_lookup(arg->option_registry, string+2);
465 if(!ao)
466 g_ptr_array_add(error_queue,
467 g_strdup_printf("Unrecognised option \"%s\"",
468 string));
469 } else {
470 for(i = 1; string[i]; i++){
471 ao = arg->symbol_registry[(guchar)string[i]];
472 if(!ao)
473 g_error("Unknown flag [%c] in argument [%s]",
474 string[i], string);
475 if(string[i+1]) /* If not last symbol */
476 ArgumentOption_add_value(ao, error_queue, "TRUE");
477 }
478 }
479 }
480 return ao;
481 }
482
Argument_info(Argument * arg)483 void Argument_info(Argument *arg){
484 register gchar *cl = g_strjoinv(" ", arg->argv);
485 gchar hostname[1024];
486 g_print("Command line: [%s]\n", cl);
487 g_free(cl);
488 /**/
489 gethostname(hostname, 1024);
490 g_print("Hostname: [%s]\n", hostname);
491 return;
492 }
493
Argument_process(Argument * arg,gchar * name,gchar * desc,gchar * synopsis)494 void Argument_process(Argument *arg, gchar *name, gchar *desc,
495 gchar *synopsis){
496 register gint i;
497 register GPtrArray *unflagged_arg = g_ptr_array_new();
498 register ArgumentOption *ao;
499 register GPtrArray *error_queue = g_ptr_array_new();
500 arg->desc = desc?g_strdup(desc):g_strdup("");
501 arg->name = g_strdup(name);
502 g_tree_traverse(arg->option_registry, Argument_set_env_var_func,
503 G_IN_ORDER, arg->name);
504 if(arg->mandatory_set->len && (arg->argc <= 1)){
505 Argument_usage(arg, synopsis);
506 exit(1);
507 }
508 for(i = 1; i < arg->argc; i++){
509 ao = Argument_process_get_option(arg, arg->argv[i],
510 error_queue);
511 if(ao){ /* -? */
512 if(ao->type){ /* Not boolean */
513 if((i+1) == arg->argc){
514 g_ptr_array_add(error_queue,
515 g_strdup_printf("No argument supplied with %s",
516 arg->argv[i]));
517 } else {
518 if(ao->handler){ /* Not list */
519 ArgumentOption_add_value(ao, error_queue,
520 arg->argv[++i]);
521 } else { /* Is list */
522 do {
523 ArgumentOption_add_value(ao, error_queue,
524 arg->argv[i+1]);
525 i++;
526 } while(((i+1) < arg->argc)
527 && (arg->argv[i+1][0] != '-'));
528 }
529 }
530 } else { /* Is boolean */
531 if((i+1) == arg->argc){
532 ArgumentOption_add_value(ao, error_queue, "TRUE");
533 } else {
534 if(arg->argv[i+1][0] == '-'){
535 ArgumentOption_add_value(ao, error_queue,
536 "TRUE");
537 } else {
538 ArgumentOption_add_value(ao, error_queue,
539 arg->argv[i+1]);
540 i++;
541 }
542 }
543 }
544 } else { /* unflagged argument */
545 g_ptr_array_add(unflagged_arg, arg->argv[i]);
546 }
547 }
548 if(arg->mandatory_set->len < unflagged_arg->len){
549 g_ptr_array_add(error_queue,
550 g_strdup_printf("Too many unflagged arguments"));
551 } else {
552 for(i = 0; i < unflagged_arg->len; i++){
553 ao = arg->mandatory_set->pdata[i];
554 ArgumentOption_add_value(ao, error_queue,
555 unflagged_arg->pdata[i]);
556 }
557 }
558 g_ptr_array_free(unflagged_arg, TRUE);
559 g_tree_traverse(arg->option_registry,
560 Argument_traverse_registry_func,
561 G_IN_ORDER, error_queue);
562 if((!(arg->show_short_help | arg->show_long_help)
563 && error_queue->len)){
564 Argument_usage(arg, synopsis);
565 g_print("--\n"
566 "%d ERROR%s encountered in argument processing\n"
567 "--\n",
568 error_queue->len,
569 (error_queue->len > 1)?"S were":" was");
570 for(i = 0; i < error_queue->len; i++){
571 g_print("[ %d ] : %s\n",
572 i+1, (gchar*)error_queue->pdata[i]);
573 g_free(error_queue->pdata[i]);
574 }
575 g_print("--\n\n"
576 "Use -h or --help for more information on usage\n"
577 "\n");
578 exit(1);
579 }
580 if(arg->show_short_help){
581 Argument_usage(arg, synopsis);
582 Argument_short_help(arg);
583 exit(1);
584 }
585 if(arg->show_long_help){
586 Argument_usage(arg, synopsis);
587 Argument_long_help(arg);
588 exit(1);
589 }
590 g_ptr_array_free(error_queue, TRUE);
591 return;
592 }
593 /* FIXME: tidy */
594
ArgumentSet_create(gchar * desc)595 ArgumentSet *ArgumentSet_create(gchar *desc){
596 register ArgumentSet *as = g_new(ArgumentSet, 1);
597 g_assert(desc);
598 as->desc = g_strdup(desc);
599 as->arg_option = g_ptr_array_new();
600 return as;
601 }
602
Argument_absorb_ArgumentSet(Argument * arg,ArgumentSet * as)603 void Argument_absorb_ArgumentSet(Argument *arg, ArgumentSet *as){
604 register ArgumentOption *ao;
605 register gint i;
606 g_ptr_array_add(arg->arg_set, as);
607 for(i = 0; i < as->arg_option->len; i++){
608 ao = as->arg_option->pdata[i];
609 if(!ao->default_string)
610 g_ptr_array_add(arg->mandatory_set, ao);
611 if(ao->symbol){ /* Check option not already used */
612 g_assert(!arg->symbol_registry[(guchar)ao->symbol]);
613 arg->symbol_registry[(guchar)ao->symbol] = ao;
614 }
615 g_assert(!g_tree_lookup(arg->option_registry, ao));
616 g_tree_insert(arg->option_registry, ao->option, ao);
617 }
618 return;
619 }
620
ArgumentSet_add_option(ArgumentSet * as,gchar symbol,gchar * option,gchar * type,gchar * desc,gchar * default_string,ArgumentHandler handler,gpointer handler_data)621 void ArgumentSet_add_option(ArgumentSet *as,
622 gchar symbol,
623 gchar *option,
624 gchar *type,
625 gchar *desc,
626 gchar *default_string,
627 ArgumentHandler handler,
628 gpointer handler_data){
629 register ArgumentOption *ao = ArgumentOption_create(
630 as, symbol, option, type, desc,
631 default_string, handler, handler_data);
632 g_ptr_array_add(as->arg_option, ao);
633 return;
634 }
635
Argument_parse_string(gchar * arg_string,gpointer data)636 gchar *Argument_parse_string(gchar *arg_string, gpointer data){
637 register gchar **dst_string = (gchar**)data;
638 if(!strcasecmp(arg_string, "NULL"))
639 (*dst_string) = NULL;
640 else
641 (*dst_string) = arg_string;
642 return NULL;
643 }
644
Argument_parse_char(gchar * arg_string,gpointer data)645 gchar *Argument_parse_char(gchar *arg_string, gpointer data){
646 register gchar *dst_char = (gchar*)data;
647 if((!arg_string[0]) || (arg_string[1]))
648 return g_strdup_printf(
649 "Expected single character argument not [%s]",
650 arg_string);
651 (*dst_char) = arg_string[0];
652 return NULL;
653 }
654
Argument_parse_int(gchar * arg_string,gpointer data)655 gchar *Argument_parse_int(gchar *arg_string, gpointer data){
656 register gint *dst_int = (gint*)data;
657 (*dst_int) = atoi(arg_string);
658 return NULL;
659 }
660
Argument_parse_float(gchar * arg_string,gpointer data)661 gchar *Argument_parse_float(gchar *arg_string, gpointer data){
662 register gfloat *dst_float = (gfloat*)data;
663 (*dst_float) = atof(arg_string);
664 return NULL;
665 }
666
Argument_parse_boolean(gchar * arg_string,gpointer data)667 gchar *Argument_parse_boolean(gchar *arg_string, gpointer data){
668 register gboolean *dst_boolean = (gboolean*)data;
669 (*dst_boolean) = ArgumentParse_boolean(arg_string);
670 return NULL;
671 }
672
673 /**/
674
675