[Asterisk-code-review] CLI: Refactor cli complete. (asterisk[master])

Corey Farrell asteriskteam at digium.com
Fri Nov 17 13:40:16 CST 2017


Corey Farrell has uploaded this change for review. ( https://gerrit.asterisk.org/7268


Change subject: CLI: Refactor cli_complete.
......................................................................

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
---
M main/asterisk.c
1 file changed, 76 insertions(+), 66 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/68/7268/1

diff --git a/main/asterisk.c b/main/asterisk.c
index 46dc9a7..1ee6aa4 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -3054,7 +3054,7 @@
 	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 */
@@ -3063,8 +3063,6 @@
 	if (limit == 0) {
 		limit = 1;
 	}
-
-	qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare);
 
 	for (;;) {
 		int numoutputline;
@@ -3095,7 +3093,7 @@
 	int nummatches = 0;
 	char **matches;
 	int retval = CC_ERROR;
-	char buf[2048], savechr;
+	char savechr;
 	int res;
 
 	LineInfo *lf = (LineInfo *)el_line(editline);
@@ -3116,65 +3114,80 @@
 	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);
-		}
-		buf[res] = '\0';
-		nummatches = atoi(buf);
+		static const char * const cmd_matches_fmt = "_COMMAND MATCHESARRAY \"%s\" \"%s\"";
+		char *mbuf;
+		char *new_mbuf;
+		int mlen = 0, maxmbuf = 2048;
 
-		if (nummatches > 0) {
-			char *mbuf;
-			char *new_mbuf;
-			int mlen = 0, maxmbuf = 2048;
+		/* Start with a 2048 byte buffer */
+		mbuf = ast_malloc(maxmbuf);
 
-			/* 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;
-				}
-				/* Only read 1024 bytes at a time */
-				res = read(ast_consock, mbuf + mlen, 1024);
-				if (res > 0)
-					mlen += res;
-			}
-			mbuf[mlen] = '\0';
-
-			matches = ast_el_strtoarr(mbuf);
+		/* This will run snprintf twice at most. */
+		while (mbuf && (mlen = snprintf(mbuf, maxmbuf, cmd_matches_fmt, lf->buffer, ptr)) > maxmbuf) {
+			/* Return value does not include space for NULL terminator. */
+			maxmbuf = mlen + 1;
 			ast_free(mbuf);
-		} else
-			matches = (char **) NULL;
-	} 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;
+			mbuf = ast_malloc(maxmbuf);
 		}
+
+		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);
+				}
+				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';
+
+		matches = ast_el_strtoarr(mbuf);
+		ast_free(mbuf);
+	} else {
+		matches = ast_cli_completion_matches((char *)lf->buffer,ptr);
 	}
 
 	if (matches) {
 		int i;
-		int matches_num, maxlen, match_len;
+		int maxlen, match_len;
+
+		while (matches[nummatches + 1]) {
+			nummatches++;
+		}
+
+		if (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);
@@ -3190,21 +3203,18 @@
 			/* 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);
 	}
 

-- 
To view, visit https://gerrit.asterisk.org/7268
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie2211b519a3d4bec45bf46e0095bdd01d384cb69
Gerrit-Change-Number: 7268
Gerrit-PatchSet: 1
Gerrit-Owner: Corey Farrell <git at cfware.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20171117/675e563b/attachment.html>


More information about the asterisk-code-review mailing list