@@ -437,27 +437,80 @@ static int handle_luainit (lua_State *L) {
437437** lua_saveline defines how to "save" a read line in a "history".
438438** lua_freeline defines how to free a line read by lua_readline.
439439*/
440- #if !defined(lua_readline ) /* { */
441440
442- #if defined(LUA_USE_READLINE ) /* { */
441+ #if defined(LUA_USE_READLINE )
443442
444443#include <readline/readline.h>
445444#include <readline/history.h>
446445#define lua_initreadline (L ) ((void)L, rl_readline_name="lua")
447- #define lua_readline (L ,b ,p ) ((void)L, ((b)=readline(p)) != NULL)
448- #define lua_saveline (L ,line ) ((void)L, add_history(line))
449- #define lua_freeline (L ,b ) ((void)L, free(b))
446+ #define lua_readline (b ,p ) ((void)b, readline(p))
447+ #define lua_saveline (line ) add_history(line)
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) */
456+ typedef char * (* l_readline_t ) (const char * prompt );
457+ static l_readline_t l_readline = NULL ;
458+
459+ static 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) */
471+ typedef void (* l_addhist_t ) (const char * string );
472+ static l_addhist_t l_addhist = NULL ;
473+
474+ static 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+ }
450479
451- #else /* }{ */
480+
481+ static 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 )
452489
453490#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; }
459491
460- #endif /* } */
492+ #else /* { */
493+
494+ #include <dlfcn.h>
495+
496+
497+ static 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 /* } */
461514
462515#endif /* } */
463516
@@ -505,11 +558,10 @@ static int incomplete (lua_State *L, int status) {
505558*/
506559static int pushline (lua_State * L , int firstline ) {
507560 char buffer [LUA_MAXINPUT ];
508- char * b = buffer ;
509561 size_t l ;
510562 const char * prmt = get_prompt (L , firstline );
511- int readstatus = lua_readline (L , b , prmt );
512- if (readstatus == 0 )
563+ char * b = lua_readline (buffer , prmt );
564+ if (b == NULL )
513565 return 0 ; /* no input (prompt will be popped by caller) */
514566 lua_pop (L , 1 ); /* remove prompt */
515567 l = strlen (b );
@@ -519,7 +571,7 @@ static int pushline (lua_State *L, int firstline) {
519571 lua_pushfstring (L , "return %s" , b + 1 ); /* change '=' to 'return' */
520572 else
521573 lua_pushlstring (L , b , l );
522- lua_freeline (L , b );
574+ lua_freeline (b );
523575 return 1 ;
524576}
525577
@@ -535,7 +587,7 @@ static int addreturn (lua_State *L) {
535587 if (status == LUA_OK ) {
536588 lua_remove (L , -2 ); /* remove modified line */
537589 if (line [0 ] != '\0' ) /* non empty? */
538- lua_saveline (L , line ); /* keep history */
590+ lua_saveline (line ); /* keep history */
539591 }
540592 else
541593 lua_pop (L , 2 ); /* pop result from 'luaL_loadbuffer' and modified line */
@@ -552,7 +604,7 @@ static int multiline (lua_State *L) {
552604 const char * line = lua_tolstring (L , 1 , & len ); /* get what it has */
553605 int status = luaL_loadbuffer (L , line , len , "=stdin" ); /* try it */
554606 if (!incomplete (L , status ) || !pushline (L , 0 )) {
555- lua_saveline (L , line ); /* keep history */
607+ lua_saveline (line ); /* keep history */
556608 return status ; /* cannot or should not try to add continuation line */
557609 }
558610 lua_pushliteral (L , "\n" ); /* add newline... */
0 commit comments