X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttv%2Flttv%2Foption.c;h=148b4c88ad1c4c69d21d4fc7ceea07e4517273d1;hb=90e19f82bca635a1ba52b8a50b64e484bd19c14f;hp=f0d44254577565d404e1720acb88a30d7b7b6479;hpb=6d3ad1b2722e69f425f4d822f893c599c112cbc2;p=lttv.git diff --git a/lttv/lttv/option.c b/lttv/lttv/option.c index f0d44254..148b4c88 100644 --- a/lttv/lttv/option.c +++ b/lttv/lttv/option.c @@ -26,292 +26,287 @@ #include typedef struct _LttvOption { - char *long_name; - char char_name; - char *description; - char *arg_description; - LttvOptionType t; - gpointer p; - LttvOptionHook hook; - gpointer hook_data; - - /* Keep the order of addition */ - guint val; + char *long_name; + char char_name; + char *description; + char *arg_description; + LttvOptionType t; + gpointer p; + LttvOptionHook hook; + gpointer hook_data; + + /* Keep the order of addition */ + guint val; } LttvOption; GHashTable *options; -static void -list_options(gpointer key, gpointer value, gpointer user_data) +static void list_options(gpointer key, gpointer value, gpointer user_data) { - GPtrArray *list = (GPtrArray *)user_data; - LttvOption *option = (LttvOption *)value; + GPtrArray *list = (GPtrArray *)user_data; + LttvOption *option = (LttvOption *)value; - if(list->len < option->val) - g_ptr_array_set_size(list, option->val); - list->pdata[option->val-1] = option; + if(list->len < option->val) + g_ptr_array_set_size(list, option->val); + list->pdata[option->val-1] = option; } -static void -free_option(LttvOption *option) +static void free_option(LttvOption *option) { - g_free(option->long_name); - g_free(option->description); - g_free(option->arg_description); - g_free(option); + g_free(option->long_name); + g_free(option->description); + g_free(option->arg_description); + g_free(option); } void lttv_option_add(const char *long_name, const char char_name, - const char *description, const char *arg_description, - const LttvOptionType t, void *p, - const LttvOptionHook h, void *hook_data) + const char *description, const char *arg_description, + const LttvOptionType t, void *p, + const LttvOptionHook h, void *hook_data) { - LttvOption *option; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add option %s", long_name); - if(g_hash_table_lookup(options, long_name) != NULL) { - g_warning("duplicate option"); - return; - } - - option = g_new(LttvOption, 1); - option->long_name = g_strdup(long_name); - option->char_name = char_name; - option->description = g_strdup(description); - option->arg_description = g_strdup(arg_description); - option->t = t; - option->p = p; - option->hook = h; - option->hook_data = hook_data; - option->val = g_hash_table_size(options) + 1; - g_hash_table_insert(options, option->long_name, option); + LttvOption *option; + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Add option %s", long_name); + if(g_hash_table_lookup(options, long_name) != NULL) { + g_warning("duplicate option"); + return; + } + + option = g_new(LttvOption, 1); + option->long_name = g_strdup(long_name); + option->char_name = char_name; + option->description = g_strdup(description); + option->arg_description = g_strdup(arg_description); + option->t = t; + option->p = p; + option->hook = h; + option->hook_data = hook_data; + option->val = g_hash_table_size(options) + 1; + g_hash_table_insert(options, option->long_name, option); } -void -lttv_option_remove(const char *long_name) +void lttv_option_remove(const char *long_name) { - LttvOption *option = g_hash_table_lookup(options, long_name); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Remove option %s", long_name); - if(option == NULL) { - g_warning("trying to remove unknown option %s", long_name); - return; - } - g_hash_table_remove(options, long_name); - free_option(option); + LttvOption *option = g_hash_table_lookup(options, long_name); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Remove option %s", long_name); + if(option == NULL) { + g_warning("trying to remove unknown option %s", long_name); + return; + } + g_hash_table_remove(options, long_name); + free_option(option); } static int poptToLTT[] = { - POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG + POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG }; static struct poptOption endOption = { NULL, '\0', 0, NULL, 0, NULL, NULL }; -static void -build_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc, - int argc, char **argv) +static void build_popts(GPtrArray **plist, struct poptOption **ppopts, + poptContext *pc, int argc, char **argv) { - LttvOption *option; + LttvOption *option; - GPtrArray *list; + GPtrArray *list; - struct poptOption *popts; + struct poptOption *popts; - poptContext c; + poptContext c; - guint i; + guint i; - list = g_ptr_array_sized_new(g_hash_table_size(options)); + list = g_ptr_array_sized_new(g_hash_table_size(options)); - g_hash_table_foreach(options, list_options, list); + g_hash_table_foreach(options, list_options, list); - /* Build a popt options array from our list */ + /* Build a popt options array from our list */ - popts = g_new(struct poptOption, list->len + 1); + popts = g_new(struct poptOption, list->len + 1); - /* add the options in the reverse order, so last additions are parsed first */ - for(i = 0 ; i < list->len ; i++) { - guint reverse_i = list->len-1-i; - option = (LttvOption *)list->pdata[i]; - popts[reverse_i].longName = option->long_name; - popts[reverse_i].shortName = option->char_name; - popts[reverse_i].descrip = option->description; - popts[reverse_i].argDescrip = option->arg_description; - popts[reverse_i].argInfo = poptToLTT[option->t]; - popts[reverse_i].arg = option->p; - popts[reverse_i].val = option->val; - } + /* add the options in the reverse order, so last additions are parsed first */ + for(i = 0 ; i < list->len ; i++) { + guint reverse_i = list->len-1-i; + option = (LttvOption *)list->pdata[i]; + popts[reverse_i].longName = option->long_name; + popts[reverse_i].shortName = option->char_name; + popts[reverse_i].descrip = option->description; + popts[reverse_i].argDescrip = option->arg_description; + popts[reverse_i].argInfo = poptToLTT[option->t]; + popts[reverse_i].arg = option->p; + popts[reverse_i].val = option->val; + } - /* Terminate the array for popt and create the context */ + /* Terminate the array for popt and create the context */ - popts[list->len] = endOption; - c = poptGetContext(argv[0], argc, (const char**)argv, popts, 0); + popts[list->len] = endOption; + c = poptGetContext(argv[0], argc, (const char**)argv, popts, 0); - *plist = list; - *ppopts = popts; - *pc = c; + *plist = list; + *ppopts = popts; + *pc = c; } -static void -destroy_popts(GPtrArray **plist, struct poptOption **ppopts, poptContext *pc) +static void destroy_popts(GPtrArray **plist, struct poptOption **ppopts, + poptContext *pc) { - g_ptr_array_free(*plist, TRUE); *plist = NULL; - g_free(*ppopts); *ppopts = NULL; - poptFreeContext(*pc); + g_ptr_array_free(*plist, TRUE); *plist = NULL; + g_free(*ppopts); *ppopts = NULL; + poptFreeContext(*pc); } void lttv_option_parse(int argc, char **argv) { - GPtrArray *list; + GPtrArray *list; - LttvOption *option; + LttvOption *option; - int i, rc, first_arg; + int i, rc, first_arg; - struct poptOption *popts; + struct poptOption *popts; - poptContext c; + poptContext c; - i = 0; + i = 0; - first_arg = 0; + first_arg = 0; - guint hash_size = 0; + guint hash_size = 0; - build_popts(&list, &popts, &c, argc, argv); + build_popts(&list, &popts, &c, argc, argv); - /* Parse options while not end of options event */ + /* Parse options while not end of options event */ - while((rc = poptGetNextOpt(c)) != -1) { + while((rc = poptGetNextOpt(c)) != -1) { - /* The option was recognized and the rc value returned is the argument - position in the array. Call the associated hook if present. */ - - if(rc > 0) { - option = (LttvOption *)(list->pdata[rc - 1]); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Option %s encountered", - option->long_name); - hash_size = g_hash_table_size(options); - if(option->hook != NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s hook called", - option->long_name); - option->hook(option->hook_data); - } - i++; + /* The option was recognized and the rc value returned is the argument + position in the array. Call the associated hook if present. */ - /* If the size of the option hash changed, add new options - * right now. It resolves the conflict of multiple same short - * option use. - */ - if(hash_size != g_hash_table_size(options)) { - destroy_popts(&list, &popts, &c); - build_popts(&list, &popts, &c, argc, argv); + if(rc > 0) { + option = (LttvOption *)(list->pdata[rc - 1]); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Option %s encountered", + option->long_name); + hash_size = g_hash_table_size(options); + if(option->hook != NULL) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s hook called", + option->long_name); + option->hook(option->hook_data); + } + i++; - /* Get back to the same argument */ + /* If the size of the option hash changed, add new options + * right now. It resolves the conflict of multiple same short + * option use. + */ + if(hash_size != g_hash_table_size(options)) { + destroy_popts(&list, &popts, &c); + build_popts(&list, &popts, &c, argc, argv); - first_arg = i; - for(i = 0; i < first_arg; i++) { - rc = poptGetNextOpt(c); - option = (LttvOption *)(list->pdata[rc - 1]); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped", - option->long_name); - } - } - } + /* Get back to the same argument */ - else if(rc == POPT_ERROR_BADOPT && i != first_arg) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - "Option %s not recognized, rescan options with new additions", - poptBadOption(c,0)); + first_arg = i; + for(i = 0; i < first_arg; i++) { + rc = poptGetNextOpt(c); + option = (LttvOption *)(list->pdata[rc - 1]); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped", + option->long_name); + } + } + } - /* Perhaps this option is newly added, restart parsing */ + else if(rc == POPT_ERROR_BADOPT && i != first_arg) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, + "Option %s not recognized, rescan options with new additions", + poptBadOption(c,0)); - destroy_popts(&list, &popts, &c); - build_popts(&list, &popts, &c, argc, argv); + /* Perhaps this option is newly added, restart parsing */ - /* Get back to the same argument */ + destroy_popts(&list, &popts, &c); + build_popts(&list, &popts, &c, argc, argv); - first_arg = i; - for(i = 0; i < first_arg; i++) { - rc = poptGetNextOpt(c); - option = (LttvOption *)(list->pdata[rc - 1]); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped", - option->long_name); - } - } + /* Get back to the same argument */ - else { + first_arg = i; + for(i = 0; i < first_arg; i++) { + rc = poptGetNextOpt(c); + option = (LttvOption *)(list->pdata[rc - 1]); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Option %s rescanned, skipped", + option->long_name); + } + } - /* The option has some error and it is not because this is a newly - added option not recognized. */ + else { - g_error("option %s: %s", poptBadOption(c,0), poptStrerror(rc)); - break; - } - - } + /* The option has some error and it is not because this is a newly + added option not recognized. */ - destroy_popts(&list, &popts, &c); + g_error("option %s: %s", poptBadOption(c,0), poptStrerror(rc)); + break; + } + + } + + destroy_popts(&list, &popts, &c); } /* CHECK */ static void show_help(LttvOption *option) { - printf("--%s -%c argument: %s\n" , option->long_name, - option->char_name, - option->arg_description); - printf(" %s\n" , option->description); + printf("--%s -%c argument: %s\n" , option->long_name, + option->char_name, option->arg_description); + printf(" %s\n" , option->description); } void lttv_option_show_help(void) { - GPtrArray *list = g_ptr_array_new(); + GPtrArray *list = g_ptr_array_new(); - guint i; + guint i; - g_hash_table_foreach(options, list_options, list); + g_hash_table_foreach(options, list_options, list); printf("Built-in commands available:\n"); printf("\n"); - for(i = 0 ; i < list->len ; i++) { - show_help((LttvOption *)list->pdata[i]); - } - g_ptr_array_free(list, TRUE); + for(i = 0 ; i < list->len ; i++) { + show_help((LttvOption *)list->pdata[i]); + } + g_ptr_array_free(list, TRUE); } static void init() { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init option.c"); - options = g_hash_table_new(g_str_hash, g_str_equal); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Init option.c"); + options = g_hash_table_new(g_str_hash, g_str_equal); } static void destroy() { - GPtrArray *list = g_ptr_array_new(); + GPtrArray *list = g_ptr_array_new(); - guint i; + guint i; - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy option.c"); - g_hash_table_foreach(options, list_options, list); - g_hash_table_destroy(options); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Destroy option.c"); + g_hash_table_foreach(options, list_options, list); + g_hash_table_destroy(options); - for(i = 0 ; i < list->len ; i++) { - free_option((LttvOption *)list->pdata[i]); - } - g_ptr_array_free(list, TRUE); + for(i = 0 ; i < list->len ; i++) { + free_option((LttvOption *)list->pdata[i]); + } + g_ptr_array_free(list, TRUE); } LTTV_MODULE("option", "Command line options processing", \ - "Functions to add, remove and parse command line options", \ - init, destroy) + "Functions to add, remove and parse command line options", \ + init, destroy)