Refactoring in the use of 'readline' by 'lua.c'

More common code for 'readline' loaded statically or dynamically (or
not loaded).
This commit is contained in:
Roberto Ierusalimschy
2025-06-23 14:00:21 -03:00
parent 07b009c371
commit 30531c291b

75
lua.c
View File

@@ -432,32 +432,30 @@ static int handle_luainit (lua_State *L) {
/* /*
** lua_readline defines how to show a prompt and then read a line from ** * lua_initreadline initializes the readline system.
** the standard input. ** * lua_readline defines how to show a prompt and then read a line from
** lua_saveline defines how to "save" a read line in a "history". ** the standard input.
** lua_freeline defines how to free a line read by lua_readline. ** * lua_saveline defines how to "save" a read line in a "history".
** * lua_freeline defines how to free a line read by lua_readline.
**
** If lua_readline is defined, all of them should be defined.
*/ */
#if defined(LUA_USE_READLINE)
#include <readline/readline.h>
#include <readline/history.h>
#define lua_initreadline(L) ((void)L, rl_readline_name="lua")
#define lua_readline(b,p) ((void)b, readline(p))
#define lua_saveline(line) add_history(line)
#define lua_freeline(b) free(b)
#endif
#if !defined(lua_readline) /* { */ #if !defined(lua_readline) /* { */
/* pointer to dynamically loaded 'readline' function (if any) */ /* Code to use the readline library, either statically or dynamically linked */
typedef char *(*l_readline_t) (const char *prompt);
static l_readline_t l_readline = NULL; /* pointer to 'readline' function (if any) */
typedef char *(*l_readlineT) (const char *prompt);
static l_readlineT l_readline = NULL;
/* pointer to 'add_history' function (if any) */
typedef void (*l_addhistT) (const char *string);
static l_addhistT l_addhist = NULL;
static char *lua_readline (char *buff, const char *prompt) { static char *lua_readline (char *buff, const char *prompt) {
if (l_readline != NULL) /* is there a dynamic 'readline'? */ if (l_readline != NULL) /* is there a 'readline'? */
return (*l_readline)(prompt); /* use it */ return (*l_readline)(prompt); /* use it */
else { /* emulate 'readline' over 'buff' */ else { /* emulate 'readline' over 'buff' */
fputs(prompt, stdout); fputs(prompt, stdout);
@@ -467,33 +465,38 @@ static char *lua_readline (char *buff, const char *prompt) {
} }
/* pointer to dynamically loaded 'add_history' function (if any) */
typedef void (*l_addhist_t) (const char *string);
static l_addhist_t l_addhist = NULL;
static void lua_saveline (const char *line) { static void lua_saveline (const char *line) {
if (l_addhist != NULL) /* is there a dynamic 'add_history'? */ if (l_addhist != NULL) /* is there an 'add_history'? */
(*l_addhist)(line); /* use it */ (*l_addhist)(line); /* use it */
/* else nothing to be done */ /* else nothing to be done */
} }
static void lua_freeline (char *line) { static void lua_freeline (char *line) {
if (l_readline != NULL) /* is there a dynamic 'readline'? */ if (l_readline != NULL) /* is there a 'readline'? */
free(line); /* free line created by it */ free(line); /* free line created by it */
/* else 'lua_readline' used an automatic buffer; nothing to free */ /* else 'lua_readline' used an automatic buffer; nothing to free */
} }
#if !defined(LUA_USE_DLOPEN) || !defined(LUA_READLINELIB) #if defined(LUA_USE_READLINE) /* { */
#define lua_initreadline(L) ((void)L) /* assume Lua will be linked with '-lreadline' */
#include <readline/readline.h>
#include <readline/history.h>
#else /* { */ static void lua_initreadline(lua_State *L) {
UNUSED(L);
rl_readline_name = "lua";
l_readline = readline;
l_addhist = add_history;
}
#elif defined(LUA_USE_DLOPEN) && defined(LUA_READLINELIB) /* }{ */
/* try to load 'readline' dynamically */
#include <dlfcn.h> #include <dlfcn.h>
static void lua_initreadline (lua_State *L) { static void lua_initreadline (lua_State *L) {
void *lib = dlopen(LUA_READLINELIB, RTLD_NOW | RTLD_LOCAL); void *lib = dlopen(LUA_READLINELIB, RTLD_NOW | RTLD_LOCAL);
if (lib == NULL) if (lib == NULL)
@@ -502,14 +505,16 @@ static void lua_initreadline (lua_State *L) {
const char **name = cast(const char**, dlsym(lib, "rl_readline_name")); const char **name = cast(const char**, dlsym(lib, "rl_readline_name"));
if (name != NULL) if (name != NULL)
*name = "Lua"; *name = "Lua";
l_readline = cast(l_readline_t, cast_func(dlsym(lib, "readline"))); l_readline = cast(l_readlineT, cast_func(dlsym(lib, "readline")));
if (l_readline == NULL) l_addhist = cast(l_addhistT, cast_func(dlsym(lib, "add_history")));
lua_warning(L, "unable to load 'readline'", 0);
else
l_addhist = cast(l_addhist_t, cast_func(dlsym(lib, "add_history")));
} }
} }
#else /* }{ */
/* no readline; leave function pointers as NULL */
#define lua_initreadline(L) cast(void, L)
#endif /* } */ #endif /* } */
#endif /* } */ #endif /* } */