pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmocore/+/14436


Change subject: vty: command.c: Fix: multi-choice args are no longer passed 
incomplete to vty func
......................................................................

vty: command.c: Fix: multi-choice args are no longer passed incomplete to vty 
func

For instance, take command "multi0 (one|two|three)":
If user executes "multi0 tw", VTY func will receive argv[0]="two"
instead of argv[0]="tw".

Fixes: OS#4045
Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a
---
M src/vty/command.c
M tests/tdef/tdef_vty_test_config_root.vty
M tests/vty/vty_transcript_test.vty
3 files changed, 83 insertions(+), 25 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/36/14436/1

diff --git a/src/vty/command.c b/src/vty/command.c
index b4afd35..6e8bc5b 100644
--- a/src/vty/command.c
+++ b/src/vty/command.c
@@ -2217,7 +2217,7 @@
 cmd_execute_command_real(vector vline, struct vty *vty,
                         struct cmd_element **cmd)
 {
-       unsigned int i;
+       unsigned int i, j;
        unsigned int index;
        vector cmd_vector;
        struct cmd_element *cmd_element;
@@ -2228,6 +2228,10 @@
        enum match_type match = 0;
        int varflag;
        char *command;
+       int rc;
+       /* Used for temporary storage of cmd_deopt() allocated arguments during
+          argv[] generation */
+       void *cmd_deopt_ctx = NULL;

        /* Make copy of command elements. */
        cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));
@@ -2293,11 +2297,15 @@
        varflag = 0;
        argc = 0;

+       cmd_deopt_ctx = talloc_named_const(tall_vty_cmd_ctx, 0, __func__);
+
        for (i = 0; i < vector_active(vline); i++) {
                if (varflag) {
                        argv[argc++] = vector_slot(vline, i);
-                       if (argc == CMD_ARGC_MAX)
-                               return CMD_ERR_EXEED_ARGC_MAX;
+                       if (argc == CMD_ARGC_MAX) {
+                               rc = CMD_ERR_EXEED_ARGC_MAX;
+                               goto rc_free_deopt_ctx;
+                       }
                        continue;
                }

@@ -2313,11 +2321,38 @@
                            || CMD_OPTION(desc->cmd))
                                argv[argc++] = vector_slot(vline, i);
                } else {
-                       argv[argc++] = vector_slot(vline, i);
+                       /* multi choice argument. look up which choice
+                          the user meant (can only be one after
+                          filtering and checking for ambigous). For instance,
+                          if user typed "th" for "(two|three)" arg, we
+                          want to pass "three" in argv[]. */
+                       for (j = 0; j < vector_active(descvec); j++) {
+                               struct desc *desc = vector_slot(descvec, j);
+                               const char *tmp_cmd;
+                               if (!desc)
+                                       continue;
+                               if (cmd_match(desc->cmd, vector_slot(vline, i), 
ANY_MATCH, true) == NO_MATCH)
+                                       continue;
+                               if (CMD_OPTION(desc->cmd)) {
+                                       /* we need to first remove the [] 
chars, then check to see what's inside (var or token) */
+                                       tmp_cmd = cmd_deopt(cmd_deopt_ctx, 
desc->cmd);
+                               } else {
+                                       tmp_cmd = desc->cmd;
+                               }
+
+                               if(CMD_VARIABLE(tmp_cmd)) {
+                                       argv[argc++] = vector_slot(vline, i);
+                               } else {
+                                       argv[argc++] = tmp_cmd;
+                               }
+                               break;
+                       }
                }

-               if (argc == CMD_ARGC_MAX)
-                       return CMD_ERR_EXEED_ARGC_MAX;
+               if (argc == CMD_ARGC_MAX){
+                       rc = CMD_ERR_EXEED_ARGC_MAX;
+                       goto rc_free_deopt_ctx;
+               }
        }

        /* For vtysh execution. */
@@ -2325,10 +2360,14 @@
                *cmd = matched_element;

        if (matched_element->daemon)
-               return CMD_SUCCESS_DAEMON;
+               rc = CMD_SUCCESS_DAEMON;
+       else    /* Execute matched command. */
+               rc = (*matched_element->func) (matched_element, vty, argc, 
argv);

