File:
[ELWIX - Embedded LightWeight unIX -] /
libaitcli /
example /
t.c
Revision
1.2:
download - view:
text,
annotated -
select for diffs -
revision graph
Wed Mar 16 17:24:03 2011 UTC (13 years, 7 months ago) by
misho
Branches:
MAIN
CVS tags:
cli4_6,
cli4_5,
cli4_4,
cli4_3,
cli4_2,
cli4_1,
cli4_0,
cli3_9,
cli3_8,
cli3_7,
cli3_6,
cli3_5,
cli3_4,
cli3_3,
cli3_2,
cli3_1,
cli3_0,
cli2_3,
cli2_2,
cli2_1,
HEAD,
CLI4_5,
CLI4_4,
CLI4_3,
CLI4_2,
CLI4_1,
CLI4_0,
CLI3_9,
CLI3_8,
CLI3_7,
CLI3_6,
CLI3_5,
CLI3_4,
CLI3_3,
CLI3_2,
CLI3_1,
CLI3_0,
CLI2_3,
CLI2_2,
CLI2_1,
CLI2_0
2.0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <poll.h>
#include <aitio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/queue.h>
#include "keys.h"
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);
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;
int pos;
unsigned char b[BUFSIZ];
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
pos = buf->line_eol - buf->line_bol;
if (buf->line_mode == LINEMODE_INS)
memmove(buf->line_buf + pos + buf->line_keys[idx].key_len, buf->line_buf + pos,
buf->line_len - buf->line_eol);
if (buf->line_mode == LINEMODE_INS || 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(buf->line_buf + pos, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
buf->line_buf[buf->line_len - 1] = 0;
write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
if (buf->line_mode == LINEMODE_INS) {
printfCLI(buf, (const u_char*) buf->line_buf + pos + buf->line_keys[idx].key_len,
buf->line_len - buf->line_eol, 0);
printfEOL(buf, -1, 1);
}
return RETCODE_OK;
}
static int
bufEOL(int idx, void * __restrict buffer)
{
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
printfCR(buffer, 1);
return RETCODE_EOL;
}
static int
bufEOF(int idx, void * __restrict buffer)
{
linebuffer_t *buf = buffer;
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len);
return RETCODE_EOF;
}
static int
bufTab(int idx, void * __restrict buffer)
{
linebuffer_t *buf = buffer;
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
/* show */
write(buf->line_out, "shmink", 6);
return RETCODE_OK;
}
static int
bufUP(int idx, void * __restrict buffer)
{
linebuffer_t *buf = buffer;
int pos;
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
if (!buf->line_h)
buf->line_h = TAILQ_FIRST(&buf->line_history);
else
buf->line_h = TAILQ_NEXT(buf->line_h, hist_next);
if (!buf->line_h)
return RETCODE_OK;
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
bufDOWN(int idx, void * __restrict buffer)
{
linebuffer_t *buf = buffer;
int pos;
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
if (!buf->line_h)
buf->line_h = TAILQ_LAST(&buf->line_history, tqHistoryHead);
else
buf->line_h = TAILQ_PREV(buf->line_h, tqHistoryHead, hist_next);
if (!buf->line_h)
return RETCODE_OK;
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);
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;
if (buf->line_bol < buf->line_eol) {
clrscrEOL(buf);
buf->line_eol--;
buf->line_len--;
memmove(buf->line_buf + buf->line_eol - buf->line_bol,
buf->line_buf + buf->line_eol - buf->line_bol + 1,
buf->line_len - buf->line_eol);
buf->line_buf[buf->line_len - 1] = 0;
printfEOL(buf, buf->line_len - 1, 1);
printfEOL(buf, -1, 1);
}
return RETCODE_OK;
}
static int
bufBTAB(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_len = buf->line_eol - buf->line_bol + 1;
buf->line_buf[buf->line_len - 1] = 0;
printfEOL(buf, -1, 1);
}
return RETCODE_OK;
}
static int
bufMode(int idx, void * __restrict buffer)
{
linebuffer_t *buf = buffer;
if (!buffer || idx < 0 || idx > MAX_BINDKEY)
return RETCODE_ERR;
buf->line_mode = !buf->line_mode ? LINEMODE_OVER : LINEMODE_INS;
return RETCODE_OK;
}
static int
bufBegin(int idx, void * __restrict buffer)
{
linebuffer_t *buf = buffer;
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;
clrscrEOL(buf);
buf->line_len--;
memmove(buf->line_buf + buf->line_eol - buf->line_bol,
buf->line_buf + buf->line_eol - buf->line_bol + 1,
buf->line_len - buf->line_eol);
buf->line_buf[buf->line_len - 1] = 0;
printfEOL(buf, buf->line_len - 1, 1);
printfEOL(buf, -1, 1);
return RETCODE_OK;
}
// ---------------------------------------------------------------
int
bindKeyCLI(bindkey_t * __restrict key, linebuffer_t * __restrict buffer)
{
register int i;
if (!key || !buffer)
return RETCODE_ERR;
for (i = 0; i < MAX_BINDKEY; i++)
if (key->key_len == buffer->line_keys[i].key_len &&
!memcmp(key->key_ch, buffer->line_keys[i].key_ch, key->key_len)) {
buffer->line_keys[i].key_func = key->key_func;
return i;
}
return RETCODE_OK;
}
linebuffer_t *
initCLI(int fin, int fout, const char *prompt)
{
linebuffer_t *buffer;
bindkey_t *keys;
register int i;
struct termios t;
memset(&t, 0, sizeof t);
/* init buffer */
buffer = malloc(sizeof (linebuffer_t));
if (!buffer)
return NULL;
else {
memset(buffer, 0, sizeof(linebuffer_t));
buffer->line_in = fin;
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(BUFSIZ);
if (!buffer->line_buf) {
if (buffer->line_prompt)
free(buffer->line_prompt);
free(buffer);
return NULL;
} else {
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;
} else
memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1));
/* fill key bindings */
// ascii chars & ctrl+chars
for (i = 0; i < 256; i++) {
*keys[i].key_ch = (unsigned char) i;
keys[i].key_len = 1;
if (!i || i == *K_CTRL_D)
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)
keys[i].key_func = catCh2Buf;
}
// alt+chars
for (i = 256; i < 512; i++) {
keys[i].key_ch[0] = 0x1b;
keys[i].key_ch[1] = (unsigned char) i - 256;
keys[i].key_len = 2;
}
// 3 bytes
keys[i].key_len = sizeof K_F1 - 1;
memcpy(keys[i].key_ch, K_F1, keys[i++].key_len);
keys[i].key_len = sizeof K_F2 - 1;
memcpy(keys[i].key_ch, K_F2, keys[i++].key_len);
keys[i].key_len = sizeof K_F3 - 1;
memcpy(keys[i].key_ch, K_F3, keys[i++].key_len);
keys[i].key_len = sizeof K_F4 - 1;
memcpy(keys[i].key_ch, K_F4, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F1 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F1, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F2 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F2, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F3 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F3, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F4 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F4, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F5 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F5, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F6 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F6, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F7 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F7, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F8 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F8, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F9 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F9, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F10 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F10, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F11 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F11, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_SH_F12 - 1;
memcpy(keys[i].key_ch, K_CTRL_SH_F12, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F1 - 1;
memcpy(keys[i].key_ch, K_CTRL_F1, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F2 - 1;
memcpy(keys[i].key_ch, K_CTRL_F2, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F3 - 1;
memcpy(keys[i].key_ch, K_CTRL_F3, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F4 - 1;
memcpy(keys[i].key_ch, K_CTRL_F4, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F5 - 1;
memcpy(keys[i].key_ch, K_CTRL_F5, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F6 - 1;
memcpy(keys[i].key_ch, K_CTRL_F6, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F7 - 1;
memcpy(keys[i].key_ch, K_CTRL_F7, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F8 - 1;
memcpy(keys[i].key_ch, K_CTRL_F8, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F9 - 1;
memcpy(keys[i].key_ch, K_CTRL_F9, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F10 - 1;
memcpy(keys[i].key_ch, K_CTRL_F10, keys[i++].key_len);
keys[i].key_len = sizeof K_CTRL_F11 - 1;
memcpy(keys[i].key_ch, K_CTRL_F11, keys[i++].key_len);
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;
memcpy(keys[i].key_ch, K_UP, keys[i++].key_len);
keys[i].key_len = sizeof K_DOWN - 1;
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 = bufBTAB;
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);
keys[i].key_len = sizeof K_PGDN - 1;
memcpy(keys[i].key_ch, K_PGDN, keys[i++].key_len);
// 5 bytes
keys[i].key_len = sizeof K_F5 - 1;
memcpy(keys[i].key_ch, K_F5, keys[i++].key_len);
keys[i].key_len = sizeof K_F6 - 1;
memcpy(keys[i].key_ch, K_F6, keys[i++].key_len);
keys[i].key_len = sizeof K_F7 - 1;
memcpy(keys[i].key_ch, K_F7, keys[i++].key_len);
keys[i].key_len = sizeof K_F8 - 1;
memcpy(keys[i].key_ch, K_F8, keys[i++].key_len);
keys[i].key_len = sizeof K_F9 - 1;
memcpy(keys[i].key_ch, K_F9, keys[i++].key_len);
keys[i].key_len = sizeof K_F10 - 1;
memcpy(keys[i].key_ch, K_F10, keys[i++].key_len);
keys[i].key_len = sizeof K_F11 - 1;
memcpy(keys[i].key_ch, K_F11, keys[i++].key_len);
keys[i].key_len = sizeof K_F12 - 1;
memcpy(keys[i].key_ch, K_F12, keys[i++].key_len);
tcgetattr(buffer->line_in, &t);
t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOCTL | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT);
t.c_iflag |= IGNBRK;
t.c_cc[VMIN] = 1;
t.c_cc[VTIME] = 0;
tcsetattr(buffer->line_in, TCSANOW, &t);
buffer->line_keys = keys;
return buffer;
}
void
endCLI(linebuffer_t * __restrict buffer)
{
struct tagHistory *h;
if (buffer) {
while ((h = TAILQ_FIRST(&buffer->line_history))) {
TAILQ_REMOVE(&buffer->line_history, h, hist_next);
free(h);
}
if (buffer->line_prompt)
free(buffer->line_prompt);
if (buffer->line_keys)
free(buffer->line_keys);
if (buffer->line_buf)
free(buffer->line_buf);
free(buffer);
buffer = NULL;
}
}
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)
{
int code = RETCODE_ERR;
if (buffer) {
if (buffer->line_buf)
free(buffer->line_buf);
buffer->line_buf = malloc(BUFSIZ);
if (buffer->line_buf) {
memset(buffer->line_buf, 0, BUFSIZ);
buffer->line_eol = buffer->line_bol;
buffer->line_len = 1 + buffer->line_eol;
code = RETCODE_OK;
}
}
return code;
}
int
readLineCLI(linebuffer_t * __restrict buffer)
{
int code, readLen;
register int i;
char buf[BUFSIZ];
struct pollfd fds;
if (!buffer)
return RETCODE_ERR;
memset(&fds, 0, sizeof fds);
fds.fd = buffer->line_in;
fds.events = POLLIN;
printfCR(buffer, 1);
while (42) {
if (poll(&fds, 1, -1) < 1)
return RETCODE_ERR;
memset(buf, 0, sizeof buf);
readLen = read(buffer->line_in, buf, BUFSIZ);
if (readLen == -1)
return RETCODE_ERR;
if (!readLen)
return RETCODE_EOF;
recheck:
// for (i = 0; i < readLen; i++)
// printf("i=%d readLen=%d buf=%x\n", i, readLen, (u_char) buf[i]);
for (code = RETCODE_OK, i = MAX_BINDKEY - 1; i > -1; i--)
if (readLen >= buffer->line_keys[i].key_len &&
!memcmp(buffer->line_keys[i].key_ch, buf, buffer->line_keys[i].key_len)) {
readLen -= buffer->line_keys[i].key_len;
if (readLen)
memmove(buf, buf + buffer->line_keys[i].key_len, readLen);
else
memset(buf, 0, buffer->line_keys[i].key_len);
if (buffer->line_keys[i].key_func)
if ((code = buffer->line_keys[i].key_func(i, buffer)))
readLen = 0;
if (readLen)
goto recheck;
else
break;
}
if (code)
break;
}
return code;
}
int
addHistoryCLI(linebuffer_t * __restrict buffer, const char * __restrict str)
{
struct tagHistory *h;
if (!buffer)
return RETCODE_ERR;
if (!(h = malloc(sizeof(struct tagHistory)))) {
return RETCODE_ERR;
} else
memset(h, 0, sizeof(struct tagHistory));
if (str) {
if (!*str) {
free(h);
return RETCODE_OK;
}
h->hist_len = strlcpy(h->hist_line, str, BUFSIZ);
} else {
if (!*buffer->line_buf || buffer->line_len < 2) {
free(h);
return RETCODE_OK;
}
memcpy(h->hist_line, buffer->line_buf, (h->hist_len = buffer->line_len));
io_TrimStr((unsigned char*) h->hist_line);
h->hist_len = strlen(h->hist_line);
}
TAILQ_INSERT_HEAD(&buffer->line_history, h, hist_next);
return h->hist_len;
}
int
saveHistoryCLI(linebuffer_t * __restrict buffer, const char *histfile, int lines)
{
FILE *f;
mode_t mode;
char szFName[MAXPATHLEN];
struct tagHistory *h;
if (!buffer)
return RETCODE_ERR;
if (!histfile)
strlcpy(szFName, HISTORY_FILE, MAXPATHLEN);
else
strlcpy(szFName, histfile, MAXPATHLEN);
mode = umask(0177);
f = fopen(szFName, "w");
if (!f)
return RETCODE_ERR;
TAILQ_FOREACH(h, &buffer->line_history, hist_next) {
fprintf(f, "%s\n", h->hist_line);
if (lines)
lines--;
else
break;
}
fclose(f);
umask(mode);
return RETCODE_OK;
}
int
loadHistoryCLI(linebuffer_t * __restrict buffer, const char *histfile)
{
FILE *f;
char szFName[MAXPATHLEN], buf[BUFSIZ];
struct tagHistory *h;
if (!buffer)
return RETCODE_ERR;
if (!histfile)
strlcpy(szFName, HISTORY_FILE, MAXPATHLEN);
else
strlcpy(szFName, histfile, MAXPATHLEN);
f = fopen(szFName, "r");
if (!f)
return RETCODE_ERR;
while (fgets(buf, BUFSIZ, f)) {
if (!*buf || *buf == '#')
continue;
else
io_TrimStr((unsigned char*) buf);
if (!(h = malloc(sizeof(struct tagHistory)))) {
fclose(f);
return RETCODE_ERR;
} else
memset(h, 0, sizeof(struct tagHistory));
h->hist_len = strlcpy(h->hist_line, buf, BUFSIZ);
TAILQ_INSERT_TAIL(&buffer->line_history, h, hist_next);
}
fclose(f);
return RETCODE_OK;
}
inline void
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, CLI_PROMPT);
bindKeyCLI(&key, buffer);
loadHistoryCLI(buffer, NULL);
while (42) {
ret = readLineCLI(buffer);
addHistoryCLI(buffer, NULL);
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);
if (ret == RETCODE_EOF)
break;
}
saveHistoryCLI(buffer, NULL, HISTORY_LINES);
endCLI(buffer);
return 0;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>