Module Name:    src
Committed By:   christos
Date:           Tue Dec 10 19:42:09 UTC 2019

Modified Files:
        src/lib/libedit: filecomplete.c

Log Message:
When 'attempted_completion_function' non-NULL, with a 'single_match'
match, the expected space is not being added. Problem observed with
"chronyc" and "sqlite3" tab completion. That functionality got
moved to escape_filename() for the !attempted_completion_function
case, but the non-NULL 'attempted_completion_function' case must
also be handled. (Lonnie Abelbeck)


To generate a diff of this commit:
cvs rdiff -u -r1.61 -r1.62 src/lib/libedit/filecomplete.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libedit/filecomplete.c
diff -u src/lib/libedit/filecomplete.c:1.61 src/lib/libedit/filecomplete.c:1.62
--- src/lib/libedit/filecomplete.c:1.61	Wed Oct  9 10:31:07 2019
+++ src/lib/libedit/filecomplete.c	Tue Dec 10 14:42:09 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: filecomplete.c,v 1.61 2019/10/09 14:31:07 christos Exp $	*/
+/*	$NetBSD: filecomplete.c,v 1.62 2019/12/10 19:42:09 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: filecomplete.c,v 1.61 2019/10/09 14:31:07 christos Exp $");
+__RCSID("$NetBSD: filecomplete.c,v 1.62 2019/12/10 19:42:09 christos Exp $");
 #endif /* not lint && not SCCSID */
 
 #include <sys/types.h>
@@ -703,107 +703,110 @@ fn_complete(EditLine *el,
 	if (over != NULL)
 		*over = 0;
 
-	if (matches) {
-		int i;
-		size_t matches_num, maxlen, match_len, match_display=1;
-		int single_match = matches[2] == NULL &&
-			(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0);
-
-		retval = CC_REFRESH;
-
-		if (matches[0][0] != '\0') {
-			el_deletestr(el, (int)len);
-			if (!attempted_completion_function)
-				completion = escape_filename(el, matches[0],
-				    single_match, app_func);
-			else
-				completion = strdup(matches[0]);
-			if (completion == NULL)
-				goto out;
-			if (single_match) {
-				/* We found exact match. Add a space after it,
-				 * unless we do filename completion and the
-				 * object is a directory. Also do necessary
-				 * escape quoting
-				 */
-				el_winsertstr(el,
-				    ct_decode_string(completion, &el->el_scratch));
-			} else {
-				/* Only replace the completed string with
-				 * common part of possible matches if there is
-				 * possible completion.
-				 */
-				el_winsertstr(el,
-				    ct_decode_string(completion, &el->el_scratch));
-			}
-			free(completion);
-		}
+	if (matches == NULL) {
+		goto out;
+	}
+	int i;
+	size_t matches_num, maxlen, match_len, match_display=1;
+	int single_match = matches[2] == NULL &&
+		(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0);
+
+	retval = CC_REFRESH;
+
+	if (matches[0][0] != '\0') {
+		el_deletestr(el, (int)len);
+		if (!attempted_completion_function)
+			completion = escape_filename(el, matches[0],
+			    single_match, app_func);
+		else
+			completion = strdup(matches[0]);
+		if (completion == NULL)
+			goto out;
 
+		/*
+		 * Replace the completed string with the common part of
+		 * all possible matches if there is a possible completion.
+		 */
+		el_winsertstr(el,
+		    ct_decode_string(completion, &el->el_scratch));
 
-		if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
+		if (single_match && attempted_completion_function) {
 			/*
-			 * More than one match and requested to list possible
-			 * matches.
+			 * We found an exact match. Add a space after
+			 * it, unless we do filename completion and the
+			 * object is a directory. Also do necessary
+			 * escape quoting
 			 */
+			el_winsertstr(el, ct_decode_string(
+			    (*app_func)(completion), &el->el_scratch));
+		}
+		free(completion);
+	}
 
-			for(i = 1, maxlen = 0; matches[i]; i++) {
-				match_len = strlen(matches[i]);
-				if (match_len > maxlen)
-					maxlen = match_len;
-			}
-			/* matches[1] through matches[i-1] are available */
-			matches_num = (size_t)(i - 1);
 
-			/* newline to get on next line from command line */
-			(void)fprintf(el->el_outfile, "\n");
+	if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
+		/*
+		 * More than one match and requested to list possible
+		 * matches.
+		 */
 
-			/*
-			 * If there are too many items, ask user for display
-			 * confirmation.
-			 */
-			if (matches_num > query_items) {
-				(void)fprintf(el->el_outfile,
-				    "Display all %zu possibilities? (y or n) ",
-				    matches_num);
-				(void)fflush(el->el_outfile);
-				if (getc(stdin) != 'y')
-					match_display = 0;
-				(void)fprintf(el->el_outfile, "\n");
-			}
+		for(i = 1, maxlen = 0; matches[i]; i++) {
+			match_len = strlen(matches[i]);
+			if (match_len > maxlen)
+				maxlen = match_len;
+		}
+		/* matches[1] through matches[i-1] are available */
+		matches_num = (size_t)(i - 1);
 
-			if (match_display) {
-				/*
-				 * Interface of this function requires the
-				 * strings be matches[1..num-1] for compat.
-				 * We have matches_num strings not counting
-				 * the prefix in matches[0], so we need to
-				 * add 1 to matches_num for the call.
-				 */
-				fn_display_match_list(el, matches,
-				    matches_num+1, maxlen, app_func);
-			}
-			retval = CC_REDISPLAY;
-		} else if (matches[0][0]) {
+		/* newline to get on next line from command line */
+		(void)fprintf(el->el_outfile, "\n");
+
+		/*
+		 * If there are too many items, ask user for display
+		 * confirmation.
+		 */
+		if (matches_num > query_items) {
+			(void)fprintf(el->el_outfile,
+			    "Display all %zu possibilities? (y or n) ",
+			    matches_num);
+			(void)fflush(el->el_outfile);
+			if (getc(stdin) != 'y')
+				match_display = 0;
+			(void)fprintf(el->el_outfile, "\n");
+		}
+
+		if (match_display) {
 			/*
-			 * There was some common match, but the name was
-			 * not complete enough. Next tab will print possible
-			 * completions.
+			 * Interface of this function requires the
+			 * strings be matches[1..num-1] for compat.
+			 * We have matches_num strings not counting
+			 * the prefix in matches[0], so we need to
+			 * add 1 to matches_num for the call.
 			 */
-			el_beep(el);
-		} else {
-			/* lcd is not a valid object - further specification */
-			/* is needed */
-			el_beep(el);
-			retval = CC_NORM;
+			fn_display_match_list(el, matches,
+			    matches_num+1, maxlen, app_func);
 		}
-
-		/* free elements of array and the array itself */
-		for (i = 0; matches[i]; i++)
-			el_free(matches[i]);
-		el_free(matches);
-		matches = NULL;
+		retval = CC_REDISPLAY;
+	} else if (matches[0][0]) {
+		/*
+		 * There was some common match, but the name was
+		 * not complete enough. Next tab will print possible
+		 * completions.
+		 */
+		el_beep(el);
+	} else {
+		/* lcd is not a valid object - further specification */
+		/* is needed */
+		el_beep(el);
+		retval = CC_NORM;
 	}
 
+	/* free elements of array and the array itself */
+	for (i = 0; matches[i]; i++)
+		el_free(matches[i]);
+	el_free(matches);
+	matches = NULL;
+
 out:
 	el_free(temp);
 	return retval;

Reply via email to