From: Luigi Rizzo Date: Tue, 12 Dec 2006 09:40:45 +0000 (+0000) Subject: Make sure tab-completion works even when we have typed a fully X-Git-Tag: 1.6.0-beta1~3^2~3748 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33cbc5e55e3a9b2b9d275df52b48d492d88579e7;p=thirdparty%2Fasterisk.git Make sure tab-completion works even when we have typed a fully matching word (e.g. "sip"); this is implemented by this one-line change - for (;; dst++, src += n) { + for (;src < argindex; dst++, src += n) { However this code is not exactly trivial to understand, so i am also adding some comments to help figuring out what it does. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@48408 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/cli.c b/main/cli.c index cd2e407482..895b8b8556 100644 --- a/main/cli.c +++ b/main/cli.c @@ -1598,12 +1598,16 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, char *ret = NULL; char matchstr[80] = ""; int tws = 0; + /* Split the argument into an array of words */ char *dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws); if (!dup) /* malloc error */ return NULL; + + /* Compute the index of the last argument (could be an empty string) */ argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x; - /* rebuild the command, ignore tws */ + + /* rebuild the command, ignore terminating white space and flatten space */ ast_join(matchstr, sizeof(matchstr)-1, argv); matchlen = strlen(matchstr); if (tws) { @@ -1616,7 +1620,12 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, while ( (e = cli_next(&i)) ) { /* XXX repeated code */ int src = 0, dst = 0, n = 0; - for (;; dst++, src += n) { + + /* + * Try to match words, up to and excluding the last word, which + * is either a blank or something that we want to extend. + */ + for (;src < argindex; dst++, src += n) { n = word_match(argv[src], e->cmda[dst]); if (n < 0) break; @@ -1627,12 +1636,17 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n); matchnum += n; /* this many matches here */ if (ret) { + /* + * argv[src] is a valid prefix of the next word in this + * command. If this is also the correct entry, return it. + */ if (matchnum > state) break; free(ret); ret = NULL; } else if (ast_strlen_zero(e->cmda[dst])) { - /* This entry is a prefix of the command string entered + /* + * This entry is a prefix of the command string entered * (only one entry in the list should have this property). * Run the generator if one is available. In any case we are done. */