<p>laforge <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/14436">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">vty: command.c: Fix: multi-choice args are no longer passed incomplete to vty func<br><br>For instance, take command "multi0 (one|two|three)":<br>If user executes "multi0 tw", VTY func will receive argv[0]="two"<br>instead of argv[0]="tw".<br><br>Fixes: OS#4045<br>Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a<br>---<br>M src/vty/command.c<br>M tests/tdef/tdef_vty_test_config_root.vty<br>M tests/vty/vty_transcript_test.vty<br>3 files changed, 56 insertions(+), 18 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/vty/command.c b/src/vty/command.c</span><br><span>index 17d28fe..3c91bfd 100644</span><br><span>--- a/src/vty/command.c</span><br><span>+++ b/src/vty/command.c</span><br><span>@@ -2217,7 +2217,7 @@</span><br><span> cmd_execute_command_real(vector vline, struct vty *vty,</span><br><span> struct cmd_element **cmd)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i, j;</span><br><span> unsigned int index;</span><br><span> vector cmd_vector;</span><br><span> struct cmd_element *cmd_element;</span><br><span>@@ -2228,6 +2228,10 @@</span><br><span> enum match_type match = 0;</span><br><span> int varflag;</span><br><span> char *command;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Used for temporary storage of cmd_deopt() allocated arguments during</span><br><span style="color: hsl(120, 100%, 40%);">+ argv[] generation */</span><br><span style="color: hsl(120, 100%, 40%);">+ void *cmd_deopt_ctx = NULL;</span><br><span> </span><br><span> /* Make copy of command elements. */</span><br><span> cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));</span><br><span>@@ -2293,9 +2297,13 @@</span><br><span> varflag = 0;</span><br><span> argc = 0;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ cmd_deopt_ctx = talloc_named_const(tall_vty_cmd_ctx, 0, __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> for (i = 0; i < vector_active(vline); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (argc == CMD_ARGC_MAX)</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_ERR_EXEED_ARGC_MAX;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (argc == CMD_ARGC_MAX) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = CMD_ERR_EXEED_ARGC_MAX;</span><br><span style="color: hsl(120, 100%, 40%);">+ goto rc_free_deopt_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> if (varflag) {</span><br><span> argv[argc++] = vector_slot(vline, i);</span><br><span> continue;</span><br><span>@@ -2313,7 +2321,32 @@</span><br><span> || CMD_OPTION(desc->cmd))</span><br><span> argv[argc++] = vector_slot(vline, i);</span><br><span> } else {</span><br><span style="color: hsl(0, 100%, 40%);">- argv[argc++] = vector_slot(vline, i);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* multi choice argument. look up which choice</span><br><span style="color: hsl(120, 100%, 40%);">+ the user meant (can only be one after</span><br><span style="color: hsl(120, 100%, 40%);">+ filtering and checking for ambigous). For instance,</span><br><span style="color: hsl(120, 100%, 40%);">+ if user typed "th" for "(two|three)" arg, we</span><br><span style="color: hsl(120, 100%, 40%);">+ want to pass "three" in argv[]. */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (j = 0; j < vector_active(descvec); j++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct desc *desc = vector_slot(descvec, j);</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *tmp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!desc)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (cmd_match(desc->cmd, vector_slot(vline, i), ANY_MATCH, true) == NO_MATCH)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (CMD_OPTION(desc->cmd)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we need to first remove the [] chars, then check to see what's inside (var or token) */</span><br><span style="color: hsl(120, 100%, 40%);">+ tmp_cmd = cmd_deopt(cmd_deopt_ctx, desc->cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ tmp_cmd = desc->cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if(CMD_VARIABLE(tmp_cmd)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ argv[argc++] = vector_slot(vline, i);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ argv[argc++] = tmp_cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>@@ -2322,10 +2355,14 @@</span><br><span> *cmd = matched_element;</span><br><span> </span><br><span> if (matched_element->daemon)</span><br><span style="color: hsl(0, 100%, 40%);">- return CMD_SUCCESS_DAEMON;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = CMD_SUCCESS_DAEMON;</span><br><span style="color: hsl(120, 100%, 40%);">+ else /* Execute matched command. */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = (*matched_element->func) (matched_element, vty, argc, argv);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Execute matched command. */</span><br><span style="color: hsl(0, 100%, 40%);">- return (*matched_element->func) (matched_element, vty, argc, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+rc_free_deopt_ctx:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Now after we called the command func, we can free temporary strings */</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(cmd_deopt_ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span> }</span><br><span> </span><br><span> int</span><br><span>diff --git a/tests/tdef/tdef_vty_test_config_root.vty b/tests/tdef/tdef_vty_test_config_root.vty</span><br><span>index 8613ff3..f3aba0f 100644</span><br><span>--- a/tests/tdef/tdef_vty_test_config_root.vty</span><br><span>+++ b/tests/tdef/tdef_vty_test_config_root.vty</span><br><span>@@ -163,7 +163,6 @@</span><br><span> tdef_vty_test(config)# timer test T2 100</span><br><span> </span><br><span> tdef_vty_test(config)# timer tes T2 100</span><br><span style="color: hsl(0, 100%, 40%);">-% Error: no timers found</span><br><span> </span><br><span> tdef_vty_test(config)# timer te T2 100</span><br><span> % Ambiguous command.</span><br><span>@@ -219,7 +218,6 @@</span><br><span> software: T3 = 480 m Fix bugs (default: 480 m)</span><br><span> </span><br><span> tdef_vty_test(config)# timer softw T3 23</span><br><span style="color: hsl(0, 100%, 40%);">-% Error: no timers found</span><br><span> </span><br><span> tdef_vty_test(config)# timer</span><br><span> tea: T1 = 50 s Water Boiling Timeout (default: 50 s)</span><br><span>@@ -234,7 +232,7 @@</span><br><span> test: X23 = 239471 s Negative T number (default: 239471 s)</span><br><span> software: T1 = 13 m Write code (default: 30 m)</span><br><span> software: T2 = 0 ms Hit segfault (default: 20 ms)</span><br><span style="color: hsl(0, 100%, 40%);">-software: T3 = 480 m Fix bugs (default: 480 m)</span><br><span style="color: hsl(120, 100%, 40%);">+software: T3 = 23 m Fix bugs (default: 480 m)</span><br><span> </span><br><span> tdef_vty_test(config)# do show timer</span><br><span> tea: T1 = 50 s Water Boiling Timeout (default: 50 s)</span><br><span>@@ -249,13 +247,14 @@</span><br><span> test: X23 = 239471 s Negative T number (default: 239471 s)</span><br><span> software: T1 = 13 m Write code (default: 30 m)</span><br><span> software: T2 = 0 ms Hit segfault (default: 20 ms)</span><br><span style="color: hsl(0, 100%, 40%);">-software: T3 = 480 m Fix bugs (default: 480 m)</span><br><span style="color: hsl(120, 100%, 40%);">+software: T3 = 23 m Fix bugs (default: 480 m)</span><br><span> </span><br><span> tdef_vty_test(config)# show running-config</span><br><span> ... !timer</span><br><span> timer tea T3 32</span><br><span> timer software T1 13</span><br><span> timer software T2 0</span><br><span style="color: hsl(120, 100%, 40%);">+timer software T3 23</span><br><span> ... !timer</span><br><span> </span><br><span> tdef_vty_test(config)# timer tea T3 default</span><br><span>@@ -263,10 +262,12 @@</span><br><span> tdef_vty_test(config)# show running-config</span><br><span> ... !timer</span><br><span> timer software T2 0</span><br><span style="color: hsl(120, 100%, 40%);">+timer software T3 23</span><br><span> ... !timer</span><br><span> </span><br><span> tdef_vty_test(config)# timer softw 2 default</span><br><span style="color: hsl(0, 100%, 40%);">-% Error: no timers found</span><br><span> tdef_vty_test(config)# timer software 2 default</span><br><span> tdef_vty_test(config)# show running-config</span><br><span> ... !timer</span><br><span style="color: hsl(120, 100%, 40%);">+timer software T3 23</span><br><span style="color: hsl(120, 100%, 40%);">+... !timer</span><br><span>diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty</span><br><span>index 1557744..f2dbacb 100644</span><br><span>--- a/tests/vty/vty_transcript_test.vty</span><br><span>+++ b/tests/vty/vty_transcript_test.vty</span><br><span>@@ -16,13 +16,13 @@</span><br><span> ok argc=1 two</span><br><span> </span><br><span> vty_transcript_test> multi0 o</span><br><span style="color: hsl(0, 100%, 40%);">-ok argc=1 o</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 one</span><br><span> </span><br><span> vty_transcript_test> multi0 t</span><br><span> % Ambiguous command.</span><br><span> </span><br><span> vty_transcript_test> multi0 th</span><br><span style="color: hsl(0, 100%, 40%);">-ok argc=1 th</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 three</span><br><span> </span><br><span> vty_transcript_test> multi0</span><br><span> % Command incomplete.</span><br><span>@@ -39,13 +39,13 @@</span><br><span> ok argc=1 two</span><br><span> </span><br><span> vty_transcript_test> multi1 o</span><br><span style="color: hsl(0, 100%, 40%);">-ok argc=1 o</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 one</span><br><span> </span><br><span> vty_transcript_test> multi1 t</span><br><span> % Ambiguous command.</span><br><span> </span><br><span> vty_transcript_test> multi1 th</span><br><span style="color: hsl(0, 100%, 40%);">-ok argc=1 th</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 three</span><br><span> </span><br><span> vty_transcript_test> multi1</span><br><span> ok argc=0</span><br><span>@@ -68,10 +68,10 @@</span><br><span> ok argc=0</span><br><span> </span><br><span> vty_transcript_test> multi0 thr</span><br><span style="color: hsl(0, 100%, 40%);">-ok argc=1 thr</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 three</span><br><span> </span><br><span> vty_transcript_test> multi1 on</span><br><span style="color: hsl(0, 100%, 40%);">-ok argc=1 on</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 one</span><br><span> </span><br><span> vty_transcript_test> multi2 t</span><br><span> % Ambiguous command.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/14436">change 14436</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/14436"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a </div>
<div style="display:none"> Gerrit-Change-Number: 14436 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>