CLI: Refactor cli_complete.

* Stop using "_COMMAND NUMMATCHES" on remote consoles.  Using this
  command had doubled the amount of work needed from the Asterisk
  daemon for each completion request.
* Fix code formatting.
* Remove static buffer used to send the command, use the same buffer
  that will receive the results.
* Move sort from ast_cli_display_match_list.

Change-Id: Ie2211b519a3d4bec45bf46e0095bdd01d384cb69
certified/13.21
Corey Farrell 8 years ago
parent e723331f4f
commit 26a400c67a

@ -3183,7 +3183,7 @@ static int ast_el_sort_compare(const void *i1, const void *i2)
return strcasecmp(s1, s2);
}
static void ast_cli_display_match_list(char **matches, int len, int max)
static void ast_cli_display_match_list(char **matches, int max)
{
int idx = 1;
/* find out how many entries can be put on one line, with two spaces between strings */
@ -3193,8 +3193,6 @@ static void ast_cli_display_match_list(char **matches, int len, int max)
limit = 1;
}
qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
for (;;) {
int numoutputline;
@ -3224,7 +3222,7 @@ static char *cli_complete(EditLine *editline, int ch)
int nummatches = 0;
char **matches;
int retval = CC_ERROR;
char buf[2048], savechr;
char savechr;
int res;
LineInfo *lf = (LineInfo *)el_line(editline);
@ -3245,65 +3243,80 @@ static char *cli_complete(EditLine *editline, int ch)
len = lf->cursor - ptr;
if (ast_opt_remote) {
snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);
fdsend(ast_consock, buf);
if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {
return (char*)(CC_ERROR);
#define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\""
char *mbuf;
char *new_mbuf;
int mlen = 0, maxmbuf = 2048;
/* Start with a 2048 byte buffer */
mbuf = ast_malloc(maxmbuf);
/* This will run snprintf twice at most. */
while (mbuf && (mlen = snprintf(mbuf, maxmbuf, CMD_MATCHESARRAY, lf->buffer, ptr)) > maxmbuf) {
/* Return value does not include space for NULL terminator. */
maxmbuf = mlen + 1;
ast_free(mbuf);
mbuf = ast_malloc(maxmbuf);
}
buf[res] = '\0';
nummatches = atoi(buf);
if (nummatches > 0) {
char *mbuf;
char *new_mbuf;
int mlen = 0, maxmbuf = 2048;
/* Start with a 2048 byte buffer */
if (!(mbuf = ast_malloc(maxmbuf))) {
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
}
snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);
fdsend(ast_consock, buf);
res = 0;
mbuf[0] = '\0';
while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
if (mlen + 1024 > maxmbuf) {
/* Every step increment buffer 1024 bytes */
maxmbuf += 1024;
new_mbuf = ast_realloc(mbuf, maxmbuf);
if (!new_mbuf) {
ast_free(mbuf);
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
}
mbuf = new_mbuf;
if (!mbuf) {
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
}
fdsend(ast_consock, mbuf);
res = 0;
mlen = 0;
mbuf[0] = '\0';
while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {
if (mlen + 1024 > maxmbuf) {
/* Expand buffer to the next 1024 byte increment. */
maxmbuf = mlen + 1024;
new_mbuf = ast_realloc(mbuf, maxmbuf);
if (!new_mbuf) {
ast_free(mbuf);
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
}
/* Only read 1024 bytes at a time */
res = read(ast_consock, mbuf + mlen, 1024);
if (res > 0)
mlen += res;
mbuf = new_mbuf;
}
/* Only read 1024 bytes at a time */
res = read(ast_consock, mbuf + mlen, 1024);
if (res > 0) {
mlen += res;
}
mbuf[mlen] = '\0';
}
mbuf[mlen] = '\0';
matches = ast_el_strtoarr(mbuf);
ast_free(mbuf);
} else
matches = (char **) NULL;
matches = ast_el_strtoarr(mbuf);
ast_free(mbuf);
} else {
char **p, *oldbuf=NULL;
nummatches = 0;
matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
for (p = matches; p && *p; p++) {
if (!oldbuf || strcmp(*p,oldbuf))
nummatches++;
oldbuf = *p;
}
}
if (matches) {
int i;
int matches_num, maxlen, match_len;
int maxlen, match_len;
while (matches[nummatches + 1]) {
nummatches++;
}
if (ast_opt_remote && nummatches > 1) {
qsort(&matches[0], (size_t)(nummatches), sizeof(char *), ast_el_sort_compare);
nummatches = 1;
i = 1;
while (matches[i + 1]) {
if (strcasecmp(matches[i], matches[i + 1])) {
/* don't count duplicates. */
nummatches++;
}
i++;
}
}
if (matches[0][0] != '\0') {
el_deletestr(editline, (int) len);
@ -3319,21 +3332,18 @@ static char *cli_complete(EditLine *editline, int ch)
/* Must be more than one match */
for (i = 1, maxlen = 0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
if (match_len > maxlen) {
maxlen = match_len;
}
}
matches_num = i - 1;
if (matches_num >1) {
fprintf(stdout, "\n");
ast_cli_display_match_list(matches, nummatches, maxlen);
retval = CC_REDISPLAY;
} else {
el_insertstr(editline," ");
retval = CC_REFRESH;
}
fprintf(stdout, "\n");
ast_cli_display_match_list(matches, maxlen);
retval = CC_REDISPLAY;
}
for (i = 0; matches[i]; i++)
for (i = 0; matches[i]; i++) {
ast_free(matches[i]);
}
ast_free(matches);
}

Loading…
Cancel
Save