<p>Vadim Yanitskiy has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/20464">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">vty/command: print attribute flags in the output of 'list'<br><br>Here is an example:<br><br>  OsmoAPP(config-foo)# list<br>    ...  help<br>    ...  list<br>    ...  show running-config<br>    ...  exit<br>    ..F  lib-command foo (one|two|three)<br>    ZB.  lib-command bar [zoo]<br>    .bf  app-command foo-bar<br>    z..  app-command zoo .TEXT<br>    ...  app-command nope<br><br>A dot indicates that the associated attribute is not set.<br><br>Note that there is no strict relation between rows and index values<br>of the attributes.  In the example above there could be one or more<br>hidden flag rows corresponding to attributes that are not assigned<br>to any of the commands within 'config-foo' node.<br><br>If neither of the commands belonging to the current node (where<br>'list' command is executed) has attributes, the output would<br>not contain empty dot-rows.<br><br>Global attributes (such as CMD_ATTR_IMMEDIATE) are not yet displayed<br>because we still have not agreed on what kind of symbols to assign<br>them.  This will be implemented later.<br><br>Change-Id: I71cef3ec0fab44c7e11fc353b8bc42268a4ee8f0<br>Related: SYS#4937<br>---<br>M src/vty/command.c<br>1 file changed, 72 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/64/20464/1</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 e82c43b..eeca39b 100644</span><br><span>--- a/src/vty/command.c</span><br><span>+++ b/src/vty/command.c</span><br><span>@@ -3035,11 +3035,81 @@</span><br><span>    return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Compose flag bit-mask for all commands within the given node */</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned int node_flag_mask(const struct cmd_node *cnode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int flag_mask = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int f, i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for (f = 0; f < VTY_CMD_USR_ATTR_NUM; f++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               for (i = 0; i < vector_active(cnode->cmd_vector); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        const struct cmd_element *cmd;</span><br><span style="color: hsl(120, 100%, 40%);">+                        char flag_letter;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if ((cmd = vector_slot(cnode->cmd_vector, i)) == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+                             continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (cmd->attr & (CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN))</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (~cmd->usrattr & (1 << f))</span><br><span style="color: hsl(120, 100%, 40%);">+                            continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (cmd->attr & CMD_ATTR_LIB_COMMAND)</span><br><span style="color: hsl(120, 100%, 40%);">+                          flag_letter = cmd_lib_attr_letters[f];</span><br><span style="color: hsl(120, 100%, 40%);">+                        else</span><br><span style="color: hsl(120, 100%, 40%);">+                          flag_letter = host.app_info->usr_attr_letters[f];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (flag_letter == '\0')</span><br><span style="color: hsl(120, 100%, 40%);">+                              continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   flag_mask |= (1 << f);</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return flag_mask;</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%);">+/* Compose flag char-mask for the given command (e.g. '.F.OB..') */</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *cmd_flag_mask(const struct cmd_element *cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+                           unsigned int flag_mask)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   static char char_mask[VTY_CMD_USR_ATTR_NUM + 1];</span><br><span style="color: hsl(120, 100%, 40%);">+      char *ptr = &char_mask[0];</span><br><span style="color: hsl(120, 100%, 40%);">+        char flag_letter;</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int f;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (f = 0; f < VTY_CMD_USR_ATTR_NUM; f++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (~flag_mask & (1 << f))</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (~cmd->usrattr & (1 << f)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  *(ptr++) = '.';</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</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->attr & CMD_ATTR_LIB_COMMAND)</span><br><span style="color: hsl(120, 100%, 40%);">+                  flag_letter = cmd_lib_attr_letters[f];</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  flag_letter = host.app_info->usr_attr_letters[f];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                *(ptr++) = flag_letter ? flag_letter : '.';</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 (ptr > &char_mask[0]) {</span><br><span style="color: hsl(120, 100%, 40%);">+             *(ptr++) = ' ';</span><br><span style="color: hsl(120, 100%, 40%);">+               *(ptr++) = ' ';</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%);">+   *ptr = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return char_mask;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Help display function for all node. */</span><br><span> gDEFUN(config_list, config_list_cmd, "list", "Print command list\n")</span><br><span> {</span><br><span>         unsigned int i;</span><br><span>      struct cmd_node *cnode = vector_slot(cmdvec, vty->node);</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int flag_mask = node_flag_mask(cnode);</span><br><span>      struct cmd_element *cmd;</span><br><span> </span><br><span>         for (i = 0; i < vector_active(cnode->cmd_vector); i++) {</span><br><span>@@ -3047,7 +3117,8 @@</span><br><span>                       continue;</span><br><span>            if (cmd->attr & (CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN))</span><br><span>                      continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               vty_out(vty, "  %s%s", cmd->string, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "  %s%s%s", cmd_flag_mask(cmd, flag_mask),</span><br><span style="color: hsl(120, 100%, 40%);">+                     cmd->string, VTY_NEWLINE);</span><br><span>        }</span><br><span> </span><br><span>        return CMD_SUCCESS;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/20464">change 20464</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/+/20464"/><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: I71cef3ec0fab44c7e11fc353b8bc42268a4ee8f0 </div>
<div style="display:none"> Gerrit-Change-Number: 20464 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>