Annotation of libaitcli/example/t.c, revision 1.1.2.1
1.1.2.1 ! misho 1: #include <stdio.h>
! 2: #include <stdlib.h>
! 3: #include <unistd.h>
! 4: #include <string.h>
! 5: #include <termios.h>
! 6: #include <poll.h>
! 7: #include <aitio.h>
! 8: #include <sys/param.h>
! 9: #include <sys/stat.h>
! 10: #include <sys/queue.h>
! 11: #include "keys.h"
! 12:
! 13:
! 14: int freeLineCLI(linebuffer_t * __restrict buffer);
! 15:
! 16:
! 17: static int
! 18: catCh2Buf(int idx, void * __restrict buffer)
! 19: {
! 20: linebuffer_t *buf = buffer;
! 21: char *ptr;
! 22:
! 23: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 24: return RETCODE_ERR;
! 25:
! 26: ptr = realloc(buf->line_buf, buf->line_len + buf->line_keys[idx].key_len);
! 27: if (!ptr)
! 28: return RETCODE_ERR;
! 29: else
! 30: buf->line_len += buf->line_keys[idx].key_len;
! 31:
! 32: memcpy(ptr + buf->line_eol, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
! 33: ptr[buf->line_len - 1] = 0;
! 34:
! 35: /* show */
! 36: write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
! 37:
! 38: buf->line_eol += buf->line_keys[idx].key_len;
! 39: buf->line_buf = ptr;
! 40: return RETCODE_OK;
! 41: }
! 42:
! 43: static int
! 44: bufEOL(int idx, void * __restrict buffer)
! 45: {
! 46: linebuffer_t *buf = buffer;
! 47:
! 48: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 49: return RETCODE_ERR;
! 50:
! 51: /* show */
! 52: write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
! 53:
! 54: return RETCODE_EOL;
! 55: }
! 56:
! 57: static int
! 58: bufEOF(int idx, void * __restrict buffer)
! 59: {
! 60: linebuffer_t *buf = buffer;
! 61:
! 62: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 63: return RETCODE_ERR;
! 64:
! 65: /* show */
! 66: write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
! 67:
! 68: return RETCODE_EOF;
! 69: }
! 70:
! 71: static int
! 72: bufTab(int idx, void * __restrict buffer)
! 73: {
! 74: linebuffer_t *buf = buffer;
! 75:
! 76: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 77: return RETCODE_ERR;
! 78:
! 79: /* show */
! 80: write(buf->line_out, "shmink", 6);
! 81:
! 82: return RETCODE_OK;
! 83: }
! 84:
! 85: static int
! 86: bufUP(int idx, void * __restrict buffer)
! 87: {
! 88: linebuffer_t *buf = buffer;
! 89: char *ptr;
! 90: register int i;
! 91:
! 92: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 93: return RETCODE_ERR;
! 94:
! 95: if (!buf->line_h)
! 96: buf->line_h = TAILQ_FIRST(&buf->line_history);
! 97: else
! 98: buf->line_h = TAILQ_NEXT(buf->line_h, hist_next);
! 99: if (!buf->line_h)
! 100: return RETCODE_OK;
! 101:
! 102: /* clear line */
! 103: write(buf->line_out, K_CR, 1);
! 104: for (i = 0; i < buf->line_len; i++)
! 105: write(buf->line_out, K_SPACE, 1);
! 106:
! 107: freeLineCLI(buffer);
! 108: ptr = realloc(buf->line_buf, buf->line_len + buf->line_h->hist_len);
! 109: if (!ptr)
! 110: return RETCODE_ERR;
! 111: else
! 112: buf->line_len += buf->line_h->hist_len;
! 113:
! 114: memcpy(ptr + buf->line_eol, buf->line_h->hist_line, buf->line_h->hist_len);
! 115: ptr[buf->line_len - 1] = 0;
! 116:
! 117: buf->line_eol += buf->line_h->hist_len;
! 118: buf->line_buf = ptr;
! 119:
! 120: /* show */
! 121: write(buf->line_out, K_CR, 1);
! 122: write(buf->line_out, buf->line_buf, buf->line_len);
! 123:
! 124: return RETCODE_OK;
! 125: }
! 126:
! 127: static int
! 128: bufDOWN(int idx, void * __restrict buffer)
! 129: {
! 130: linebuffer_t *buf = buffer;
! 131: char *ptr;
! 132: register int i;
! 133:
! 134: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 135: return RETCODE_ERR;
! 136:
! 137: if (!buf->line_h)
! 138: buf->line_h = TAILQ_LAST(&buf->line_history, tqHistoryHead);
! 139: else
! 140: buf->line_h = TAILQ_PREV(buf->line_h, tqHistoryHead, hist_next);
! 141: if (!buf->line_h)
! 142: return RETCODE_OK;
! 143:
! 144: /* clear line */
! 145: write(buf->line_out, K_CR, 1);
! 146: for (i = 0; i < buf->line_len; i++)
! 147: write(buf->line_out, K_SPACE, 1);
! 148:
! 149: freeLineCLI(buffer);
! 150: ptr = realloc(buf->line_buf, buf->line_len + buf->line_h->hist_len);
! 151: if (!ptr)
! 152: return RETCODE_ERR;
! 153: else
! 154: buf->line_len += buf->line_h->hist_len;
! 155:
! 156: memcpy(ptr + buf->line_eol, buf->line_h->hist_line, buf->line_h->hist_len);
! 157: ptr[buf->line_len - 1] = 0;
! 158:
! 159: buf->line_eol += buf->line_h->hist_len;
! 160: buf->line_buf = ptr;
! 161:
! 162: /* show */
! 163: write(buf->line_out, K_CR, 1);
! 164: write(buf->line_out, buf->line_buf, buf->line_len);
! 165:
! 166: return RETCODE_OK;
! 167: }
! 168:
! 169: static int
! 170: bufClr(int idx, void * __restrict buffer)
! 171: {
! 172: linebuffer_t *buf = buffer;
! 173: register int i;
! 174:
! 175: if (!buffer || idx < 0 || idx > MAX_BINDKEY)
! 176: return RETCODE_ERR;
! 177:
! 178: /* clear line */
! 179: write(buf->line_out, K_CR, 1);
! 180: for (i = 0; i < buf->line_len; i++)
! 181: write(buf->line_out, K_SPACE, 1);
! 182:
! 183: freeLineCLI(buffer);
! 184:
! 185: write(buf->line_out, K_CR, 1);
! 186: return RETCODE_OK;
! 187: }
! 188:
! 189: // ---------------------------------------------------------------
! 190:
! 191: int
! 192: bindKeyCLI(bindkey_t * __restrict key, linebuffer_t * __restrict buffer)
! 193: {
! 194: register int i;
! 195:
! 196: if (!key || !buffer)
! 197: return RETCODE_ERR;
! 198:
! 199: for (i = 0; i < MAX_BINDKEY; i++)
! 200: if (key->key_len == buffer->line_keys[i].key_len &&
! 201: !memcmp(key->key_ch, buffer->line_keys[i].key_ch, key->key_len)) {
! 202: buffer->line_keys[i].key_func = key->key_func;
! 203: return i;
! 204: }
! 205: return RETCODE_OK;
! 206: }
! 207:
! 208: linebuffer_t *
! 209: initCLI(int fin, int fout)
! 210: {
! 211: linebuffer_t *buffer;
! 212: bindkey_t *keys;
! 213: register int i;
! 214: struct termios t;
! 215:
! 216: memset(&t, 0, sizeof t);
! 217: /* init buffer */
! 218: buffer = malloc(sizeof (linebuffer_t));
! 219: if (!buffer)
! 220: return NULL;
! 221: else {
! 222: memset(buffer, 0, sizeof(linebuffer_t));
! 223:
! 224: buffer->line_in = fin;
! 225: buffer->line_out = fout;
! 226:
! 227: TAILQ_INIT(&buffer->line_history);
! 228: }
! 229: buffer->line_buf = malloc(1);
! 230: if (!buffer->line_buf) {
! 231: free(buffer);
! 232: return NULL;
! 233: } else {
! 234: *buffer->line_buf = 0;
! 235: buffer->line_len = 1;
! 236: }
! 237: keys = calloc(MAX_BINDKEY + 1, sizeof(bindkey_t));
! 238: if (!keys) {
! 239: free(buffer->line_buf);
! 240: free(buffer);
! 241: return NULL;
! 242: } else
! 243: memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1));
! 244:
! 245: /* fill key bindings */
! 246: // ascii chars & ctrl+chars
! 247: for (i = 0; i < 256; i++) {
! 248: *keys[i].key_ch = (unsigned char) i;
! 249: keys[i].key_len = 1;
! 250:
! 251: if (!i || i == *K_CTRL_D)
! 252: keys[i].key_func = bufEOF;
! 253: if (i == *K_CTRL_M || i == *K_CTRL_J)
! 254: keys[i].key_func = bufEOL;
! 255: if (i == *K_CTRL_C)
! 256: keys[i].key_func = bufClr;
! 257: if (i >= *K_SPACE && i < *K_BACKSPACE)
! 258: keys[i].key_func = catCh2Buf;
! 259: if (i > *K_BACKSPACE && i < 0xff)
! 260: keys[i].key_func = catCh2Buf;
! 261: }
! 262: // alt+chars
! 263: for (i = 256; i < 512; i++) {
! 264: keys[i].key_ch[0] = 0x1b;
! 265: keys[i].key_ch[1] = (unsigned char) i - 256;
! 266: keys[i].key_len = 2;
! 267: }
! 268:
! 269: // 3 bytes
! 270: keys[i].key_len = sizeof K_F1 - 1;
! 271: memcpy(keys[i].key_ch, K_F1, keys[i++].key_len);
! 272: keys[i].key_len = sizeof K_F2 - 1;
! 273: memcpy(keys[i].key_ch, K_F2, keys[i++].key_len);
! 274: keys[i].key_len = sizeof K_F3 - 1;
! 275: memcpy(keys[i].key_ch, K_F3, keys[i++].key_len);
! 276: keys[i].key_len = sizeof K_F4 - 1;
! 277: memcpy(keys[i].key_ch, K_F4, keys[i++].key_len);
! 278: keys[i].key_len = sizeof K_CTRL_SH_F1 - 1;
! 279: memcpy(keys[i].key_ch, K_CTRL_SH_F1, keys[i++].key_len);
! 280: keys[i].key_len = sizeof K_CTRL_SH_F2 - 1;
! 281: memcpy(keys[i].key_ch, K_CTRL_SH_F2, keys[i++].key_len);
! 282: keys[i].key_len = sizeof K_CTRL_SH_F3 - 1;
! 283: memcpy(keys[i].key_ch, K_CTRL_SH_F3, keys[i++].key_len);
! 284: keys[i].key_len = sizeof K_CTRL_SH_F4 - 1;
! 285: memcpy(keys[i].key_ch, K_CTRL_SH_F4, keys[i++].key_len);
! 286: keys[i].key_len = sizeof K_CTRL_SH_F5 - 1;
! 287: memcpy(keys[i].key_ch, K_CTRL_SH_F5, keys[i++].key_len);
! 288: keys[i].key_len = sizeof K_CTRL_SH_F6 - 1;
! 289: memcpy(keys[i].key_ch, K_CTRL_SH_F6, keys[i++].key_len);
! 290: keys[i].key_len = sizeof K_CTRL_SH_F7 - 1;
! 291: memcpy(keys[i].key_ch, K_CTRL_SH_F7, keys[i++].key_len);
! 292: keys[i].key_len = sizeof K_CTRL_SH_F8 - 1;
! 293: memcpy(keys[i].key_ch, K_CTRL_SH_F8, keys[i++].key_len);
! 294: keys[i].key_len = sizeof K_CTRL_SH_F9 - 1;
! 295: memcpy(keys[i].key_ch, K_CTRL_SH_F9, keys[i++].key_len);
! 296: keys[i].key_len = sizeof K_CTRL_SH_F10 - 1;
! 297: memcpy(keys[i].key_ch, K_CTRL_SH_F10, keys[i++].key_len);
! 298: keys[i].key_len = sizeof K_CTRL_SH_F11 - 1;
! 299: memcpy(keys[i].key_ch, K_CTRL_SH_F11, keys[i++].key_len);
! 300: keys[i].key_len = sizeof K_CTRL_SH_F12 - 1;
! 301: memcpy(keys[i].key_ch, K_CTRL_SH_F12, keys[i++].key_len);
! 302: keys[i].key_len = sizeof K_CTRL_F1 - 1;
! 303: memcpy(keys[i].key_ch, K_CTRL_F1, keys[i++].key_len);
! 304: keys[i].key_len = sizeof K_CTRL_F2 - 1;
! 305: memcpy(keys[i].key_ch, K_CTRL_F2, keys[i++].key_len);
! 306: keys[i].key_len = sizeof K_CTRL_F3 - 1;
! 307: memcpy(keys[i].key_ch, K_CTRL_F3, keys[i++].key_len);
! 308: keys[i].key_len = sizeof K_CTRL_F4 - 1;
! 309: memcpy(keys[i].key_ch, K_CTRL_F4, keys[i++].key_len);
! 310: keys[i].key_len = sizeof K_CTRL_F5 - 1;
! 311: memcpy(keys[i].key_ch, K_CTRL_F5, keys[i++].key_len);
! 312: keys[i].key_len = sizeof K_CTRL_F6 - 1;
! 313: memcpy(keys[i].key_ch, K_CTRL_F6, keys[i++].key_len);
! 314: keys[i].key_len = sizeof K_CTRL_F7 - 1;
! 315: memcpy(keys[i].key_ch, K_CTRL_F7, keys[i++].key_len);
! 316: keys[i].key_len = sizeof K_CTRL_F8 - 1;
! 317: memcpy(keys[i].key_ch, K_CTRL_F8, keys[i++].key_len);
! 318: keys[i].key_len = sizeof K_CTRL_F9 - 1;
! 319: memcpy(keys[i].key_ch, K_CTRL_F9, keys[i++].key_len);
! 320: keys[i].key_len = sizeof K_CTRL_F10 - 1;
! 321: memcpy(keys[i].key_ch, K_CTRL_F10, keys[i++].key_len);
! 322: keys[i].key_len = sizeof K_CTRL_F11 - 1;
! 323: memcpy(keys[i].key_ch, K_CTRL_F11, keys[i++].key_len);
! 324: keys[i].key_len = sizeof K_CTRL_F12 - 1;
! 325: memcpy(keys[i].key_ch, K_CTRL_F12, keys[i++].key_len);
! 326: keys[i].key_len = sizeof K_HOME - 1;
! 327: memcpy(keys[i].key_ch, K_HOME, keys[i++].key_len);
! 328: keys[i].key_len = sizeof K_END - 1;
! 329: memcpy(keys[i].key_ch, K_END, keys[i++].key_len);
! 330: keys[i].key_len = sizeof K_UP - 1;
! 331: keys[i].key_func = bufUP;
! 332: memcpy(keys[i].key_ch, K_UP, keys[i++].key_len);
! 333: keys[i].key_len = sizeof K_DOWN - 1;
! 334: keys[i].key_func = bufDOWN;
! 335: memcpy(keys[i].key_ch, K_DOWN, keys[i++].key_len);
! 336: keys[i].key_len = sizeof K_RIGHT - 1;
! 337: memcpy(keys[i].key_ch, K_RIGHT, keys[i++].key_len);
! 338: keys[i].key_len = sizeof K_LEFT - 1;
! 339: memcpy(keys[i].key_ch, K_LEFT, keys[i++].key_len);
! 340: keys[i].key_len = sizeof K_BTAB - 1;
! 341: memcpy(keys[i].key_ch, K_BTAB, keys[i++].key_len);
! 342: // 4 bytes
! 343: keys[i].key_len = sizeof K_INS - 1;
! 344: memcpy(keys[i].key_ch, K_INS, keys[i++].key_len);
! 345: keys[i].key_len = sizeof K_DEL - 1;
! 346: memcpy(keys[i].key_ch, K_DEL, keys[i++].key_len);
! 347: keys[i].key_len = sizeof K_PGUP - 1;
! 348: memcpy(keys[i].key_ch, K_PGUP, keys[i++].key_len);
! 349: keys[i].key_len = sizeof K_PGDN - 1;
! 350: memcpy(keys[i].key_ch, K_PGDN, keys[i++].key_len);
! 351: // 5 bytes
! 352: keys[i].key_len = sizeof K_F5 - 1;
! 353: memcpy(keys[i].key_ch, K_F5, keys[i++].key_len);
! 354: keys[i].key_len = sizeof K_F6 - 1;
! 355: memcpy(keys[i].key_ch, K_F6, keys[i++].key_len);
! 356: keys[i].key_len = sizeof K_F7 - 1;
! 357: memcpy(keys[i].key_ch, K_F7, keys[i++].key_len);
! 358: keys[i].key_len = sizeof K_F8 - 1;
! 359: memcpy(keys[i].key_ch, K_F8, keys[i++].key_len);
! 360: keys[i].key_len = sizeof K_F9 - 1;
! 361: memcpy(keys[i].key_ch, K_F9, keys[i++].key_len);
! 362: keys[i].key_len = sizeof K_F10 - 1;
! 363: memcpy(keys[i].key_ch, K_F10, keys[i++].key_len);
! 364: keys[i].key_len = sizeof K_F11 - 1;
! 365: memcpy(keys[i].key_ch, K_F11, keys[i++].key_len);
! 366: keys[i].key_len = sizeof K_F12 - 1;
! 367: memcpy(keys[i].key_ch, K_F12, keys[i++].key_len);
! 368:
! 369: tcgetattr(buffer->line_in, &t);
! 370: t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOCTL | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT);
! 371: t.c_iflag |= IGNBRK;
! 372: t.c_cc[VMIN] = 1;
! 373: t.c_cc[VTIME] = 0;
! 374: tcsetattr(buffer->line_in, TCSANOW, &t);
! 375:
! 376: buffer->line_keys = keys;
! 377: return buffer;
! 378: }
! 379:
! 380: void
! 381: endCLI(linebuffer_t * __restrict buffer)
! 382: {
! 383: struct tagHistory *h;
! 384:
! 385: if (buffer) {
! 386: while ((h = TAILQ_FIRST(&buffer->line_history))) {
! 387: TAILQ_REMOVE(&buffer->line_history, h, hist_next);
! 388: free(h);
! 389: }
! 390:
! 391: if (buffer->line_keys)
! 392: free(buffer->line_keys);
! 393: if (buffer->line_buf)
! 394: free(buffer->line_buf);
! 395:
! 396: free(buffer);
! 397: buffer = NULL;
! 398: }
! 399: }
! 400:
! 401: int
! 402: freeLineCLI(linebuffer_t * __restrict buffer)
! 403: {
! 404: int code = RETCODE_ERR;
! 405:
! 406: if (buffer) {
! 407: if (buffer->line_buf)
! 408: free(buffer->line_buf);
! 409:
! 410: buffer->line_buf = malloc(1);
! 411: if (buffer->line_buf) {
! 412: *buffer->line_buf = 0;
! 413: buffer->line_eol = 0;
! 414: buffer->line_len = 1;
! 415:
! 416: code = RETCODE_OK;
! 417: }
! 418: }
! 419:
! 420: return code;
! 421: }
! 422:
! 423: int
! 424: readLineCLI(linebuffer_t * __restrict buffer)
! 425: {
! 426: int code, readLen;
! 427: register int i;
! 428: char buf[BUFSIZ];
! 429: struct pollfd fds;
! 430:
! 431: if (!buffer)
! 432: return RETCODE_ERR;
! 433:
! 434: memset(&fds, 0, sizeof fds);
! 435: fds.fd = buffer->line_in;
! 436: fds.events = POLLIN;
! 437:
! 438: while (42) {
! 439: if (poll(&fds, 1, -1) < 1)
! 440: return RETCODE_ERR;
! 441:
! 442: memset(buf, 0, sizeof buf);
! 443: readLen = read(buffer->line_in, buf, BUFSIZ);
! 444: if (readLen == -1)
! 445: return RETCODE_ERR;
! 446: if (!readLen)
! 447: return RETCODE_EOF;
! 448:
! 449: recheck:
! 450: // for (i = 0; i < readLen; i++)
! 451: // printf("i=%d readLen=%d buf=%x\n", i, readLen, (u_char) buf[i]);
! 452: for (code = RETCODE_OK, i = MAX_BINDKEY - 1; i > -1; i--)
! 453: if (readLen >= buffer->line_keys[i].key_len &&
! 454: !memcmp(buffer->line_keys[i].key_ch, buf, buffer->line_keys[i].key_len)) {
! 455: readLen -= buffer->line_keys[i].key_len;
! 456: if (readLen)
! 457: memmove(buf, buf + buffer->line_keys[i].key_len, readLen);
! 458: else
! 459: memset(buf, 0, buffer->line_keys[i].key_len);
! 460:
! 461: if (buffer->line_keys[i].key_func)
! 462: if ((code = buffer->line_keys[i].key_func(i, buffer)))
! 463: readLen = 0;
! 464:
! 465: if (readLen)
! 466: goto recheck;
! 467: else
! 468: break;
! 469: }
! 470:
! 471: if (code)
! 472: break;
! 473: }
! 474:
! 475: return code;
! 476: }
! 477:
! 478: int
! 479: addHistoryCLI(linebuffer_t * __restrict buffer, const char * __restrict str)
! 480: {
! 481: struct tagHistory *h;
! 482:
! 483: if (!buffer)
! 484: return RETCODE_ERR;
! 485:
! 486: if (!(h = malloc(sizeof(struct tagHistory)))) {
! 487: return RETCODE_ERR;
! 488: } else
! 489: memset(h, 0, sizeof(struct tagHistory));
! 490:
! 491: if (str) {
! 492: if (!*str) {
! 493: free(h);
! 494: return RETCODE_OK;
! 495: }
! 496:
! 497: h->hist_len = strlcpy(h->hist_line, str, BUFSIZ);
! 498: } else {
! 499: if (!*buffer->line_buf || buffer->line_len < 2) {
! 500: free(h);
! 501: return RETCODE_OK;
! 502: }
! 503:
! 504: memcpy(h->hist_line, buffer->line_buf, (h->hist_len = buffer->line_len));
! 505: io_TrimStr((unsigned char*) h->hist_line);
! 506: h->hist_len = strlen(h->hist_line);
! 507: }
! 508:
! 509: TAILQ_INSERT_HEAD(&buffer->line_history, h, hist_next);
! 510: return h->hist_len;
! 511: }
! 512:
! 513: int
! 514: saveHistoryCLI(linebuffer_t * __restrict buffer, const char *histfile)
! 515: {
! 516: FILE *f;
! 517: mode_t mode;
! 518: char szFName[MAXPATHLEN];
! 519: struct tagHistory *h;
! 520:
! 521: if (!buffer)
! 522: return RETCODE_ERR;
! 523: if (!histfile)
! 524: strlcpy(szFName, HISTORY_FILE, MAXPATHLEN);
! 525: else
! 526: strlcpy(szFName, histfile, MAXPATHLEN);
! 527:
! 528: mode = umask(0177);
! 529: f = fopen(szFName, "w");
! 530: if (!f)
! 531: return RETCODE_ERR;
! 532: TAILQ_FOREACH(h, &buffer->line_history, hist_next)
! 533: fprintf(f, "%s\n", h->hist_line);
! 534: fclose(f);
! 535: umask(mode);
! 536:
! 537: return RETCODE_OK;
! 538: }
! 539:
! 540: int
! 541: loadHistoryCLI(linebuffer_t * __restrict buffer, const char *histfile)
! 542: {
! 543: FILE *f;
! 544: char szFName[MAXPATHLEN], buf[BUFSIZ];
! 545: struct tagHistory *h;
! 546:
! 547: if (!buffer)
! 548: return RETCODE_ERR;
! 549: if (!histfile)
! 550: strlcpy(szFName, HISTORY_FILE, MAXPATHLEN);
! 551: else
! 552: strlcpy(szFName, histfile, MAXPATHLEN);
! 553:
! 554: f = fopen(szFName, "r");
! 555: if (!f)
! 556: return RETCODE_ERR;
! 557: while (fgets(buf, BUFSIZ, f)) {
! 558: if (!*buf || *buf == '#')
! 559: continue;
! 560: else
! 561: io_TrimStr((unsigned char*) buf);
! 562:
! 563: if (!(h = malloc(sizeof(struct tagHistory)))) {
! 564: fclose(f);
! 565: return RETCODE_ERR;
! 566: } else
! 567: memset(h, 0, sizeof(struct tagHistory));
! 568:
! 569: h->hist_len = strlcpy(h->hist_line, buf, BUFSIZ);
! 570: TAILQ_INSERT_TAIL(&buffer->line_history, h, hist_next);
! 571: }
! 572: fclose(f);
! 573:
! 574: return RETCODE_OK;
! 575: }
! 576:
! 577: inline void
! 578: resetHistoryCLI(linebuffer_t * __restrict buffer)
! 579: {
! 580: buffer->line_h = NULL;
! 581: }
! 582:
! 583:
! 584: int
! 585: main()
! 586: {
! 587: int ret;
! 588: bindkey_t key = { sizeof K_TAB - 1, K_TAB, bufTab };
! 589: linebuffer_t *buffer = initCLI(STDIN_FILENO, STDOUT_FILENO);
! 590:
! 591: bindKeyCLI(&key, buffer);
! 592:
! 593: loadHistoryCLI(buffer, NULL);
! 594:
! 595: while (42) {
! 596: ret = readLineCLI(buffer);
! 597: addHistoryCLI(buffer, NULL);
! 598:
! 599: printf("LINE=%s (%d)/%d CODE=%d\n", buffer->line_buf, buffer->line_len, buffer->line_eol, ret);
! 600:
! 601: freeLineCLI(buffer);
! 602: resetHistoryCLI(buffer);
! 603:
! 604: if (ret == RETCODE_EOF)
! 605: break;
! 606: }
! 607:
! 608: saveHistoryCLI(buffer, NULL);
! 609:
! 610: endCLI(buffer);
! 611: return 0;
! 612: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>