changeset 31:9b429b283786

Add command history functionality.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 03 Aug 2008 12:02:03 +0300
parents 751cff550992
children 67ec4073e38c
files nnchat.c
diffstat 1 files changed, 33 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/nnchat.c	Sun Aug 03 08:17:55 2008 +0300
+++ b/nnchat.c	Sun Aug 03 12:02:03 2008 +0300
@@ -141,15 +141,15 @@
 
 
 typedef struct {
-	ssize_t pos, len;
-	char data[SET_BUFSIZE];
+	ssize_t pos, len, size;
+	char *data;
 } editbuf_t;
 
 
 int writeBuf(editbuf_t *buf, ssize_t pos, int ch)
 {
 	/* Check arguments */
-	if (buf->len+1 >= SET_BUFSIZE) return -3;
+	if (buf->len+1 >= buf->size) return -3;
 	
 	if (pos < 0)
 		return -1;
@@ -164,7 +164,7 @@
 int insertBuf(editbuf_t *buf, ssize_t pos, int ch)
 {
 	/* Check arguments */
-	if (buf->len+1 >= SET_BUFSIZE) return -3;
+	if (buf->len+1 >= buf->size) return -3;
 	
 	if (pos < 0)
 		return -1;
@@ -197,28 +197,39 @@
 	buf->pos = 0;
 }
 
-editbuf_t * newBuf(void)
+editbuf_t * newBuf(ssize_t n)
 {
-	return (editbuf_t *) th_calloc(1, sizeof(editbuf_t));
+	editbuf_t *res = th_calloc(1, sizeof(editbuf_t));
+	
+	res->data = (char *) th_malloc(n);
+	res->size = n;
+	
+	return res;
 }
 
 void freeBuf(editbuf_t *buf)
 {
-	th_free(buf);
+	if (buf) {
+		th_free(buf->data);
+		th_free(buf);
+	}
 }
 
 editbuf_t * copyBuf(editbuf_t *src)
 {
-	editbuf_t *dst = newBuf();
+	editbuf_t *res;
 	
-	if (dst == NULL) return NULL;
+	assert(src != NULL);
+	
+	if (src == NULL) return NULL;
 	
-	if (src != NULL) {
-		memcpy(dst->data, src->data, SET_BUFSIZE);
-		clearBuf(dst);
-	}
+	if ((res = newBuf(src->size)) == NULL)
+		return NULL;
 	
-	return dst;
+	memcpy(res->data, src->data, src->size);
+	res->pos = res->len = src->len;
+	
+	return res;
 }
 
 void setBufPos(editbuf_t *buf, ssize_t pos)
@@ -962,7 +973,7 @@
 	struct timeval tv;
 	fd_set sockfds;
 	char *tmpStr;
-	editbuf_t *editBuf = newBuf();
+	editbuf_t *editBuf = newBuf(SET_BUFSIZE);
 	editbuf_t *histBuf[SET_MAX_HISTORY+2];
 	int histPos = 0, histMax = 0;
 	
@@ -1144,16 +1155,18 @@
 			case '\r':
 				/* Call the user input handler */
 				if (editBuf->len > 0) {
-					insertBuf(editBuf, editBuf->pos, 0);
 					
 					if (histMax > 0) {
-						freeBuf(histBuf[histMax]);
+						freeBuf(histBuf[SET_MAX_HISTORY+1]);
+						histBuf[SET_MAX_HISTORY+1] = NULL;
 						memmove(&histBuf[2], &histBuf[1], histMax * sizeof(histBuf[0]));
 					}
+					
 					histPos = 0;
 					histBuf[1] = copyBuf(editBuf);
 					if (histMax < SET_MAX_HISTORY) histMax++;
 					
+					insertBuf(editBuf, editBuf->pos, 0);
 					result = handleUserInput(tmpSocket, editBuf->data, editBuf->len);
 					
 					clearBuf(editBuf);
@@ -1178,8 +1191,10 @@
 				break;
 			
 			case KEY_UP:
-				if (histPos == 0)
+				if (histPos == 0) {
+					freeBuf(histBuf[0]);
 					histBuf[0] = copyBuf(editBuf);
+				}
 				if (histPos < histMax) {
 					histPos++;
 					freeBuf(editBuf);