[cli] Remove data option type and add new tagged option concept.
authorMatthias Bolte <matthias.bolte@googlemail.com>
Fri, 17 Apr 2009 19:11:39 +0000 (21:11 +0200)
committerMatthias Bolte <matthias.bolte@googlemail.com>
Fri, 17 Apr 2009 19:11:39 +0000 (21:11 +0200)
  * 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 <matthias.bolte@googlemail.com>

cli/command.c
cli/core.c
cli/help.c
cli/option.c
cli/option.h
include/libvsccli/option.h
include/libvsccli/types.h
remote/remote.c

index e344fe7..6f23df5 100644 (file)
@@ -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,
index e56e37a..f379b6f 100644 (file)
@@ -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;
        }
 
index db9465b..baa816b 100644 (file)
@@ -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 = {
index 99a7510..85d7137 100644 (file)
@@ -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 <number>", option_info->short_name);
-               snprintf (buffer2, 256, "--%s <number>", option_info->long_name);
-               break;
-
-       case VSC_CLI__OPTION_TYPE__STRING:
-               snprintf (buffer1, 256, "-%c <string>", option_info->short_name);
-               snprintf (buffer2, 256, "--%s <string>", 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 = "<number>";
+                               break;
+
+                       case VSC_CLI__OPTION_TYPE__STRING:
+                               type = "<string>";
+                               break;
+
+                       default:
+                               type = "<INVALID>";
+                               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 {
index 6965856..749e2ec 100644 (file)
@@ -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,
index d451d4a..65023c0 100644 (file)
 
 #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,
index 37b933c..952229c 100644 (file)
@@ -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 {
index 4219d5e..63be377 100644 (file)
@@ -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 = {