-       /* Execute matched command. */
-       return (*matched_element->func) (matched_element, vty, argc, argv);
+rc_free_deopt_ctx:
+       /* Now after we called the command func, we can free temporary strings 
*/
+       talloc_free(cmd_deopt_ctx);
+       return rc;
 }

 int
diff --git a/tests/tdef/tdef_vty_test_config_root.vty 
b/tests/tdef/tdef_vty_test_config_root.vty
index 8613ff3..3ff3f37 100644
--- a/tests/tdef/tdef_vty_test_config_root.vty
+++ b/tests/tdef/tdef_vty_test_config_root.vty
@@ -163,7 +163,6 @@
 tdef_vty_test(config)# timer test T2 100

 tdef_vty_test(config)# timer tes T2 100
-% Error: no timers found

 tdef_vty_test(config)# timer te T2 100
 % Ambiguous command.
@@ -219,7 +218,6 @@
 software: T3 = 480 m   Fix bugs (default: 480 m)

 tdef_vty_test(config)# timer softw T3 23
-% Error: no timers found

 tdef_vty_test(config)# timer
 tea: T1 = 50 s Water Boiling Timeout (default: 50 s)
@@ -234,7 +232,7 @@
 test: X23 = 239471 s   Negative T number (default: 239471 s)
 software: T1 = 13 m    Write code (default: 30 m)
 software: T2 = 0 ms    Hit segfault (default: 20 ms)
-software: T3 = 480 m   Fix bugs (default: 480 m)
+software: T3 = 23 m    Fix bugs (default: 480 m)

 tdef_vty_test(config)# do show timer
 tea: T1 = 50 s Water Boiling Timeout (default: 50 s)
@@ -249,24 +247,45 @@
 test: X23 = 239471 s   Negative T number (default: 239471 s)
 software: T1 = 13 m    Write code (default: 30 m)
 software: T2 = 0 ms    Hit segfault (default: 20 ms)
-software: T3 = 480 m   Fix bugs (default: 480 m)
+software: T3 = 23 m    Fix bugs (default: 480 m)

 tdef_vty_test(config)# show running-config
-... !timer
+
+Current configuration:
+!
+!
+line vty
+ no login
+!
 timer tea T3 32
 timer software T1 13
 timer software T2 0
-... !timer
+timer software T3 23
+end

 tdef_vty_test(config)# timer tea T3 default
 tdef_vty_test(config)# timer software T1 default
 tdef_vty_test(config)# show running-config
-... !timer
+
+Current configuration:
+!
+!
+line vty
+ no login
+!
 timer software T2 0
-... !timer
+timer software T3 23
+end

 tdef_vty_test(config)# timer softw 2 default
-% Error: no timers found
 tdef_vty_test(config)# timer software 2 default
 tdef_vty_test(config)# show running-config
-... !timer
+
+Current configuration:
+!
+!
+line vty
+ no login
+!
+timer software T3 23
+end
diff --git a/tests/vty/vty_transcript_test.vty 
b/tests/vty/vty_transcript_test.vty
index 1557744..f2dbacb 100644
--- a/tests/vty/vty_transcript_test.vty
+++ b/tests/vty/vty_transcript_test.vty
@@ -16,13 +16,13 @@
 ok argc=1 two

 vty_transcript_test> multi0 o
-ok argc=1 o
+ok argc=1 one

 vty_transcript_test> multi0 t
 % Ambiguous command.

 vty_transcript_test> multi0 th
-ok argc=1 th
+ok argc=1 three

 vty_transcript_test> multi0
 % Command incomplete.
@@ -39,13 +39,13 @@
 ok argc=1 two

 vty_transcript_test> multi1 o
-ok argc=1 o
+ok argc=1 one

 vty_transcript_test> multi1 t
 % Ambiguous command.

 vty_transcript_test> multi1 th
-ok argc=1 th
+ok argc=1 three

 vty_transcript_test> multi1
 ok argc=0
@@ -68,10 +68,10 @@
 ok argc=0

 vty_transcript_test> multi0 thr
-ok argc=1 thr
+ok argc=1 three

 vty_transcript_test> multi1 on
-ok argc=1 on
+ok argc=1 one

 vty_transcript_test> multi2 t
 % Ambiguous command.

--
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/14436
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a
Gerrit-Change-Number: 14436
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to