comparison nnchat.c @ 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
comparison
equal deleted inserted replaced
30:751cff550992 31:9b429b283786
139 return TRUE; 139 return TRUE;
140 } 140 }
141 141
142 142
143 typedef struct { 143 typedef struct {
144 ssize_t pos, len; 144 ssize_t pos, len, size;
145 char data[SET_BUFSIZE]; 145 char *data;
146 } editbuf_t; 146 } editbuf_t;
147 147
148 148
149 int writeBuf(editbuf_t *buf, ssize_t pos, int ch) 149 int writeBuf(editbuf_t *buf, ssize_t pos, int ch)
150 { 150 {
151 /* Check arguments */ 151 /* Check arguments */
152 if (buf->len+1 >= SET_BUFSIZE) return -3; 152 if (buf->len+1 >= buf->size) return -3;
153 153
154 if (pos < 0) 154 if (pos < 0)
155 return -1; 155 return -1;
156 else if (pos >= buf->len) { 156 else if (pos >= buf->len) {
157 buf->data[buf->len++] = ch; 157 buf->data[buf->len++] = ch;
162 } 162 }
163 163
164 int insertBuf(editbuf_t *buf, ssize_t pos, int ch) 164 int insertBuf(editbuf_t *buf, ssize_t pos, int ch)
165 { 165 {
166 /* Check arguments */ 166 /* Check arguments */
167 if (buf->len+1 >= SET_BUFSIZE) return -3; 167 if (buf->len+1 >= buf->size) return -3;
168 168
169 if (pos < 0) 169 if (pos < 0)
170 return -1; 170 return -1;
171 else if (pos >= buf->len) { 171 else if (pos >= buf->len) {
172 buf->data[buf->len] = ch; 172 buf->data[buf->len] = ch;
195 { 195 {
196 buf->len = 0; 196 buf->len = 0;
197 buf->pos = 0; 197 buf->pos = 0;
198 } 198 }
199 199
200 editbuf_t * newBuf(void) 200 editbuf_t * newBuf(ssize_t n)
201 { 201 {
202 return (editbuf_t *) th_calloc(1, sizeof(editbuf_t)); 202 editbuf_t *res = th_calloc(1, sizeof(editbuf_t));
203
204 res->data = (char *) th_malloc(n);
205 res->size = n;
206
207 return res;
203 } 208 }
204 209
205 void freeBuf(editbuf_t *buf) 210 void freeBuf(editbuf_t *buf)
206 { 211 {
207 th_free(buf); 212 if (buf) {
213 th_free(buf->data);
214 th_free(buf);
215 }
208 } 216 }
209 217
210 editbuf_t * copyBuf(editbuf_t *src) 218 editbuf_t * copyBuf(editbuf_t *src)
211 { 219 {
212 editbuf_t *dst = newBuf(); 220 editbuf_t *res;
213 221
214 if (dst == NULL) return NULL; 222 assert(src != NULL);
215 223
216 if (src != NULL) { 224 if (src == NULL) return NULL;
217 memcpy(dst->data, src->data, SET_BUFSIZE); 225
218 clearBuf(dst); 226 if ((res = newBuf(src->size)) == NULL)
219 } 227 return NULL;
220 228
221 return dst; 229 memcpy(res->data, src->data, src->size);
230 res->pos = res->len = src->len;
231
232 return res;
222 } 233 }
223 234
224 void setBufPos(editbuf_t *buf, ssize_t pos) 235 void setBufPos(editbuf_t *buf, ssize_t pos)
225 { 236 {
226 /* Check arguments */ 237 /* Check arguments */
960 cursesInit = FALSE, 971 cursesInit = FALSE,
961 insertMode = TRUE; 972 insertMode = TRUE;
962 struct timeval tv; 973 struct timeval tv;
963 fd_set sockfds; 974 fd_set sockfds;
964 char *tmpStr; 975 char *tmpStr;
965 editbuf_t *editBuf = newBuf(); 976 editbuf_t *editBuf = newBuf(SET_BUFSIZE);
966 editbuf_t *histBuf[SET_MAX_HISTORY+2]; 977 editbuf_t *histBuf[SET_MAX_HISTORY+2];
967 int histPos = 0, histMax = 0; 978 int histPos = 0, histMax = 0;
968 979
969 memset(histBuf, 0, sizeof(histBuf)); 980 memset(histBuf, 0, sizeof(histBuf));
970 981
1142 case KEY_ENTER: 1153 case KEY_ENTER:
1143 case '\n': 1154 case '\n':
1144 case '\r': 1155 case '\r':
1145 /* Call the user input handler */ 1156 /* Call the user input handler */
1146 if (editBuf->len > 0) { 1157 if (editBuf->len > 0) {
1147 insertBuf(editBuf, editBuf->pos, 0);
1148 1158
1149 if (histMax > 0) { 1159 if (histMax > 0) {
1150 freeBuf(histBuf[histMax]); 1160 freeBuf(histBuf[SET_MAX_HISTORY+1]);
1161 histBuf[SET_MAX_HISTORY+1] = NULL;
1151 memmove(&histBuf[2], &histBuf[1], histMax * sizeof(histBuf[0])); 1162 memmove(&histBuf[2], &histBuf[1], histMax * sizeof(histBuf[0]));
1152 } 1163 }
1164
1153 histPos = 0; 1165 histPos = 0;
1154 histBuf[1] = copyBuf(editBuf); 1166 histBuf[1] = copyBuf(editBuf);
1155 if (histMax < SET_MAX_HISTORY) histMax++; 1167 if (histMax < SET_MAX_HISTORY) histMax++;
1156 1168
1169 insertBuf(editBuf, editBuf->pos, 0);
1157 result = handleUserInput(tmpSocket, editBuf->data, editBuf->len); 1170 result = handleUserInput(tmpSocket, editBuf->data, editBuf->len);
1158 1171
1159 clearBuf(editBuf); 1172 clearBuf(editBuf);
1160 1173
1161 if (result < 0) { 1174 if (result < 0) {
1176 } 1189 }
1177 update = TRUE; 1190 update = TRUE;
1178 break; 1191 break;
1179 1192
1180 case KEY_UP: 1193 case KEY_UP:
1181 if (histPos == 0) 1194 if (histPos == 0) {
1195 freeBuf(histBuf[0]);
1182 histBuf[0] = copyBuf(editBuf); 1196 histBuf[0] = copyBuf(editBuf);
1197 }
1183 if (histPos < histMax) { 1198 if (histPos < histMax) {
1184 histPos++; 1199 histPos++;
1185 freeBuf(editBuf); 1200 freeBuf(editBuf);
1186 editBuf = copyBuf(histBuf[histPos]); 1201 editBuf = copyBuf(histBuf[histPos]);
1187 update = TRUE; 1202 update = TRUE;