ref: b0e3f5e80d3a5868c45c665a6f1ff84b07d49ed2
parent: 22430de3a9bd077deea6d5854751d81ca97fb424
author: Tor Andersson <tor.andersson@artifex.com>
date: Tue May 8 08:52:35 EDT 2018
Add readline support to mujs shell.
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,9 @@
ifeq "$(shell uname)" "Linux"
CFLAGS += -ffunction-sections -fdata-sections
+ CFLAGS += -DHAVE_READLINE
LDFLAGS += -Wl,--gc-sections
+ LIBREADLINE += -lreadline
endif
ifeq "$(build)" "debug"
@@ -78,7 +80,7 @@
$(OUT)/mujs: $(OUT)/libmujs.o $(OUT)/main.o
@ mkdir -p $(dir $@)
- $(CC) $(LDFLAGS) -o $@ $^ -lm
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBREADLINE) -lm
$(OUT)/mujs-pp: $(OUT)/libmujs.o $(OUT)/pp.o
@ mkdir -p $(dir $@)
--- a/main.c
+++ b/main.c
@@ -5,6 +5,32 @@
#include "mujs.h"
+#ifdef HAVE_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#else
+void using_history(void) { }
+void add_history(const char *string) { }
+void rl_bind_key(int key, void (*fun)(void)) { }
+void rl_insert(void) { }
+char *readline(const char *prompt)
+{
+ static char line[500], *p;
+ int n;
+ fputs(prompt, stdout);
+ p = fgets(line, sizeof line, stdin);
+ if (p) {
+ n = strlen(line);
+ if (n > 0 && line[n-1] == '\n')
+ line[--n] = 0;
+ p = malloc(n+1);
+ memcpy(p, line, n+1);
+ return p;
+ }
+ return NULL;
+}
+#endif
+
#define PS1 "> "
static void jsB_gc(js_State *J)
@@ -93,14 +119,13 @@
static void jsB_readline(js_State *J)
{
- char line[256];
- int n;
- if (!fgets(line, sizeof line, stdin))
+ char *line = readline("");
+ if (!line)
js_error(J, "cannot read line from stdin");
- n = strlen(line);
- if (n > 0 && line[n-1] == '\n')
- line[n-1] = 0;
js_pushstring(J, line);
+ if (*line)
+ add_history(line);
+ free(line);
}
static void jsB_quit(js_State *J)
@@ -179,7 +204,7 @@
int
main(int argc, char **argv)
{
- char line[256];
+ char *input;
js_State *J;
int i, status = 0;
@@ -215,14 +240,19 @@
status = 1;
} else {
if (isatty(0)) {
- fputs(PS1, stdout);
- while (fgets(line, sizeof line, stdin)) {
- eval_print(J, line);
- fputs(PS1, stdout);
+ using_history();
+ rl_bind_key('\t', rl_insert);
+ input = readline(PS1);
+ while (input) {
+ eval_print(J, input);
+ if (*input)
+ add_history(input);
+ free(input);
+ input = readline(PS1);
}
putchar('\n');
} else {
- char *input = read_stdin();
+ input = read_stdin();
if (!input || !js_dostring(J, input))
status = 1;
free(input);