[svn-commits] kmoore: branch 10 r372518 - in /branches/10: ./ apps/app_queue.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Sep 6 16:40:51 CDT 2012


Author: kmoore
Date: Thu Sep  6 16:40:50 2012
New Revision: 372518

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=372518
Log:
Ensure listed queues are not offered for completion

When using tab-completion for the list of queues on "queue reset stats"
or "queue reload {all|members|parameters|rules}", the tab-completion
listing for further queues erroneously listed queues that had already
been added to the list. The tab-completion listing now only displays
queues that are not already in the list.

(closes issue AST-963)
Reported-by: John Bigelow
........

Merged revisions 372517 from http://svn.asterisk.org/svn/asterisk/branches/1.8

Modified:
    branches/10/   (props changed)
    branches/10/apps/app_queue.c

Propchange: branches/10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: branches/10/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/apps/app_queue.c?view=diff&rev=372518&r1=372517&r2=372518
==============================================================================
--- branches/10/apps/app_queue.c (original)
+++ branches/10/apps/app_queue.c Thu Sep  6 16:40:50 2012
@@ -7371,17 +7371,97 @@
 	return CLI_SUCCESS;
 }
 
-static char *complete_queue(const char *line, const char *word, int pos, int state)
+/*! 
+ * \brief Check if a given word is in a space-delimited list
+ *
+ * \param list Space delimited list of words
+ * \param word The word used to search the list
+ *
+ * \note This function will not return 1 if the word is at the very end of the
+ * list (followed immediately by a \0, not a space) since it is used for
+ * checking tab-completion and a word at the end is still being tab-completed.
+ *
+ * \return Returns 1 if the word is found
+ * \return Returns 0 if the word is not found
+*/
+static int word_in_list(const char *list, const char *word) {
+	int list_len, word_len = strlen(word);
+	const char *find, *end_find, *end_list;
+
+	/* strip whitespace from front */
+	while (isspace(*list)) {
+		list++;
+	}
+
+	while ((find = strstr(list, word))) {
+		/* beginning of find starts inside another word? */
+		if (find != list && *(find - 1) != ' ') {
+			list = find;
+			/* strip word from front */
+			while (!isspace(*list) && *list != '\0') {
+				list++;
+			}
+			/* strip whitespace from front */
+			while (isspace(*list)) {
+				list++;
+			}
+			continue;
+		}
+
+		/* end of find ends inside another word or at very end of list? */
+		list_len = strlen(list);
+		end_find = find + word_len;
+		end_list = list + list_len;
+		if (end_find == end_list || *end_find != ' ') {
+			list = find;
+			/* strip word from front */
+			while (!isspace(*list) && *list != '\0') {
+				list++;
+			}
+			/* strip whitespace from front */
+			while (isspace(*list)) {
+				list++;
+			}
+			continue;
+		}
+
+		/* terminating conditions satisfied, word at beginning or separated by ' ' */
+		return 1;
+	}
+	
+	return 0;
+}
+
+/*! 
+ * \brief Check if a given word is in a space-delimited list
+ *
+ * \param line The line as typed not including the current word being completed
+ * \param word The word currently being completed
+ * \param pos The number of completed words in line
+ * \param state The nth desired completion option
+ * \param word_list_offset Offset into the line where the list of queues begins.  If non-zero, queues in the list will not be offered for further completion.
+ *
+ * \return Returns the queue tab-completion for the given word and state
+*/
+static char *complete_queue(const char *line, const char *word, int pos, int state, ptrdiff_t word_list_offset)
 {
 	struct call_queue *q;
 	char *ret = NULL;
 	int which = 0;
 	int wordlen = strlen(word);
 	struct ao2_iterator queue_iter;
+	const char *word_list = NULL;
+
+	/* for certain commands, already completed items should be left out of
+	 * the list */
+	if (word_list_offset && strlen(line) >= word_list_offset) {
+		word_list = line + word_list_offset;
+	}
 
 	queue_iter = ao2_iterator_init(queues, 0);
 	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
-		if (!strncasecmp(word, q->name, wordlen) && ++which > state) {
+		if (!strncasecmp(word, q->name, wordlen) && ++which > state
+			&& (!word_list_offset || !word_in_list(word_list, q->name))) {
 			ret = ast_strdup(q->name);
 			queue_t_unref(q, "Done with iterator");
 			break;
@@ -7390,9 +7470,10 @@
 	}
 	ao2_iterator_destroy(&queue_iter);
 
-	/* Pretend "rules" is always at the end of the queues list since it is
-	 * an alternate command that should be tab-completable */
-	if (!ret && which == state && !wordlen) {
+	/* Pretend "rules" is at the end of the queues list in certain
+	 * circumstances since it is an alternate command that should be
+	 * tab-completable for "queue show" */
+	if (!ret && which == state && !wordlen && !strncmp("queue show", line, 10)) {
 		ret = ast_strdup("rules");
 	}
 
@@ -7401,8 +7482,9 @@
 
 static char *complete_queue_show(const char *line, const char *word, int pos, int state)
 {
-	if (pos == 2)
-		return complete_queue(line, word, pos, state);
+	if (pos == 2) {
+		return complete_queue(line, word, pos, state, 0);
+	}
 	return NULL;
 }
 
@@ -7832,7 +7914,7 @@
 	case 4: /* only one possible match, "to" */
 		return state == 0 ? ast_strdup("to") : NULL;
 	case 5: /* <queue> */
-		return complete_queue(line, word, pos, state);
+		return complete_queue(line, word, pos, state, 0);
 	case 6: /* only one possible match, "penalty" */
 		return state == 0 ? ast_strdup("penalty") : NULL;
 	case 7:
@@ -7968,8 +8050,9 @@
 	if (pos == 4)   /* only one possible match, 'from' */
 		return (state == 0 ? ast_strdup("from") : NULL);
 
-	if (pos == 5)   /* No need to duplicate code */
-		return complete_queue(line, word, pos, state);
+	if (pos == 5) {  /* No need to duplicate code */
+		return complete_queue(line, word, pos, state, 0);
+	}
 
 	/* here is the case for 3, <member> */
 	queue_iter = ao2_iterator_init(queues, 0);
@@ -8053,7 +8136,7 @@
 	case 4:	/* only one possible match, "queue" */
 		return state == 0 ? ast_strdup("queue") : NULL;
 	case 5:	/* <queue> */
-		return complete_queue(line, word, pos, state);
+		return complete_queue(line, word, pos, state, 0);
 	case 6: /* "reason" */
 		return state == 0 ? ast_strdup("reason") : NULL;
 	case 7: /* Can't autocomplete a reason, since it's 100% customizeable */
@@ -8131,7 +8214,7 @@
 			return NULL;
 		}
 	case 7:
-		return complete_queue(line, word, pos, state);
+		return complete_queue(line, word, pos, state, 0);
 	default:
 		return NULL;
 	}
@@ -8250,7 +8333,7 @@
 			return NULL;
 		case CLI_GENERATE:
 			if (a->pos >= 3) {
-				return complete_queue(a->line, a->word, a->pos, a->n);
+				return complete_queue(a->line, a->word, a->pos, a->n, 17);
 			} else {
 				return NULL;
 			}
@@ -8299,7 +8382,13 @@
 			return NULL;
 		case CLI_GENERATE:
 			if (a->pos >= 3) {
-				return complete_queue(a->line, a->word, a->pos, a->n);
+				/* find the point at which the list of queue names starts */
+				const char *command_end = a->line + strlen("queue reload ");
+				command_end = strchr(command_end, ' ');
+				if (!command_end) {
+					command_end = a->line + strlen(a->line);
+				}
+				return complete_queue(a->line, a->word, a->pos, a->n, command_end - a->line);
 			} else {
 				return NULL;
 			}




More information about the svn-commits mailing list