API converted to be readline alike. Ctrl-d behavior fixed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
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 <sys/ioctl.h>
#include <unistd.h>
+#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);