shithub: libmujs

Download patch

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);