Mercurial > hg > nnchat
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; |