aboutsummaryrefslogtreecommitdiff
path: root/lua.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-04 17:11:58 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-04 17:11:58 -0300
commit366c85564874d560b3608349f752e9e490f9002d (patch)
tree77426f1c700cf4c7aa15b0742cf6669c9166af7a /lua.c
parent781219dbe16fc327f5b828e1ff6fa45ec3265cba (diff)
downloadlua-366c85564874d560b3608349f752e9e490f9002d.tar.gz
lua-366c85564874d560b3608349f752e9e490f9002d.tar.bz2
lua-366c85564874d560b3608349f752e9e490f9002d.zip
lua.c loads 'readline' dynamically
(See comments in luaconf.h.) This change allows easier compilation, as Lua compiles and works even if the package 'readline' is absent from the system. Moreover, non-interactive uses don't load the library, making the stand-alone slightly faster for small loads.
Diffstat (limited to 'lua.c')
-rw-r--r--lua.c88
1 files changed, 70 insertions, 18 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... */