From 2c54c88c462b31a0f30e162899a5801d0ce967b9 Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 22 Mar 2010 17:24:28 +0100 Subject: [PATCH] API converted to be readline alike. Ctrl-d behavior fixed. --- example.c | 15 ++++++--------- linenoise.c | 21 +++++++++++++++++---- linenoise.h | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/example.c b/example.c index 960e8c5..22e5188 100644 --- a/example.c +++ b/example.c @@ -3,17 +3,14 @@ #include "linenoise.h" int main(void) { - char buf[1024]; - int retval; + char *line; - while(1) { - retval = linenoise(buf,1024,"hello> "); - if (retval > 0) { - printf("echo: '%s'\n", buf); - linenoiseHistoryAdd(buf); - } else if (retval == -1) { - exit(1); + while((line = linenoise("hello> ")) != NULL) { + if (line[0] != '\0') { + printf("echo: '%s'\n", line); + linenoiseHistoryAdd(line); } + free(line); } return 0; } diff --git a/linenoise.c b/linenoise.c index 2b3e5ef..bcef68e 100644 --- a/linenoise.c +++ b/linenoise.c @@ -80,6 +80,8 @@ #include #include +#define LINENOISE_MAX_LINE 4096 + static struct termios orig_termios; /* in order to restore at exit */ static int rawmode = 0; /* for atexit() function to check if restore is needed*/ static int atexit_registered = 0; /* register atexit just 1 time */ @@ -154,7 +156,7 @@ static int getColumns(void) { return ws.ws_col; } -static void refreshLine(int fd, char *prompt, char *buf, size_t len, size_t pos, size_t cols) { +static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_t pos, size_t cols) { char seq[64]; size_t plen = strlen(prompt); @@ -181,7 +183,7 @@ static void refreshLine(int fd, char *prompt, char *buf, size_t len, size_t pos, if (write(fd,seq,strlen(seq)) == -1) return; } -static int linenoisePrompt(int fd, char *buf, size_t buflen, char *prompt) { +static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) { size_t plen = strlen(prompt); size_t pos = 0; size_t len = 0; @@ -205,9 +207,11 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, char *prompt) { if (nread <= 0) return len; switch(c) { case 13: /* enter */ - case 4: /* ctrl+d */ history_len--; return len; + case 4: /* ctrl+d */ + history_len--; + return (len == 0) ? -1 : (int)len; case 3: /* ctrl+c */ errno = EAGAIN; return -1; @@ -302,7 +306,7 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, char *prompt) { return len; } -int linenoise(char *buf, size_t buflen, char *prompt) { +static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) { int fd = STDIN_FILENO; int count; @@ -317,6 +321,15 @@ int linenoise(char *buf, size_t buflen, char *prompt) { return count; } +char *linenoise(const char *prompt) { + char buf[LINENOISE_MAX_LINE]; + int count; + + count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt); + if (count == -1) return NULL; + return strdup(buf); +} + /* Using a circular buffer is smarter, but a bit more complex to handle. */ int linenoiseHistoryAdd(char *line) { if (history_max_len == 0) return 0; diff --git a/linenoise.h b/linenoise.h index 6483655..ff45e2c 100644 --- a/linenoise.h +++ b/linenoise.h @@ -34,7 +34,7 @@ #ifndef __LINENOISE_H #define __LINENOISE_H -int linenoise(char *buf, size_t buflen, char *prompt); +char *linenoise(const char *prompt); int linenoiseHistoryAdd(char *line); int linenoiseHistorySetMaxLen(int len);