From: Matthias Bolte Date: Fri, 17 Apr 2009 19:11:39 +0000 (+0200) Subject: [cli] Remove data option type and add new tagged option concept. X-Git-Tag: pg_vsc_final~48 X-Git-Url: http://git.rfc2324.org/?p=vsc-common.git;a=commitdiff_plain;h=76ed167930cf2f89cc432763c4fe64466c9e43c8 [cli] Remove data option type and add new tagged option concept. * Supported option types are boolean, number and string. Boolean options are pure tags like '--no-color'. Number and string options maybe tagged like '--proxy-url http://example.com' or just pure values like 'username' or '42'. Signed-off-by: Matthias Bolte --- diff --git a/cli/command.c b/cli/command.c index e344fe7..6f23df5 100644 --- a/cli/command.c +++ b/cli/command.c @@ -140,7 +140,7 @@ vsc_cli_command_parse (struct VscError *error, const struct VscCliOptionInfo *option_info; struct VscCliOption option; int option_parsed; - int data_option_index = 0; + int untagged_option_index = 0; VSC__ASSERT (error != NULL); VSC__ASSERT (! error->occured); @@ -190,8 +190,8 @@ vsc_cli_command_parse (struct VscError *error, while (TRUE) { option_parsed = _vsc_cli_option_parse (error, command_info->option_infos, - data_option_index, command_name, *input_tail, - input_tail, &option); + untagged_option_index, command_name, + *input_tail, input_tail, &option); if (error->occured) { VSC__APPEND_ERROR0 (error, VSC__ERROR_CODE__TRACE); @@ -199,8 +199,8 @@ vsc_cli_command_parse (struct VscError *error, } if (option_parsed) { - if (option.info->type == VSC_CLI__OPTION_TYPE__DATA) { - ++data_option_index; + if (! option.info->tagged) { + ++untagged_option_index; } _vsc_cli_option_list_append (error, &command->option_list, diff --git a/cli/core.c b/cli/core.c index e56e37a..f379b6f 100644 --- a/cli/core.c +++ b/cli/core.c @@ -49,7 +49,7 @@ _quit (struct VscError *error, const struct VscCliCommandInfo *command_info, const struct VscCliOption *option_list, void *user_data); static const struct VscCliOptionInfo _quit_option_infos[] = { - { -1, NULL, NULL, 0, FALSE }, + VSC_CLI__NULL__OPTION_INFO, }; const struct VscCliCommandInfo vsc_cli_quit_command_info = { @@ -147,7 +147,7 @@ _readline_options_generator(const char *text, int state) option_info = &command_info->option_infos[last_index]; ++last_index; - if (option_info->type == VSC_CLI__OPTION_TYPE__DATA) { + if (! option_info->tagged) { continue; } @@ -195,6 +195,10 @@ vsc_cli_init (struct VscError *error, const struct VscCliCommandInfo **command_infos, int output_coloring) { + int i, k; + const struct VscCliCommandInfo *command_info; + const struct VscCliOptionInfo *option_info; + VSC__ASSERT (error != NULL); VSC__ASSERT (! error->occured); VSC__ASSERT (name != NULL); @@ -208,9 +212,24 @@ vsc_cli_init (struct VscError *error, return; } - if (_vsc_cli_option_infos_lookup_data (option_infos, 0) != 0) { + for (i = 0; command_infos[i] != NULL; i++) { + command_info = command_infos[i]; + + for (k = 0; command_info->option_infos[k].long_name != NULL; k++) { + option_info = &command_info->option_infos[k]; + + if (option_info->type == VSC_CLI__OPTION_TYPE__BOOLEAN && + ! option_info->tagged) { + VSC__ERROR1 (error, VSC__ERROR_CODE__INVALID_ARGUMENT, + "Boolean options can not untagged"); + return; + } + } + } + + if (_vsc_cli_option_infos_lookup_untagged (option_infos, 0) != NULL) { VSC__ERROR1 (error, VSC__ERROR_CODE__INVALID_ARGUMENT, - "Data options can not be used as direct options"); + "Untagged options can not be used as direct options"); return; } diff --git a/cli/help.c b/cli/help.c index db9465b..baa816b 100644 --- a/cli/help.c +++ b/cli/help.c @@ -40,8 +40,9 @@ _help (struct VscError *error, const struct VscCliCommandInfo *command_info, const struct VscCliOption *option_list, void *user_data); static const struct VscCliOptionInfo _help_option_infos[] = { - { -1, "command", "name of command", VSC_CLI__OPTION_TYPE__DATA, FALSE }, - { -1, NULL, NULL, 0, FALSE }, + { -1, "command", "name of command", VSC_CLI__OPTION_TYPE__STRING, + FALSE, FALSE }, + VSC_CLI__NULL__OPTION_INFO, }; const struct VscCliCommandInfo vsc_cli_help_command_info = { diff --git a/cli/option.c b/cli/option.c index 99a7510..85d7137 100644 --- a/cli/option.c +++ b/cli/option.c @@ -34,55 +34,76 @@ const char * _vsc_cli_option_syntax (const struct VscCliOptionInfo *option_info, int synopsis) { - static char buffer1[256]; - static char buffer2[256]; - static char buffer3[512]; + const char *type = NULL; + static char syntax[512]; VSC__ASSERT (option_info != NULL); - switch (option_info->type) { - case VSC_CLI__OPTION_TYPE__DATA: - snprintf (buffer3, 512, "<%s>", option_info->long_name); - return buffer3; - - case VSC_CLI__OPTION_TYPE__BOOL: - snprintf (buffer1, 256, "-%c", option_info->short_name); - snprintf (buffer2, 256, "--%s", option_info->long_name); - break; - - case VSC_CLI__OPTION_TYPE__NUMBER: - snprintf (buffer1, 256, "-%c ", option_info->short_name); - snprintf (buffer2, 256, "--%s ", option_info->long_name); - break; - - case VSC_CLI__OPTION_TYPE__STRING: - snprintf (buffer1, 256, "-%c ", option_info->short_name); - snprintf (buffer2, 256, "--%s ", option_info->long_name); - break; - - default: - snprintf (buffer1, 256, "INVALID"); - snprintf (buffer2, 256, "INVALID"); - break; - } - - if (synopsis && option_info->short_name != -1) { - return buffer1; - } + if (option_info->tagged) { + if (option_info->type == VSC_CLI__OPTION_TYPE__BOOLEAN) { + if (synopsis) { + if (option_info->short_name > 0) { + snprintf (syntax, 512, "-%c", option_info->short_name); + } else { + snprintf (syntax, 512, "--%s", option_info->long_name); + } + } else { + if (option_info->short_name > 0) { + snprintf (syntax, 512, "-%c, --%s", option_info->short_name, + option_info->long_name); + } else { + snprintf (syntax, 512, "--%s", option_info->long_name); + } + } + } else { + switch (option_info->type) { + case VSC_CLI__OPTION_TYPE__BOOLEAN: + type = ""; + break; + + case VSC_CLI__OPTION_TYPE__NUMBER: + type = ""; + break; + + case VSC_CLI__OPTION_TYPE__STRING: + type = ""; + break; + + default: + type = ""; + break; + } - if (option_info->short_name == -1) { - return buffer2; + if (synopsis) { + if (option_info->short_name > 0) { + snprintf (syntax, 512, "-%c %s", option_info->short_name, + type); + } else { + snprintf (syntax, 512, "--%s %s", option_info->long_name, + type); + } + } else { + if (option_info->short_name > 0) { + snprintf (syntax, 512, "-%c %s, --%s %s", + option_info->short_name, type, + option_info->long_name, type); + } else { + snprintf (syntax, 512, "--%s %s", option_info->long_name, + type); + } + } + } + } else { + snprintf (syntax, 512, "<%s>", option_info->long_name); } - snprintf (buffer3, 512, "%s, %s", buffer1, buffer2); - - return buffer3; + return syntax; } int /* option_parsed */ _vsc_cli_option_parse (struct VscError *error, const struct VscCliOptionInfo *option_infos, - int data_option_index, const char *command_name, + int untagged_option_index, const char *command_name, const char *input, const char **input_tail, struct VscCliOption *option) { @@ -129,7 +150,7 @@ _vsc_cli_option_parse (struct VscError *error, goto failure; } - option_info = _vsc_cli_option_infos_lookup + option_info = _vsc_cli_option_infos_lookup_tagged (option_infos, token + num_dashes, num_dashes > 1); if (option_info == NULL) { @@ -148,7 +169,7 @@ _vsc_cli_option_parse (struct VscError *error, option->info = option_info; switch (option_info->type) { - case VSC_CLI__OPTION_TYPE__BOOL: + case VSC_CLI__OPTION_TYPE__BOOLEAN: break; case VSC_CLI__OPTION_TYPE__NUMBER: @@ -211,9 +232,9 @@ _vsc_cli_option_parse (struct VscError *error, VSC__APPEND_ERROR0 (error, VSC__ERROR_CODE__TRACE); goto failure; } - } else if (data_option_index >= 0) { - option_info = _vsc_cli_option_infos_lookup_data - (option_infos, data_option_index); + } else if (untagged_option_index >= 0) { + option_info = _vsc_cli_option_infos_lookup_untagged + (option_infos, untagged_option_index); if (option_info == NULL) { VSC__ERROR2 (error, VSC__ERROR_CODE__INTERNAL_ERROR, @@ -269,8 +290,8 @@ _option_get (const struct VscCliOption *option_list, } int -vsc_cli_option_get_bool (const struct VscCliOption *option_list, - const char *option_long_name) +vsc_cli_option_get_boolean (const struct VscCliOption *option_list, + const char *option_long_name) { return _option_get (option_list, option_long_name) != NULL; } @@ -318,8 +339,9 @@ vsc_cli_option_get_string (const struct VscCliOption *option_list, } const struct VscCliOptionInfo * -_vsc_cli_option_infos_lookup (const struct VscCliOptionInfo *option_infos, - const char *option_name, int is_long) +_vsc_cli_option_infos_lookup_tagged + (const struct VscCliOptionInfo *option_infos, const char *option_name, + int is_long) { int i; @@ -327,7 +349,7 @@ _vsc_cli_option_infos_lookup (const struct VscCliOptionInfo *option_infos, VSC__ASSERT (option_name != NULL); for (i = 0; option_infos[i].long_name != NULL; i++) { - if (option_infos[i].type == VSC_CLI__OPTION_TYPE__DATA) { + if (! option_infos[i].tagged) { continue; } @@ -346,8 +368,8 @@ _vsc_cli_option_infos_lookup (const struct VscCliOptionInfo *option_infos, } const struct VscCliOptionInfo * -_vsc_cli_option_infos_lookup_data (const struct VscCliOptionInfo *option_infos, - int position) +_vsc_cli_option_infos_lookup_untagged + (const struct VscCliOptionInfo *option_infos, int position) { int i; @@ -355,7 +377,7 @@ _vsc_cli_option_infos_lookup_data (const struct VscCliOptionInfo *option_infos, VSC__ASSERT (position >= 0); for (i = 0; option_infos[i].long_name != NULL; i++) { - if (option_infos[i].type == VSC_CLI__OPTION_TYPE__DATA) { + if (! option_infos[i].tagged) { if (position > 0) { --position; } else { diff --git a/cli/option.h b/cli/option.h index 6965856..749e2ec 100644 --- a/cli/option.h +++ b/cli/option.h @@ -30,17 +30,18 @@ _vsc_cli_option_syntax (const struct VscCliOptionInfo *option_info, int /* option_parsed */ _vsc_cli_option_parse (struct VscError *error, const struct VscCliOptionInfo *option_infos, - int data_option_index, const char *command_name, + int untagged_option_index, const char *command_name, const char *input, const char **input_tail, struct VscCliOption *option); const struct VscCliOptionInfo * -_vsc_cli_option_infos_lookup (const struct VscCliOptionInfo *option_infos, - const char *option_name, int is_long); +_vsc_cli_option_infos_lookup_tagged + (const struct VscCliOptionInfo *option_infos, const char *option_name, + int is_long); const struct VscCliOptionInfo * -_vsc_cli_option_infos_lookup_data (const struct VscCliOptionInfo *option_infos, - int position); +_vsc_cli_option_infos_lookup_untagged + (const struct VscCliOptionInfo *option_infos, int position); struct VscCliOption * /* option_list_duplicate */ _vsc_cli_option_list_duplicate (struct VscError *error, diff --git a/include/libvsccli/option.h b/include/libvsccli/option.h index d451d4a..65023c0 100644 --- a/include/libvsccli/option.h +++ b/include/libvsccli/option.h @@ -23,25 +23,27 @@ #include "types.h" +#define VSC_CLI__NULL__OPTION_INFO { -1, NULL, NULL, 0, FALSE, FALSE } + #define VSC_CLI__VERBOSE_ERRORS__OPTION_INFO__LONG_NAME "verbose-errors" #define VSC_CLI__VERBOSE_ERRORS__OPTION_INFO \ { -1, VSC_CLI__VERBOSE_ERRORS__OPTION_INFO__LONG_NAME, \ "enable verbose error reporting", \ - VSC_CLI__OPTION_TYPE__BOOL, FALSE } + VSC_CLI__OPTION_TYPE__BOOLEAN, TRUE, FALSE } #define VSC_CLI__NO_COLOR__OPTION_INFO__LONG_NAME "no-color" #define VSC_CLI__NO_COLOR__OPTION_INFO \ { -1, VSC_CLI__NO_COLOR__OPTION_INFO__LONG_NAME, \ "disable output coloring", \ - VSC_CLI__OPTION_TYPE__BOOL, FALSE } + VSC_CLI__OPTION_TYPE__BOOLEAN, TRUE, FALSE } #ifdef __cplusplus extern "C" { #endif int -vsc_cli_option_get_bool (const struct VscCliOption *option_list, - const char *option_long_name); +vsc_cli_option_get_boolean (const struct VscCliOption *option_list, + const char *option_long_name); int vsc_cli_option_get_number (const struct VscCliOption *option_list, diff --git a/include/libvsccli/types.h b/include/libvsccli/types.h index 37b933c..952229c 100644 --- a/include/libvsccli/types.h +++ b/include/libvsccli/types.h @@ -28,8 +28,7 @@ extern "C" { #endif enum VscCliOptionType { - VSC_CLI__OPTION_TYPE__DATA = 0, - VSC_CLI__OPTION_TYPE__BOOL, + VSC_CLI__OPTION_TYPE__BOOLEAN = 0, VSC_CLI__OPTION_TYPE__NUMBER, VSC_CLI__OPTION_TYPE__STRING, }; @@ -53,14 +52,15 @@ struct VscCliOptionInfo { const char* long_name; const char* help; enum VscCliOptionType type; + int tagged; int required; }; struct VscCliOption { struct VscCliOption *next; const struct VscCliOptionInfo *info; - char* string; int number; + char* string; }; struct VscCliCommandInfo { diff --git a/remote/remote.c b/remote/remote.c index 4219d5e..63be377 100644 --- a/remote/remote.c +++ b/remote/remote.c @@ -166,10 +166,10 @@ _login (struct VscError *error, const struct VscCliCommandInfo *command_info, static const struct VscCliOptionInfo _login_option_infos[] = { { -1, "username", "username for the remote system", - VSC_CLI__OPTION_TYPE__DATA, TRUE }, + VSC_CLI__OPTION_TYPE__STRING, FALSE, TRUE }, { -1, "password", "password for the remote system", - VSC_CLI__OPTION_TYPE__DATA, FALSE }, - { -1, NULL, NULL, 0, FALSE }, + VSC_CLI__OPTION_TYPE__STRING, FALSE, FALSE }, + VSC_CLI__NULL__OPTION_INFO, }; const struct VscCliCommandInfo vsc_remote_login_command_info = { @@ -310,7 +310,7 @@ _logout (struct VscError *error, const struct VscCliCommandInfo *command_info, const struct VscCliOption *option_list, void *user_data); static const struct VscCliOptionInfo _logout_option_infos[] = { - { -1, NULL, NULL, 0, FALSE }, + VSC_CLI__NULL__OPTION_INFO, }; const struct VscCliCommandInfo vsc_remote_logout_command_info = {