<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7268">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">CLI: Refactor cli_complete.<br><br>* Stop using "_COMMAND NUMMATCHES" on remote consoles. Using this<br> command had doubled the amount of work needed from the Asterisk<br> daemon for each completion request.<br>* Fix code formatting.<br>* Remove static buffer used to send the command, use the same buffer<br> that will receive the results.<br>* Move sort from ast_cli_display_match_list.<br><br>Change-Id: Ie2211b519a3d4bec45bf46e0095bdd01d384cb69<br>---<br>M main/asterisk.c<br>1 file changed, 76 insertions(+), 66 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/68/7268/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/main/asterisk.c b/main/asterisk.c<br>index 46dc9a7..1ee6aa4 100644<br>--- a/main/asterisk.c<br>+++ b/main/asterisk.c<br>@@ -3054,7 +3054,7 @@<br> return strcasecmp(s1, s2);<br> }<br> <br>-static void ast_cli_display_match_list(char **matches, int len, int max)<br>+static void ast_cli_display_match_list(char **matches, int max)<br> {<br> int idx = 1;<br> /* find out how many entries can be put on one line, with two spaces between strings */<br>@@ -3063,8 +3063,6 @@<br> if (limit == 0) {<br> limit = 1;<br> }<br>-<br>- qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);<br> <br> for (;;) {<br> int numoutputline;<br>@@ -3095,7 +3093,7 @@<br> int nummatches = 0;<br> char **matches;<br> int retval = CC_ERROR;<br>- char buf[2048], savechr;<br>+ char savechr;<br> int res;<br> <br> LineInfo *lf = (LineInfo *)el_line(editline);<br>@@ -3116,65 +3114,80 @@<br> len = lf->cursor - ptr;<br> <br> if (ast_opt_remote) {<br>- snprintf(buf, sizeof(buf), "_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);<br>- fdsend(ast_consock, buf);<br>- if ((res = read(ast_consock, buf, sizeof(buf) - 1)) < 0) {<br>- return (char*)(CC_ERROR);<br>- }<br>- buf[res] = '\0';<br>- nummatches = atoi(buf);<br>+ static const char * const cmd_matches_fmt = "_COMMAND MATCHESARRAY \"%s\" \"%s\"";<br>+ char *mbuf;<br>+ char *new_mbuf;<br>+ int mlen = 0, maxmbuf = 2048;<br> <br>- if (nummatches > 0) {<br>- char *mbuf;<br>- char *new_mbuf;<br>- int mlen = 0, maxmbuf = 2048;<br>+ /* Start with a 2048 byte buffer */<br>+ mbuf = ast_malloc(maxmbuf);<br> <br>- /* Start with a 2048 byte buffer */<br>- if (!(mbuf = ast_malloc(maxmbuf))) {<br>- *((char *) lf->cursor) = savechr;<br>- return (char *)(CC_ERROR);<br>- }<br>- snprintf(buf, sizeof(buf), "_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);<br>- fdsend(ast_consock, buf);<br>- res = 0;<br>- mbuf[0] = '\0';<br>- while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {<br>- if (mlen + 1024 > maxmbuf) {<br>- /* Every step increment buffer 1024 bytes */<br>- maxmbuf += 1024;<br>- new_mbuf = ast_realloc(mbuf, maxmbuf);<br>- if (!new_mbuf) {<br>- ast_free(mbuf);<br>- *((char *) lf->cursor) = savechr;<br>- return (char *)(CC_ERROR);<br>- }<br>- mbuf = new_mbuf;<br>- }<br>- /* Only read 1024 bytes at a time */<br>- res = read(ast_consock, mbuf + mlen, 1024);<br>- if (res > 0)<br>- mlen += res;<br>- }<br>- mbuf[mlen] = '\0';<br>-<br>- matches = ast_el_strtoarr(mbuf);<br>+ /* This will run snprintf twice at most. */<br>+ while (mbuf && (mlen = snprintf(mbuf, maxmbuf, cmd_matches_fmt, lf->buffer, ptr)) > maxmbuf) {<br>+ /* Return value does not include space for NULL terminator. */<br>+ maxmbuf = mlen + 1;<br> ast_free(mbuf);<br>- } else<br>- matches = (char **) NULL;<br>- } else {<br>- char **p, *oldbuf=NULL;<br>- nummatches = 0;<br>- matches = ast_cli_completion_matches((char *)lf->buffer,ptr);<br>- for (p = matches; p && *p; p++) {<br>- if (!oldbuf || strcmp(*p,oldbuf))<br>- nummatches++;<br>- oldbuf = *p;<br>+ mbuf = ast_malloc(maxmbuf);<br> }<br>+<br>+ if (!mbuf) {<br>+ *((char *) lf->cursor) = savechr;<br>+<br>+ return (char *)(CC_ERROR);<br>+ }<br>+<br>+ fdsend(ast_consock, mbuf);<br>+ res = 0;<br>+ mlen = 0;<br>+ mbuf[0] = '\0';<br>+<br>+ while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) {<br>+ if (mlen + 1024 > maxmbuf) {<br>+ /* Expand buffer to the next 1024 byte increment. */<br>+ maxmbuf = mlen + 1024;<br>+ new_mbuf = ast_realloc(mbuf, maxmbuf);<br>+ if (!new_mbuf) {<br>+ ast_free(mbuf);<br>+ *((char *) lf->cursor) = savechr;<br>+<br>+ return (char *)(CC_ERROR);<br>+ }<br>+ mbuf = new_mbuf;<br>+ }<br>+ /* Only read 1024 bytes at a time */<br>+ res = read(ast_consock, mbuf + mlen, 1024);<br>+ if (res > 0) {<br>+ mlen += res;<br>+ }<br>+ }<br>+ mbuf[mlen] = '\0';<br>+<br>+ matches = ast_el_strtoarr(mbuf);<br>+ ast_free(mbuf);<br>+ } else {<br>+ matches = ast_cli_completion_matches((char *)lf->buffer,ptr);<br> }<br> <br> if (matches) {<br> int i;<br>- int matches_num, maxlen, match_len;<br>+ int maxlen, match_len;<br>+<br>+ while (matches[nummatches + 1]) {<br>+ nummatches++;<br>+ }<br>+<br>+ if (nummatches > 1) {<br>+ qsort(&matches[0], (size_t)(nummatches), sizeof(char *), ast_el_sort_compare);<br>+ nummatches = 1;<br>+ i = 1;<br>+ while (matches[i + 1]) {<br>+ if (strcasecmp(matches[i], matches[i + 1])) {<br>+ /* don't count duplicates. */<br>+ nummatches++;<br>+ }<br>+ i++;<br>+ }<br>+ }<br> <br> if (matches[0][0] != '\0') {<br> el_deletestr(editline, (int) len);<br>@@ -3190,21 +3203,18 @@<br> /* Must be more than one match */<br> for (i = 1, maxlen = 0; matches[i]; i++) {<br> match_len = strlen(matches[i]);<br>- if (match_len > maxlen)<br>+ if (match_len > maxlen) {<br> maxlen = match_len;<br>+ }<br> }<br>- matches_num = i - 1;<br>- if (matches_num >1) {<br>- fprintf(stdout, "\n");<br>- ast_cli_display_match_list(matches, nummatches, maxlen);<br>- retval = CC_REDISPLAY;<br>- } else {<br>- el_insertstr(editline," ");<br>- retval = CC_REFRESH;<br>- }<br>+<br>+ fprintf(stdout, "\n");<br>+ ast_cli_display_match_list(matches, maxlen);<br>+ retval = CC_REDISPLAY;<br> }<br>- for (i = 0; matches[i]; i++)<br>+ for (i = 0; matches[i]; i++) {<br> ast_free(matches[i]);<br>+ }<br> ast_free(matches);<br> }<br> <br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7268">change 7268</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.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.asterisk.org/7268"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ie2211b519a3d4bec45bf46e0095bdd01d384cb69 </div>
<div style="display:none"> Gerrit-Change-Number: 7268 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>