$OpenBSD: patch-src_ui_readline_c,v 1.1 2014/01/13 08:46:45 dcoppa Exp $

commit 9d5682f8acf991b060119a39bc8aa447175cd294
Author: Lars-Dominik Braun <lars@6xq.net>
Date: Thu Jan 2 14:57:47 2014 +0100

Added Ctrl-u to readline.
Fixed several issues (multibyte, \0-termination) and refactored
readline code while I'm at it.

--- src/ui_readline.c.orig	Sun Sep 15 15:54:04 2013
+++ src/ui_readline.c	Mon Jan 13 07:59:38 2014
@@ -53,7 +53,6 @@ static size_t BarReadlinePrevUtf8 (char *ptr) {
  */
 size_t BarReadline (char *buf, const size_t bufSize, const char *mask,
 		BarReadlineFds_t *input, const BarReadlineFlags_t flags, int timeout) {
-	size_t bufPos = 0;
 	size_t bufLen = 0;
 	unsigned char escapeState = 0;
 	fd_set set;
@@ -107,9 +106,26 @@ size_t BarReadline (char *buf, const size_t bufSize, c
 				if (echo) {
 					fputs ("\n", stdout);
 				}
+				buf[bufLen] = '\0';
 				return bufLen;
 				break;
 
+			/* clear line */
+			case 21:
+				if (echo) {
+					while (bufLen > 0) {
+						const size_t moveSize = BarReadlinePrevUtf8 (&buf[bufLen]);
+						assert (bufLen >= moveSize);
+
+						/* move caret and delete character */
+						fputs ("\033[D\033[K", stdout);
+						bufLen -= moveSize;
+					}
+					fflush (stdout);
+				}
+				bufLen = 0;
+				break;
+
 			/* escape */
 			case 27:
 				escapeState = 1;
@@ -122,28 +138,18 @@ size_t BarReadline (char *buf, const size_t bufSize, c
 			/* backspace */
 			case 8: /* ASCII BS */
 			case 127: /* ASCII DEL */
-				if (bufPos > 0) {
-					size_t moveSize = BarReadlinePrevUtf8 (&buf[bufPos]);
-					assert ((signed int) bufPos - (signed int) moveSize >= 0);
-					memmove (&buf[bufPos-moveSize], &buf[bufPos], moveSize);
+				if (bufLen > 0) {
+					size_t moveSize = BarReadlinePrevUtf8 (&buf[bufLen]);
+					assert (bufLen >= moveSize);
+					memmove (&buf[bufLen-moveSize], &buf[bufLen], moveSize);
 
-					bufPos -= moveSize;
 					bufLen -= moveSize;
 
-					buf[bufLen] = '\0';
-
 					/* move caret back and delete last character */
 					if (echo) {
 						fputs ("\033[D\033[K", stdout);
 						fflush (stdout);
 					}
-				} else if (bufPos == 0 && buf[bufPos] != '\0') {
-					/* delete char at position 0 but don't move cursor any further */
-					buf[bufPos] = '\0';
-					if (echo) {
-						fputs ("\033[K", stdout);
-						fflush (stdout);
-					}
 				}
 				break;
 
@@ -165,25 +171,26 @@ size_t BarReadline (char *buf, const size_t bufSize, c
 					break;
 				}
 				/* don't write beyond buffer's limits */
-				if (bufPos < bufSize-1) {
-					buf[bufPos] = chr;
-					++bufPos;
+				if (bufLen < bufSize-1) {
+					buf[bufLen] = chr;
 					++bufLen;
 					if (echo) {
 						putchar (chr);
 						fflush (stdout);
 					}
 					/* buffer full => return if requested */
-					if (bufPos >= bufSize-1 && (flags & BAR_RL_FULLRETURN)) {
+					if (bufLen >= bufSize-1 && (flags & BAR_RL_FULLRETURN)) {
 						if (echo) {
 							fputs ("\n", stdout);
 						}
+						buf[bufLen] = '\0';
 						return bufLen;
 					}
 				}
 				break;
 		} /* end switch */
 	} /* end while */
+	buf[0] = '\0';
 	return 0;
 }
 
