--- libaitcli/example/t.c 2010/06/02 17:17:56 1.1.2.1 +++ libaitcli/example/t.c 2010/06/03 23:29:32 1.1.2.2 @@ -14,43 +14,86 @@ int freeLineCLI(linebuffer_t * __restrict buffer); +static inline void +clrscrEOL(linebuffer_t * __restrict buf) +{ + register int i; + + if (buf) { + write(buf->line_out, K_CR, 1); + + for (i = 0; i < buf->line_len; i++) + write(buf->line_out, K_SPACE, 1); + } +} + +static inline void +printfEOL(linebuffer_t * __restrict buf, int len, int prompt) +{ + if (buf) { + write(buf->line_out, K_CR, 1); + + if (prompt && buf->line_prompt) + write(buf->line_out, buf->line_prompt, buf->line_bol); + +// printf("buf=%s eol=%d bol=%d len=%d\n", buf->line_buf, buf->line_eol, buf->line_bol, buf->line_len); + write(buf->line_out, buf->line_buf, len == -1 ? buf->line_eol - buf->line_bol: len); + } +} + +static inline void +printfCR(linebuffer_t * __restrict buf, int prompt) +{ + if (buf) { + write(buf->line_out, K_CR, 1); + + if (prompt) + if (prompt && buf->line_prompt) + write(buf->line_out, buf->line_prompt, buf->line_bol); + } +} + +static inline void +printfCLI(linebuffer_t * __restrict buf, const unsigned char *text, int textlen, int prompt) +{ + if (buf && text && textlen) { + if (prompt && buf->line_prompt) + write(buf->line_out, buf->line_prompt, buf->line_bol); + + write(buf->line_out, text, textlen); + } +} + + static int catCh2Buf(int idx, void * __restrict buffer) { linebuffer_t *buf = buffer; - char *ptr; + int pos; if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - ptr = realloc(buf->line_buf, buf->line_len + buf->line_keys[idx].key_len); - if (!ptr) - return RETCODE_ERR; - else + pos = buf->line_eol - buf->line_bol; + + if (buf->line_eol == buf->line_len - 1) buf->line_len += buf->line_keys[idx].key_len; + buf->line_eol += buf->line_keys[idx].key_len; - memcpy(ptr + buf->line_eol, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); - ptr[buf->line_len - 1] = 0; + memcpy(buf->line_buf + pos, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); + buf->line_buf[buf->line_len - 1] = 0; - /* show */ write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); - - buf->line_eol += buf->line_keys[idx].key_len; - buf->line_buf = ptr; return RETCODE_OK; } static int bufEOL(int idx, void * __restrict buffer) { - linebuffer_t *buf = buffer; - if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - /* show */ - write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); - + printfCR(buffer, 1); return RETCODE_EOL; } @@ -62,9 +105,7 @@ bufEOF(int idx, void * __restrict buffer) if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - /* show */ write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); - return RETCODE_EOF; } @@ -86,8 +127,7 @@ static int bufUP(int idx, void * __restrict buffer) { linebuffer_t *buf = buffer; - char *ptr; - register int i; + int pos; if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; @@ -99,28 +139,18 @@ bufUP(int idx, void * __restrict buffer) if (!buf->line_h) return RETCODE_OK; - /* clear line */ - write(buf->line_out, K_CR, 1); - for (i = 0; i < buf->line_len; i++) - write(buf->line_out, K_SPACE, 1); + clrscrEOL(buf); + freeLineCLI(buf); - freeLineCLI(buffer); - ptr = realloc(buf->line_buf, buf->line_len + buf->line_h->hist_len); - if (!ptr) - return RETCODE_ERR; - else - buf->line_len += buf->line_h->hist_len; + pos = buf->line_eol - buf->line_bol; - memcpy(ptr + buf->line_eol, buf->line_h->hist_line, buf->line_h->hist_len); - ptr[buf->line_len - 1] = 0; - + buf->line_len += buf->line_h->hist_len; buf->line_eol += buf->line_h->hist_len; - buf->line_buf = ptr; - /* show */ - write(buf->line_out, K_CR, 1); - write(buf->line_out, buf->line_buf, buf->line_len); + memcpy(buf->line_buf + pos, buf->line_h->hist_line, buf->line_h->hist_len); + buf->line_buf[buf->line_len - 1] = 0; + printfEOL(buf, -1, 1); return RETCODE_OK; } @@ -128,8 +158,7 @@ static int bufDOWN(int idx, void * __restrict buffer) { linebuffer_t *buf = buffer; - char *ptr; - register int i; + int pos; if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; @@ -141,51 +170,144 @@ bufDOWN(int idx, void * __restrict buffer) if (!buf->line_h) return RETCODE_OK; - /* clear line */ - write(buf->line_out, K_CR, 1); - for (i = 0; i < buf->line_len; i++) - write(buf->line_out, K_SPACE, 1); + clrscrEOL(buf); + freeLineCLI(buf); + pos = buf->line_eol - buf->line_bol; + + buf->line_len += buf->line_h->hist_len; + buf->line_eol += buf->line_h->hist_len; + + memcpy(buf->line_buf + pos, buf->line_h->hist_line, buf->line_h->hist_len); + buf->line_buf[buf->line_len - 1] = 0; + + printfEOL(buf, -1, 1); + return RETCODE_OK; +} + +static int +bufClr(int idx, void * __restrict buffer) +{ + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + clrscrEOL(buffer); freeLineCLI(buffer); - ptr = realloc(buf->line_buf, buf->line_len + buf->line_h->hist_len); - if (!ptr) + + printfCR(buffer, 1); + return RETCODE_OK; +} + +static int +bufBS(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - else - buf->line_len += buf->line_h->hist_len; - memcpy(ptr + buf->line_eol, buf->line_h->hist_line, buf->line_h->hist_len); - ptr[buf->line_len - 1] = 0; + if (buf->line_bol < buf->line_eol) { + clrscrEOL(buf); - buf->line_eol += buf->line_h->hist_len; - buf->line_buf = ptr; + buf->line_eol--; + buf->line_len--; + buf->line_buf[buf->line_eol - buf->line_bol] = 0; - /* show */ - write(buf->line_out, K_CR, 1); - write(buf->line_out, buf->line_buf, buf->line_len); + printfEOL(buf, -1, 1); + } return RETCODE_OK; } static int -bufClr(int idx, void * __restrict buffer) +bufMode(int idx, void * __restrict buffer) { linebuffer_t *buf = buffer; - register int i; if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - /* clear line */ - write(buf->line_out, K_CR, 1); - for (i = 0; i < buf->line_len; i++) - write(buf->line_out, K_SPACE, 1); + buf->line_mode = !buf->line_mode ? LINEMODE_OVER : LINEMODE_INS; + return RETCODE_OK; +} - freeLineCLI(buffer); +static int +bufBegin(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; - write(buf->line_out, K_CR, 1); + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + buf->line_eol = buf->line_bol; + + printfCR(buf, 1); return RETCODE_OK; } +static int +bufEnd(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + buf->line_eol = buf->line_len - 1; + + printfEOL(buf, -1, 1); + return RETCODE_OK; +} + +static int +bufLEFT(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_bol < buf->line_eol) + printfEOL(buf, --buf->line_eol - buf->line_bol, 1); + + return RETCODE_OK; +} + +static int +bufRIGHT(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_eol < buf->line_len - 1) + printfEOL(buf, ++buf->line_eol - buf->line_bol, 1); + + return RETCODE_OK; +} + +static int +bufDel(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_bol < buf->line_eol) { + clrscrEOL(buf); + + buf->line_eol--; + buf->line_len--; + buf->line_buf[buf->line_eol] = 0; + + printfEOL(buf, -1, 1); + } + + return RETCODE_OK; +} + // --------------------------------------------------------------- int @@ -206,7 +328,7 @@ bindKeyCLI(bindkey_t * __restrict key, linebuffer_t * } linebuffer_t * -initCLI(int fin, int fout) +initCLI(int fin, int fout, const char *prompt) { linebuffer_t *buffer; bindkey_t *keys; @@ -225,17 +347,32 @@ initCLI(int fin, int fout) buffer->line_out = fout; TAILQ_INIT(&buffer->line_history); + + if (prompt) { + buffer->line_prompt = strdup(prompt); + if (!buffer->line_prompt) { + free(buffer); + return NULL; + } else { + buffer->line_bol = strlen(buffer->line_prompt); + buffer->line_eol = buffer->line_bol; + } + } } - buffer->line_buf = malloc(1); + buffer->line_buf = malloc(BUFSIZ); if (!buffer->line_buf) { + if (buffer->line_prompt) + free(buffer->line_prompt); free(buffer); return NULL; } else { - *buffer->line_buf = 0; - buffer->line_len = 1; + memset(buffer->line_buf, 0, BUFSIZ); + buffer->line_len = 1 + buffer->line_eol; } keys = calloc(MAX_BINDKEY + 1, sizeof(bindkey_t)); if (!keys) { + if (buffer->line_prompt) + free(buffer->line_prompt); free(buffer->line_buf); free(buffer); return NULL; @@ -252,8 +389,14 @@ initCLI(int fin, int fout) keys[i].key_func = bufEOF; if (i == *K_CTRL_M || i == *K_CTRL_J) keys[i].key_func = bufEOL; + if (i == *K_CTRL_H || i == *K_BACKSPACE) + keys[i].key_func = bufBS; if (i == *K_CTRL_C) keys[i].key_func = bufClr; + if (i == *K_CTRL_A) + keys[i].key_func = bufBegin; + if (i == *K_CTRL_E) + keys[i].key_func = bufEnd; if (i >= *K_SPACE && i < *K_BACKSPACE) keys[i].key_func = catCh2Buf; if (i > *K_BACKSPACE && i < 0xff) @@ -324,8 +467,10 @@ initCLI(int fin, int fout) keys[i].key_len = sizeof K_CTRL_F12 - 1; memcpy(keys[i].key_ch, K_CTRL_F12, keys[i++].key_len); keys[i].key_len = sizeof K_HOME - 1; + keys[i].key_func = bufBegin; memcpy(keys[i].key_ch, K_HOME, keys[i++].key_len); keys[i].key_len = sizeof K_END - 1; + keys[i].key_func = bufEnd; memcpy(keys[i].key_ch, K_END, keys[i++].key_len); keys[i].key_len = sizeof K_UP - 1; keys[i].key_func = bufUP; @@ -334,15 +479,20 @@ initCLI(int fin, int fout) keys[i].key_func = bufDOWN; memcpy(keys[i].key_ch, K_DOWN, keys[i++].key_len); keys[i].key_len = sizeof K_RIGHT - 1; + keys[i].key_func = bufRIGHT; memcpy(keys[i].key_ch, K_RIGHT, keys[i++].key_len); keys[i].key_len = sizeof K_LEFT - 1; + keys[i].key_func = bufLEFT; memcpy(keys[i].key_ch, K_LEFT, keys[i++].key_len); keys[i].key_len = sizeof K_BTAB - 1; + keys[i].key_func = bufBS; memcpy(keys[i].key_ch, K_BTAB, keys[i++].key_len); // 4 bytes keys[i].key_len = sizeof K_INS - 1; + keys[i].key_func = bufMode; memcpy(keys[i].key_ch, K_INS, keys[i++].key_len); keys[i].key_len = sizeof K_DEL - 1; + keys[i].key_func = bufDel; memcpy(keys[i].key_ch, K_DEL, keys[i++].key_len); keys[i].key_len = sizeof K_PGUP - 1; memcpy(keys[i].key_ch, K_PGUP, keys[i++].key_len); @@ -388,6 +538,9 @@ endCLI(linebuffer_t * __restrict buffer) free(h); } + if (buffer->line_prompt) + free(buffer->line_prompt); + if (buffer->line_keys) free(buffer->line_keys); if (buffer->line_buf) @@ -398,6 +551,27 @@ endCLI(linebuffer_t * __restrict buffer) } } +void +setPromptCLI(linebuffer_t * __restrict buffer, const char *prompt) +{ + if (buffer) { + if (buffer->line_prompt) { + free(buffer->line_prompt); + buffer->line_prompt = NULL; + buffer->line_bol = 0; + } + + if (prompt) { + buffer->line_prompt = strdup(prompt); + if (buffer->line_prompt) { + buffer->line_bol = strlen(buffer->line_prompt); + buffer->line_eol = buffer->line_bol; + buffer->line_len = 1 + buffer->line_eol; + } + } + } +} + int freeLineCLI(linebuffer_t * __restrict buffer) { @@ -407,11 +581,11 @@ freeLineCLI(linebuffer_t * __restrict buffer) if (buffer->line_buf) free(buffer->line_buf); - buffer->line_buf = malloc(1); + buffer->line_buf = malloc(BUFSIZ); if (buffer->line_buf) { - *buffer->line_buf = 0; - buffer->line_eol = 0; - buffer->line_len = 1; + memset(buffer->line_buf, 0, BUFSIZ); + buffer->line_eol = buffer->line_bol; + buffer->line_len = 1 + buffer->line_eol; code = RETCODE_OK; } @@ -435,6 +609,7 @@ readLineCLI(linebuffer_t * __restrict buffer) fds.fd = buffer->line_in; fds.events = POLLIN; + printfCR(buffer, 1); while (42) { if (poll(&fds, 1, -1) < 1) return RETCODE_ERR; @@ -511,7 +686,7 @@ addHistoryCLI(linebuffer_t * __restrict buffer, const } int -saveHistoryCLI(linebuffer_t * __restrict buffer, const char *histfile) +saveHistoryCLI(linebuffer_t * __restrict buffer, const char *histfile, int lines) { FILE *f; mode_t mode; @@ -529,8 +704,14 @@ saveHistoryCLI(linebuffer_t * __restrict buffer, const f = fopen(szFName, "w"); if (!f) return RETCODE_ERR; - TAILQ_FOREACH(h, &buffer->line_history, hist_next) + TAILQ_FOREACH(h, &buffer->line_history, hist_next) { fprintf(f, "%s\n", h->hist_line); + + if (lines) + lines--; + else + break; + } fclose(f); umask(mode); @@ -580,13 +761,14 @@ resetHistoryCLI(linebuffer_t * __restrict buffer) buffer->line_h = NULL; } +// ------------------------------------------------------------ int main() { int ret; bindkey_t key = { sizeof K_TAB - 1, K_TAB, bufTab }; - linebuffer_t *buffer = initCLI(STDIN_FILENO, STDOUT_FILENO); + linebuffer_t *buffer = initCLI(STDIN_FILENO, STDOUT_FILENO, /*CLI_PROMPT*/ NULL); bindKeyCLI(&key, buffer); @@ -596,7 +778,7 @@ main() ret = readLineCLI(buffer); addHistoryCLI(buffer, NULL); - printf("LINE=%s (%d)/%d CODE=%d\n", buffer->line_buf, buffer->line_len, buffer->line_eol, ret); + printf("LINE=%s (%d)/%d/%d CODE=%d\n", buffer->line_buf, buffer->line_len, buffer->line_eol, buffer->line_bol, ret); freeLineCLI(buffer); resetHistoryCLI(buffer); @@ -605,7 +787,7 @@ main() break; } - saveHistoryCLI(buffer, NULL); + saveHistoryCLI(buffer, NULL, HISTORY_LINES); endCLI(buffer); return 0;