<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12770">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">vty: enable optional-multi-choice syntax: [(one|two)]<br><br>Since very recently we sensibly handle commands like<br><br>  cmd ([one]|[two]|[three])<br><br>as optional multi-choice arguments. In addition, support the more obvious<br>syntax of<br><br>  cmd [(one|two|three)]<br><br>Internally, the tokens are mangled to [one] [two] and [three], which is how the<br>rest of the code detects optional args, and makes sense in terms of UI:<br><br>  > cmd ?<br>  [one]<br>  [two]<br>  [three]<br><br>(i.e. optional arguments are always shown in braces in '?' listings)<br><br>Before this patch, commands defined with a syntax like [(one|two)], would lead<br>to an assertion (shows as "multiple") during program startup.<br><br>Change-Id: I952b3c00f97e2447f2308b0ec6f5f1714692b5b2<br>---<br>M src/vty/command.c<br>M tests/vty/vty_transcript_test.c<br>M tests/vty/vty_transcript_test.vty<br>3 files changed, 45 insertions(+), 3 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 9d02d69..2242e76 100644</span><br><span>--- a/src/vty/command.c</span><br><span>+++ b/src/vty/command.c</span><br><span>@@ -380,6 +380,7 @@</span><br><span> static vector cmd_make_descvec(const char *string, const char *descstr)</span><br><span> {</span><br><span>     int multiple = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     int optional_brace = 0;</span><br><span>      const char *sp;</span><br><span>      char *token;</span><br><span>         int len;</span><br><span>@@ -401,6 +402,12 @@</span><br><span>              while (isspace((int)*cp) && *cp != '\0')</span><br><span>                     cp++;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+             /* Explicitly detect optional multi-choice braces like [(one|two)]. */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (cp[0] == '[' && cp[1] == '(') {</span><br><span style="color: hsl(120, 100%, 40%);">+                   optional_brace = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                   cp++;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          if (*cp == '(') {</span><br><span>                    multiple = 1;</span><br><span>                        cp++;</span><br><span>@@ -408,6 +415,9 @@</span><br><span>          if (*cp == ')') {</span><br><span>                    multiple = 0;</span><br><span>                        cp++;</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (*cp == ']')</span><br><span style="color: hsl(120, 100%, 40%);">+                               cp++;</span><br><span style="color: hsl(120, 100%, 40%);">+                 optional_brace = 0;</span><br><span>          }</span><br><span>            if (*cp == '|') {</span><br><span>                    OSMO_ASSERT(multiple);</span><br><span>@@ -434,9 +444,17 @@</span><br><span> </span><br><span>            len = cp - sp;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              token = _talloc_zero(tall_vty_cmd_ctx, len + 1, "cmd_make_descvec");</span><br><span style="color: hsl(0, 100%, 40%);">-          memcpy(token, sp, len);</span><br><span style="color: hsl(0, 100%, 40%);">-         *(token + len) = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+                token = _talloc_zero(tall_vty_cmd_ctx, len + (optional_brace? 2 : 0) + 1, "cmd_make_descvec");</span><br><span style="color: hsl(120, 100%, 40%);">+              if (optional_brace) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* Place each individual multi-choice token in its own square braces */</span><br><span style="color: hsl(120, 100%, 40%);">+                       token[0] = '[';</span><br><span style="color: hsl(120, 100%, 40%);">+                       memcpy(token + 1, sp, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                   token[1 + len] = ']';</span><br><span style="color: hsl(120, 100%, 40%);">+                 token[2 + len] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      memcpy(token, sp, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                       *(token + len) = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span> </span><br><span>                desc = talloc_zero(tall_vty_cmd_ctx, struct desc);</span><br><span>           desc->cmd = token;</span><br><span>diff --git a/tests/vty/vty_transcript_test.c b/tests/vty/vty_transcript_test.c</span><br><span>index 50131ea..7ffe713 100644</span><br><span>--- a/tests/vty/vty_transcript_test.c</span><br><span>+++ b/tests/vty/vty_transcript_test.c</span><br><span>@@ -170,10 +170,19 @@</span><br><span>       return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(multi2, multi2_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "multi2 [(one|two|three)]",</span><br><span style="color: hsl(120, 100%, 40%);">+      "multi2 test command\n" "1\n2\n3\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       vty_out(vty, "ok argc=%d%s%s%s", argc, argc ? " " : "", argc ? argv[0] : "", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void init_vty_cmds()</span><br><span> {</span><br><span>         install_element_ve(&multi0_cmd);</span><br><span>         install_element_ve(&multi1_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+  install_element_ve(&multi2_cmd);</span><br><span> }</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span>diff --git a/tests/vty/vty_transcript_test.vty b/tests/vty/vty_transcript_test.vty</span><br><span>index 514a5ed..57920a8 100644</span><br><span>--- a/tests/vty/vty_transcript_test.vty</span><br><span>+++ b/tests/vty/vty_transcript_test.vty</span><br><span>@@ -2,6 +2,7 @@</span><br><span> ...</span><br><span>   multi0 (one|two|three)</span><br><span>   multi1 ([one]|[two]|[three])</span><br><span style="color: hsl(120, 100%, 40%);">+  multi2 [(one|two|three)]</span><br><span> </span><br><span> vty_transcript_test> multi0 ?</span><br><span>   one    1</span><br><span>@@ -51,3 +52,17 @@</span><br><span> </span><br><span> vty_transcript_test> multi1 [one]</span><br><span> % Unknown command.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+vty_transcript_test> multi2 ?</span><br><span style="color: hsl(120, 100%, 40%);">+  [one]    1</span><br><span style="color: hsl(120, 100%, 40%);">+  [two]    2</span><br><span style="color: hsl(120, 100%, 40%);">+  [three]  3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+vty_transcript_test> multi2 one</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 one</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+vty_transcript_test> multi2 two</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=1 two</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+vty_transcript_test> multi2</span><br><span style="color: hsl(120, 100%, 40%);">+ok argc=0</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12770">change 12770</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/12770"/><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-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I952b3c00f97e2447f2308b0ec6f5f1714692b5b2 </div>
<div style="display:none"> Gerrit-Change-Number: 12770 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: Vadim Yanitskiy <axilirator@gmail.com> </div>