Merged revisions 313860 via svnmerge from
authorJonathan Rose <jrose@digium.com>
Fri, 15 Apr 2011 15:20:46 +0000 (15:20 +0000)
committerJonathan Rose <jrose@digium.com>
Fri, 15 Apr 2011 15:20:46 +0000 (15:20 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r313860 | jrose | 2011-04-15 10:08:05 -0500 (Fri, 15 Apr 2011) | 17 lines

  Merged revisions 313859 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2

  ........
    r313859 | jrose | 2011-04-15 09:58:37 -0500 (Fri, 15 Apr 2011) | 10 lines

    Fix a Tab Completion bug that occurs due to multiple matches on a substring.

    Makes word_match function in cli.c repeat a search for a command string until
    a proper match is found or the string is searched to the last point.

    (closes issue #17494)
    Reported by: ffossard

    Review: https://reviewboard.asterisk.org/r/1180/
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@313867 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/cli.c

index 55225ed..85f4473 100644 (file)
@@ -1879,20 +1879,30 @@ static int word_match(const char *cmd, const char *cli_word)
                return -1;
        if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
                return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
-       /* regexp match, takes [foo|bar] or {foo|bar} */
        l = strlen(cmd);
        /* wildcard match - will extend in the future */
        if (l > 0 && cli_word[0] == '%') {
                return 1;       /* wildcard */
        }
+
+       /* Start a search for the command entered against the cli word in question */
        pos = strcasestr(cli_word, cmd);
-       if (pos == NULL) /* not found, say ok if optional */
-               return cli_word[0] == '[' ? 0 : -1;
-       if (pos == cli_word)    /* no valid match at the beginning */
-               return -1;
-       if (strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l]))
-               return 1;       /* valid match */
-       return -1;      /* not found */
+       while (pos) {
+
+               /*
+                *Check if the word matched with is surrounded by reserved characters on both sides
+                * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about.
+                * If it is surrounded by reserved chars and isn't at the beginning, it's a match.
+                */
+               if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
+                       return 1;       /* valid match */
+               }
+
+               /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/
+               pos = strcasestr(pos + 1, cmd);
+       }
+       /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */
+       return -1;
 }
 
 /*! \brief if word is a valid prefix for token, returns the pos-th