aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lua.c88
-rw-r--r--luaconf.h11
-rw-r--r--makefile4
-rw-r--r--testes/main.lua16
4 files changed, 90 insertions, 29 deletions
diff --git a/lua.c b/lua.c
index 88fb8793..51979a8b 100644
--- a/lua.c
+++ b/lua.c
@@ -437,27 +437,80 @@ static int handle_luainit (lua_State *L) {
437** lua_saveline defines how to "save" a read line in a "history". 437** lua_saveline defines how to "save" a read line in a "history".
438** lua_freeline defines how to free a line read by lua_readline. 438** lua_freeline defines how to free a line read by lua_readline.
439*/ 439*/
440#if !defined(lua_readline) /* { */
441 440
442#if defined(LUA_USE_READLINE) /* { */ 441#if defined(LUA_USE_READLINE)
443 442
444#include <readline/readline.h> 443#include <readline/readline.h>
445#include <readline/history.h> 444#include <readline/history.h>
446#define lua_initreadline(L) ((void)L, rl_readline_name="lua") 445#define lua_initreadline(L) ((void)L, rl_readline_name="lua")
447#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) 446#define lua_readline(b,p) ((void)b, readline(p))
448#define lua_saveline(L,line) ((void)L, add_history(line)) 447#define lua_saveline(line) add_history(line)
449#define lua_freeline(L,b) ((void)L, free(b)) 448#define lua_freeline(b) free(b)
449
450#endif
451
452
453#if !defined(lua_readline) /* { */
454
455/* pointer to dynamically loaded 'readline' function (if any) */
456typedef char *(*l_readline_t) (const char *prompt);
457static l_readline_t l_readline = NULL;
458
459static char *lua_readline (char *buff, const char *prompt) {
460 if (l_readline != NULL) /* is there a dynamic 'readline'? */
461 return (*l_readline)(prompt); /* use it */
462 else { /* emulate 'readline' over 'buff' */
463 fputs(prompt, stdout);
464 fflush(stdout); /* show prompt */
465 return fgets(buff, LUA_MAXINPUT, stdin); /* read line */
466 }
467}
468
469
470/* pointer to dynamically loaded 'add_history' function (if any) */
471typedef void (*l_addhist_t) (const char *string);
472static l_addhist_t l_addhist = NULL;
473
474static void lua_saveline (const char *line) {
475 if (l_addhist != NULL) /* is there a dynamic 'add_history'? */
476 (*l_addhist)(line); /* use it */
477 /* else nothing to be done */
478}
450 479
451#else /* }{ */ 480
481static void lua_freeline (char *line) {
482 if (l_readline != NULL) /* is there a dynamic 'readline'? */
483 free(line); /* free line created by it */
484 /* else 'lua_readline' used an automatic buffer; nothing to free */
485}
486
487
488#if !defined(LUA_USE_DLOPEN) || !defined(LUA_READLINELIB)
452 489
453#define lua_initreadline(L) ((void)L) 490#define lua_initreadline(L) ((void)L)
454#define lua_readline(L,b,p) \
455 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
456 fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
457#define lua_saveline(L,line) { (void)L; (void)line; }
458#define lua_freeline(L,b) { (void)L; (void)b; }
459 491
460#endif /* } */ 492#else /* { */
493
494#include <dlfcn.h>
495
496
497static void lua_initreadline (lua_State *L) {
498 void *lib = dlopen(LUA_READLINELIB, RTLD_NOW | RTLD_LOCAL);
499 if (lib == NULL)
500 lua_warning(L, "library '" LUA_READLINELIB "'not found", 0);
501 else {
502 const char **name = cast(const char**, dlsym(lib, "rl_readline_name"));
503 if (name != NULL)
504 *name = "Lua";
505 l_readline = cast(l_readline_t, cast_func(dlsym(lib, "readline")));
506 if (l_readline == NULL)
507 lua_warning(L, "unable to load 'readline'", 0);
508 else
509 l_addhist = cast(l_addhist_t, cast_func(dlsym(lib, "add_history")));
510 }
511}
512
513#endif /* } */
461 514
462#endif /* } */ 515#endif /* } */
463 516
@@ -505,11 +558,10 @@ static int incomplete (lua_State *L, int status) {
505*/ 558*/
506static int pushline (lua_State *L, int firstline) { 559static int pushline (lua_State *L, int firstline) {
507 char buffer[LUA_MAXINPUT]; 560 char buffer[LUA_MAXINPUT];
508 char *b = buffer;
509 size_t l; 561 size_t l;
510 const char *prmt = get_prompt(L, firstline); 562 const char *prmt = get_prompt(L, firstline);
511 int readstatus = lua_readline(L, b, prmt); 563 char *b = lua_readline(buffer, prmt);
512 if (readstatus == 0) 564 if (b == NULL)
513 return 0; /* no input (prompt will be popped by caller) */ 565 return 0; /* no input (prompt will be popped by caller) */
514 lua_pop(L, 1); /* remove prompt */ 566 lua_pop(L, 1); /* remove prompt */
515 l = strlen(b); 567 l = strlen(b);
@@ -519,7 +571,7 @@ static int pushline (lua_State *L, int firstline) {
519 lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */ 571 lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
520 else 572 else
521 lua_pushlstring(L, b, l); 573 lua_pushlstring(L, b, l);
522 lua_freeline(L, b); 574 lua_freeline(b);
523 return 1; 575 return 1;
524} 576}
525 577
@@ -535,7 +587,7 @@ static int addreturn (lua_State *L) {
535 if (status == LUA_OK) { 587 if (status == LUA_OK) {
536 lua_remove(L, -2); /* remove modified line */ 588 lua_remove(L, -2); /* remove modified line */
537 if (line[0] != '\0') /* non empty? */ 589 if (line[0] != '\0') /* non empty? */
538 lua_saveline(L, line); /* keep history */ 590 lua_saveline(line); /* keep history */
539 } 591 }
540 else 592 else
541 lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */ 593 lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */
@@ -552,7 +604,7 @@ static int multiline (lua_State *L) {
552 const char *line = lua_tolstring(L, 1, &len); /* get what it has */ 604 const char *line = lua_tolstring(L, 1, &len); /* get what it has */
553 int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ 605 int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
554 if (!incomplete(L, status) || !pushline(L, 0)) { 606 if (!incomplete(L, status) || !pushline(L, 0)) {
555 lua_saveline(L, line); /* keep history */ 607 lua_saveline(line); /* keep history */
556 return status; /* cannot or should not try to add continuation line */ 608 return status; /* cannot or should not try to add continuation line */
557 } 609 }
558 lua_pushliteral(L, "\n"); /* add newline... */ 610 lua_pushliteral(L, "\n"); /* add newline... */
diff --git a/luaconf.h b/luaconf.h
index fe98d9a9..65715c8b 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -58,15 +58,26 @@
58#endif 58#endif
59 59
60 60
61/*
62** When Posix DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone
63** application will try to dynamically link a 'readline' facility
64** for its REPL. In that case, LUA_READLINELIB is the name of the
65** library it will look for those facilities. If lua.c cannot open
66** the specified library, it will generate a warning and then run
67** without 'readline'. If that macro is not defined, lua.c will not
68** use 'readline'.
69*/
61#if defined(LUA_USE_LINUX) 70#if defined(LUA_USE_LINUX)
62#define LUA_USE_POSIX 71#define LUA_USE_POSIX
63#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ 72#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
73#define LUA_READLINELIB "libreadline.so"
64#endif 74#endif
65 75
66 76
67#if defined(LUA_USE_MACOSX) 77#if defined(LUA_USE_MACOSX)
68#define LUA_USE_POSIX 78#define LUA_USE_POSIX
69#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ 79#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
80#define LUA_READLINELIB "libedit.dylib"
70#endif 81#endif
71 82
72 83
diff --git a/makefile b/makefile
index 74801eef..58b12f8e 100644
--- a/makefile
+++ b/makefile
@@ -70,9 +70,9 @@ LOCAL = $(TESTS) $(CWARNS)
70 70
71 71
72# enable Linux goodies 72# enable Linux goodies
73MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX -DLUA_USE_READLINE 73MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX
74MYLDFLAGS= $(LOCAL) -Wl,-E 74MYLDFLAGS= $(LOCAL) -Wl,-E
75MYLIBS= -ldl -lreadline 75MYLIBS= -ldl
76 76
77 77
78CC= gcc 78CC= gcc
diff --git a/testes/main.lua b/testes/main.lua
index 5c7d0a10..9a86fb5a 100644
--- a/testes/main.lua
+++ b/testes/main.lua
@@ -368,20 +368,18 @@ assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt))
368 368
369 369
370-- non-string prompt 370-- non-string prompt
371prompt = 371prompt = [[
372 "local C = 0;\z 372 local C = 'X';
373 _PROMPT=setmetatable({},{__tostring = function () \z 373 _PROMPT=setmetatable({},{__tostring = function ()
374 C = C + 1; return C end})" 374 C = C .. 'X'; return C end})
375]]
375prepfile[[ -- 376prepfile[[ --
376a = 2 377a = 2
377]] 378]]
378RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out) 379RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out)
379local t = getoutput() 380local t = getoutput()
380assert(string.find(t, [[ 381-- skip version line and then check the presence of the three prompts
3811 -- 382assert(string.find(t, "^.-\nXX[^\nX]*\n?XXX[^\nX]*\n?XXXX\n?$"))
3822a = 2
3833
384]], 1, true))
385 383
386 384
387-- test for error objects 385-- test for error objects