about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-11-20 16:16:00 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-11-20 16:33:41 -0800
commitb618bfc7cf7eb5fa498a051a17832c2cda4cca9c (patch)
tree0e5179289101da53572f9bce6c9f543d054d010a
parent8a3e81b4b0d8365baa40ff1326ed4d13b34506dc (diff)
downloadteliva-b618bfc7cf7eb5fa498a051a17832c2cda4cca9c.tar.gz
port changes from minimal to maximal version
From lcurseslib.c to lcurses/ directory.
-rw-r--r--src/lcurses/curses.c46
-rw-r--r--src/lcurses/curses.lua49
-rw-r--r--src/lcurses/window.c14
-rw-r--r--src/lcurseslib.c443
-rw-r--r--src/lua.c26
5 files changed, 47 insertions, 531 deletions
diff --git a/src/lcurses/curses.c b/src/lcurses/curses.c
index c5f7c3e..303607a 100644
--- a/src/lcurses/curses.c
+++ b/src/lcurses/curses.c
@@ -111,19 +111,12 @@ Pnew_chstr(lua_State *L)
 #define CCR(n, v)				\
 	lua_pushstring(L, n);			\
 	lua_pushinteger(L, v);			\
-	lua_settable(L, lua_upvalueindex(1))
+	lua_settable(L, -3);
 
 #define CC(s)	   CCR(#s, s)
 #define CF(i)	   CCR(LCURSES_STR(LCURSES_SPLICE(KEY_F, i)), KEY_F(i))
 
 /*
-** these values may be fixed only after initialization, so this is
-** called from Pinitscr, after the curses driver is initialized
-**
-** curses table is kept at upvalue position 1, in case the global
-** name is changed by the user or even in the registration phase by
-** the developer
-**
 ** some of these values are not constant so need to register
 ** them directly instead of using a table
 */
@@ -217,8 +210,8 @@ register_curses_constants(lua_State *L)
 ** proper cleanup)
 */
 
-static void
-cleanup(void)
+void
+cleanup_curses(void)
 {
 	if (!isendwin())
 	{
@@ -229,31 +222,12 @@ cleanup(void)
 }
 
 
-/***
-Initialise screen.
-@function initscr
-@treturn window main screen
-@see initscr(3x)
-*/
+extern void stack_dump(lua_State *L);
 static int
-Pinitscr(lua_State *L)
+init_stdscr(lua_State *L)
 {
-	WINDOW *w;
-
-	/* initialize curses */
-	w = initscr();
-
-	/* no longer used, so clean it up */
-	lua_pushstring(L, RIPOFF_TABLE);
-	lua_pushnil(L);
-	lua_settable(L, LUA_REGISTRYINDEX);
-
-	/* failed to initialize */
-	if (w == NULL)
-		return 0;
-
 	/* return stdscr - main window */
-	lc_newwin(L, w);
+	lc_newwin(L, stdscr);
 
 	/* save main window on registry */
 	lua_pushstring(L, STDSCR_REGISTRY);
@@ -261,10 +235,11 @@ Pinitscr(lua_State *L)
 	lua_rawset(L, LUA_REGISTRYINDEX);
 
 	/* setup curses constants - curses.xxx numbers */
+	lua_pushvalue(L, -2);
 	register_curses_constants(L);
 
 	/* install cleanup handler to help in debugging and screen trashing */
-	atexit(cleanup);
+	atexit(cleanup_curses);
 
 	return 1;
 }
@@ -1546,10 +1521,7 @@ luaopen_curses_c(lua_State *L)
 
 	luaL_register(L, "curses", curseslib);
 
-	lua_pushstring(L, "initscr");
-	lua_pushvalue(L, -2);
-	lua_pushcclosure(L, Pinitscr, 1);
-	lua_settable(L, -3);
+	init_stdscr(L);
 
 	return 1;
 }
diff --git a/src/lcurses/curses.lua b/src/lcurses/curses.lua
index bba9d12..216fb42 100644
--- a/src/lcurses/curses.lua
+++ b/src/lcurses/curses.lua
@@ -1,53 +1,20 @@
 --- Lua bindings for curses
 local M = curses
 
--- These Lua functions detect number of args, like Unified Funcs in Perl Curses
--- see http://pjb.com.au/comp/lua/lcurses.html
--- see http://search.cpan.org/perldoc?Curses
-
-function M.addch (...)
-  if #{...} == 3 then
-    return curses.stdscr():mvaddch(...)
-  else
-    return curses.stdscr():addch(...)
-  end
-end
-
-function M.addstr(...) -- detect number of args, like Unified Funcs in Perl Curses
-  if #{...} == 3 then
-    return curses.stdscr():mvaddstr(...)
-  else
-    return curses.stdscr():addstr(...)
-  end
-end
+function M.addch (c) return curses.stdscr():addch(c) end
+function M.mvaddch (y, x, c) return curses.stdscr():mvaddch(y, x, c) end
+function M.addstr (s) return curses.stdscr():addstr(s) end
+function M.mvaddstr (y, x, s) return curses.stdscr():mvaddstr(y, x, s) end
 
 function M.attrset (a) return curses.stdscr():attrset(a) end
 function M.clear ()    return curses.stdscr():clear() end
 function M.clrtobot () return curses.stdscr():clrtobot() end
 function M.clrtoeol () return curses.stdscr():clrtoeol() end
 
-function M.getch (...)
-  local c
-  if #{...} == 2 then
-    c = curses.stdscr():mvgetch(...)
-  else
-    c = curses.stdscr():getch()
-  end
-  if c < 256 then
-    return string.char(c)
-  end
-  -- could kludge-test for utf8, e.g. c3 a9 20  c3 aa 20  c3 ab 20  e2 82 ac 0a
-  return c
-end
-
-function M.getstr (...)
-  if #{...} > 1 then
-    return curses.stdscr():mvgetstr(...)
-  else
-    return curses.stdscr():getstr(...)
-  end
-end
-M.getnstr = M.getstr
+function M.getch () return curses.stdscr():getch() end
+function M.mvgetch (y, x) return curses.stdscr():getch(y, x) end
+function M.getstr (s) return curses.stdscr():getstr(s) end
+function M.mvgetstr (y, x, s) return curses.stdscr():mvgetstr(y, x, s) end
 
 function M.getyx ()    return curses.stdscr():getyx() end
 function M.keypad (b)  return curses.stdscr():keypad(b) end
diff --git a/src/lcurses/window.c b/src/lcurses/window.c
index fd18570..9c243ea 100644
--- a/src/lcurses/window.c
+++ b/src/lcurses/window.c
@@ -36,8 +36,6 @@
 @classmod curses.window
 */
 
-//? #include <config.h>
-
 #include "_helpers.c"
 
 #include "chstr.c"
@@ -311,10 +309,13 @@ Refresh the window terminal display from the virtual screen.
 @see curses.doupdate
 @see noutrefresh
 */
+extern void draw_menu (lua_State *L);
 static int
 Wrefresh(lua_State *L)
 {
-	return pushokresult(wrefresh(checkwin(L, 1)));
+	int result = wrefresh(checkwin(L, 1));
+	draw_menu(L);
+	return pushokresult(result);
 }
 
 
@@ -548,6 +549,7 @@ Wgetmaxyx(lua_State *L)
 	WINDOW *w = checkwin(L, 1);
 	int y, x;
 	getmaxyx(w, y, x);
+	--y;  // set aside space for the menu bar
 	lua_pushinteger(L, y);
 	lua_pushinteger(L, x);
 	return 2;
@@ -1302,6 +1304,7 @@ Read a character from the window input.
 @see curses.echo
 @see keypad
 */
+extern void switch_to_editor (lua_State *L, const char *message);
 static int
 Wgetch(lua_State *L)
 {
@@ -1310,6 +1313,11 @@ Wgetch(lua_State *L)
 
 	if (c == ERR)
 		return 0;
+	if (c == 24)  /* ctrl-x */
+		exit(0);
+	if (c == 5)  /* ctrl-e */
+		switch_to_editor(L, "");
+	/* handle other standard menu hotkeys here */
 
 	return pushintresult(c);
 }
diff --git a/src/lcurseslib.c b/src/lcurseslib.c
index 441a76c..b5173bb 100644
--- a/src/lcurseslib.c
+++ b/src/lcurseslib.c
@@ -1,21 +1,7 @@
 #include <ncurses.h>
-#include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #include "lua.h"
-#include "llimits.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-void cleanup_curses (void) {
-  if (!isendwin()) {
-    wclear(stdscr);
-    wrefresh(stdscr);
-    endwin();
-  }
-}
 
 
 int menu_column = 0;
@@ -52,432 +38,3 @@ void draw_menu (lua_State *L) {
   lua_pop(L, 1);
   attroff(A_BOLD|A_REVERSE);
 }
-
-
-static int Prefresh (lua_State *L) {
-  refresh();
-  draw_menu(L);
-  return 1;
-}
-
-
-static int argtypeerror (lua_State *L, int narg, const char *expected) {
-  const char *got = luaL_typename(L, narg);
-  return luaL_argerror(L, narg,
-          lua_pushfstring(L, "%s expected, got %s", expected, got));
-}
-
-
-static void checktype (lua_State *L, int narg, int t, const char *expected) {
-  if (lua_type(L, narg) != t)
-    argtypeerror(L, narg, expected);
-}
-
-
-static lua_Integer checkinteger (lua_State *L, int narg, const char *expected) {
-  lua_Integer d = lua_tointeger(L, narg);
-  if (d == 0 && !lua_isnumber(L, narg))
-    argtypeerror(L, narg, expected);
-  return d;
-}
-
-
-static int Pstdscr (lua_State *L) {
-  lua_pushstring(L, "curses:stdscr");
-  lua_rawget(L, LUA_REGISTRYINDEX);
-  return 1;
-}
-
-
-static int Pcolor_pairs (lua_State *L) {
-  lua_pushinteger(L, COLOR_PAIRS);
-  return 1;
-}
-
-
-static int Pinit_pair (lua_State *L) {
-  int pair = checkinteger(L, 1, "int");
-  short f = checkinteger(L, 2, "int");
-  short b = checkinteger(L, 3, "int");
-  init_pair(pair, f, b);
-  return 1;
-}
-
-
-static int Pcolor_pair (lua_State *L)
-{
-  int n = checkinteger(L, 1, "int");
-  lua_pushinteger(L, COLOR_PAIR(n));
-  return 1;
-}
-
-
-extern void switch_to_editor (lua_State *L, const char *message);
-static int Pgetch (lua_State *L) {
-  int c = wgetch(stdscr);
-  if (c == ERR)
-    return 0;
-  if (c == 24)  /* ctrl-x */
-    exit(0);
-  if (c == 5)  /* ctrl-e */
-    switch_to_editor(L, "");
-  /* handle other standard menu hotkeys here */
-  lua_pushinteger(L, c);
-  return 1;
-}
-
-
-static const struct luaL_Reg curseslib [] = {
-  {"color_pairs", Pcolor_pairs},
-  {"color_pair", Pcolor_pair},
-  {"getch", Pgetch},
-  {"init_pair", Pinit_pair},
-  {"refresh", Prefresh},
-  {"stdscr", Pstdscr},
-  {NULL, NULL}
-};
-
-
-static void curses_newwin (lua_State *L, WINDOW *nw) {
-  if (nw) {
-    WINDOW **w = lua_newuserdata(L, sizeof(WINDOW*));
-    luaL_getmetatable(L, "curses:window");
-    lua_setmetatable(L, -2);
-    *w = nw;
-  }
-  else {
-    lua_pushliteral(L, "failed to create window");
-    lua_error(L);
-  }
-}
-
-
-static WINDOW **lc_getwin (lua_State *L, int offset) {
-  WINDOW **w = (WINDOW**)luaL_checkudata(L, offset, "curses:window");
-  if (w == NULL)
-    luaL_argerror(L, offset, "bad curses window");
-  return w;
-}
-
-
-static WINDOW *checkwin (lua_State *L, int offset) {
-  WINDOW **w = lc_getwin(L, offset);
-  if (*w == NULL)
-    luaL_argerror(L, offset, "attempt to use closed curses window");
-  return *w;
-}
-
-
-static chtype checkch (lua_State *L, int narg) {
-  if (lua_isnumber(L, narg))
-    return cast(chtype, checkinteger(L, narg, "int"));
-  if (lua_isstring(L, narg))
-    return *lua_tostring(L, narg);
-
-  return argtypeerror(L, narg, "int or char");
-}
-
-
-static int optint (lua_State *L, int narg, lua_Integer def) {
-  if (lua_isnoneornil(L, narg))
-    return cast(int, def);
-  return cast(int, checkinteger(L, narg, "int or nil"));
-}
-
-
-static int W__tostring (lua_State *L) {
-  WINDOW **w = lc_getwin(L, 1);
-  char buff[34];
-  if (*w == NULL)
-    strcpy(buff, "closed");
-  else
-    sprintf(buff, "%p", lua_touserdata(L, 1));
-  lua_pushfstring(L, "curses window (%s)", buff);
-  return 1;
-}
-
-
-static int Waddstr (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  const char *str = luaL_checkstring(L, 2);
-  int n = optint(L, 3, -1);
-  lua_pushboolean(L, waddnstr(w, str, n));
-  return 1;
-}
-
-
-static int Wattroff (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  int attrs = checkinteger(L, 2, "int");
-  lua_pushboolean(L, wattroff(w, attrs));
-  return 1;
-}
-
-
-static int Wattron (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  int attrs = checkinteger(L, 2, "int");
-  lua_pushboolean(L, wattron(w, attrs));
-  return 1;
-}
-
-
-static int Wclear (lua_State *L) {
-  lua_pushboolean(L, wclear(checkwin(L, 1)));
-  return 1;
-}
-
-
-static int Wgetyx (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  int y, x;
-  getyx(w, y, x);
-  lua_pushinteger(L, y);
-  lua_pushinteger(L, x);
-  return 2;
-}
-
-
-static int Wgetmaxyx (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  int y, x;
-  getmaxyx(w, y, x);
-  --y;  // set aside space for the menu bar
-  lua_pushinteger(L, y);
-  lua_pushinteger(L, x);
-  return 2;
-}
-
-
-static int Wmvaddch (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  int y = checkinteger(L, 2, "int");
-  int x = checkinteger(L, 3, "int");
-  chtype ch = checkch(L, 4);
-  mvwaddch(w, y, x, ch);
-  return 1;
-}
-
-
-static int Wmvaddstr (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  int y = checkinteger(L, 2, "int");
-  int x = checkinteger(L, 3, "int");
-  const char *str = luaL_checkstring(L, 4);
-  int n = optint(L, 5, -1);
-  mvwaddnstr(w, y, x, str, n);
-  return 1;
-}
-
-
-static int Wnodelay (lua_State *L) {
-  WINDOW *w = checkwin(L, 1);
-  checktype(L, 2, LUA_TBOOLEAN, "boolean or nil");
-  int bf = (int)lua_toboolean(L, 2);
-  lua_pushboolean(L, nodelay(w, bf));
-  return 1;
-}
-
-
-static const luaL_Reg curses_window_methods[] =
-{
-  {"__tostring", W__tostring},
-  {"addstr", Waddstr},
-  {"attroff", Wattroff},
-  {"attron", Wattron},
-  {"clear", Wclear},
-  {"getmaxyx", Wgetmaxyx},
-  {"getyx", Wgetyx},
-  {"mvaddch", Wmvaddch},
-  {"mvaddstr", Wmvaddstr},
-  {"nodelay", Wnodelay},
-  {NULL, NULL}
-};
-
-
-static void register_curses_constant (lua_State *L, const char* name, int val) {
-  lua_pushstring(L, name);
-  lua_pushinteger(L, val);
-  lua_settable(L, -3);
-}
-
-
-static void register_curses_constants (lua_State *L) {
-#define CC(s) register_curses_constant(L, #s, s)
-  /* colors */
-  CC(COLOR_BLACK);
-  CC(COLOR_RED);
-  CC(COLOR_GREEN);
-  CC(COLOR_YELLOW);
-  CC(COLOR_BLUE);
-  CC(COLOR_MAGENTA);
-  CC(COLOR_CYAN);
-  CC(COLOR_WHITE);
-
-  /* alternate character set */
-  CC(ACS_BLOCK);
-  CC(ACS_BOARD);
-
-  CC(ACS_BTEE);
-  CC(ACS_TTEE);
-  CC(ACS_LTEE);
-  CC(ACS_RTEE);
-  CC(ACS_LLCORNER);
-  CC(ACS_LRCORNER);
-  CC(ACS_URCORNER);
-  CC(ACS_ULCORNER);
-
-  CC(ACS_LARROW);
-  CC(ACS_RARROW);
-  CC(ACS_UARROW);
-  CC(ACS_DARROW);
-
-  CC(ACS_HLINE);
-  CC(ACS_VLINE);
-
-  CC(ACS_BULLET);
-  CC(ACS_CKBOARD);
-  CC(ACS_LANTERN);
-  CC(ACS_DEGREE);
-  CC(ACS_DIAMOND);
-
-  CC(ACS_PLMINUS);
-  CC(ACS_PLUS);
-  CC(ACS_S1);
-  CC(ACS_S9);
-
-  /* attributes */
-  CC(A_NORMAL);
-  CC(A_STANDOUT);
-  CC(A_UNDERLINE);
-  CC(A_REVERSE);
-  CC(A_BLINK);
-  CC(A_DIM);
-  CC(A_BOLD);
-  CC(A_PROTECT);
-  CC(A_INVIS);
-  CC(A_ALTCHARSET);
-  CC(A_CHARTEXT);
-  CC(A_ATTRIBUTES);
-  CC(A_COLOR);
-
-  /* key functions */
-  CC(KEY_BREAK);
-  CC(KEY_DOWN);
-  CC(KEY_UP);
-  CC(KEY_LEFT);
-  CC(KEY_RIGHT);
-  CC(KEY_HOME);
-  CC(KEY_BACKSPACE);
-
-  CC(KEY_DL);
-  CC(KEY_IL);
-  CC(KEY_DC);
-  CC(KEY_IC);
-  CC(KEY_EIC);
-  CC(KEY_CLEAR);
-  CC(KEY_EOS);
-  CC(KEY_EOL);
-  CC(KEY_SF);
-  CC(KEY_SR);
-  CC(KEY_NPAGE);
-  CC(KEY_PPAGE);
-  CC(KEY_STAB);
-  CC(KEY_CTAB);
-  CC(KEY_CATAB);
-  CC(KEY_ENTER);
-  CC(KEY_SRESET);
-  CC(KEY_RESET);
-  CC(KEY_PRINT);
-  CC(KEY_LL);
-  CC(KEY_A1);
-  CC(KEY_A3);
-  CC(KEY_B2);
-  CC(KEY_C1);
-  CC(KEY_C3);
-  CC(KEY_BTAB);
-  CC(KEY_BEG);
-  CC(KEY_CANCEL);
-  CC(KEY_CLOSE);
-  CC(KEY_COMMAND);
-  CC(KEY_COPY);
-  CC(KEY_CREATE);
-  CC(KEY_END);
-  CC(KEY_EXIT);
-  CC(KEY_FIND);
-  CC(KEY_HELP);
-  CC(KEY_MARK);
-  CC(KEY_MESSAGE); /* ncurses extension: CC(KEY_MOUSE); */
-  CC(KEY_MOVE);
-  CC(KEY_NEXT);
-  CC(KEY_OPEN);
-  CC(KEY_OPTIONS);
-  CC(KEY_PREVIOUS);
-  CC(KEY_REDO);
-  CC(KEY_REFERENCE);
-  CC(KEY_REFRESH);
-  CC(KEY_REPLACE);
-  CC(KEY_RESIZE);
-  CC(KEY_RESTART);
-  CC(KEY_RESUME);
-  CC(KEY_SAVE);
-  CC(KEY_SBEG);
-  CC(KEY_SCANCEL);
-  CC(KEY_SCOMMAND);
-  CC(KEY_SCOPY);
-  CC(KEY_SCREATE);
-  CC(KEY_SDC);
-  CC(KEY_SDL);
-  CC(KEY_SELECT);
-  CC(KEY_SEND);
-  CC(KEY_SEOL);
-  CC(KEY_SEXIT);
-  CC(KEY_SFIND);
-  CC(KEY_SHELP);
-  CC(KEY_SHOME);
-  CC(KEY_SIC);
-  CC(KEY_SLEFT);
-  CC(KEY_SMESSAGE);
-  CC(KEY_SMOVE);
-  CC(KEY_SNEXT);
-  CC(KEY_SOPTIONS);
-  CC(KEY_SPREVIOUS);
-  CC(KEY_SPRINT);
-  CC(KEY_SREDO);
-  CC(KEY_SREPLACE);
-  CC(KEY_SRIGHT);
-  CC(KEY_SRSUME);
-  CC(KEY_SSAVE);
-  CC(KEY_SSUSPEND);
-  CC(KEY_SUNDO);
-  CC(KEY_SUSPEND);
-  CC(KEY_UNDO);
-#undef CC
-}
-
-
-LUALIB_API int luaopen_curses (lua_State *L) {
-  luaL_newmetatable(L, "curses:window");
-
-  /* metatable.__index = metatable */
-  lua_pushstring(L, "__index");
-  lua_pushvalue(L, -2);
-  lua_settable(L, -3);
-
-  luaL_register(L, NULL, curses_window_methods);
-
-  luaL_register(L, "curses", curseslib);
-
-  /* save main window on registry */
-  curses_newwin(L, stdscr);
-  lua_pushstring(L, "curses:stdscr");
-  lua_pushvalue(L, -2);
-  lua_rawset(L, LUA_REGISTRYINDEX);
-
-  lua_pushvalue(L, -2);
-  register_curses_constants(L);
-
-  atexit(cleanup_curses);
-  return 1;
-}
-
diff --git a/src/lua.c b/src/lua.c
index 61836e6..ec8818b 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -249,30 +249,34 @@ static void dotty (lua_State *L) {
 void stack_dump (lua_State *L) {
   int i;
   int top = lua_gettop(L);
+  int y = 1;
   for (i = 1; i <= top; i++) {  /* repeat for each level */
     int t = lua_type(L, i);
     switch (t) {
 
       case LUA_TSTRING:  /* strings */
-        printf("`%s'", lua_tostring(L, i));
+        mvprintw(y, 30, "`%s'", lua_tostring(L, i));
         break;
 
       case LUA_TBOOLEAN:  /* booleans */
-        printf(lua_toboolean(L, i) ? "true" : "false");
+        mvprintw(y, 30, lua_toboolean(L, i) ? "true" : "false");
         break;
 
       case LUA_TNUMBER:  /* numbers */
-        printf("%g", lua_tonumber(L, i));
+        mvprintw(y, 30, "%g", lua_tonumber(L, i));
         break;
 
       default:  /* other values */
-        printf("%s", lua_typename(L, t));
+        mvprintw(y, 30, "%s", lua_typename(L, t));
         break;
 
     }
-    printf("  ");  /* put a separator */
+    y++;
+    mvprintw(y, 30, "  ");  /* put a separator */
+    y++;
   }
-  printf("\n");  /* end the listing */
+  mvprintw(y, 30, "\n");  /* end the listing */
+  y++;
 }
 
 
@@ -646,13 +650,21 @@ struct Smain {
 static int pmain (lua_State *L) {
   struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
   char **argv = s->argv;
+  int status;
   int image;
   int has_i = 0, has_v = 0, has_e = 0;
   globalL = L;
   if (argv[0] && argv[0][0]) progname = argv[0];
   lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
   luaL_openlibs(L);  /* open libraries */
-  dofile(L, "lcurses/curses.lua");
+  status = luaL_loadfile(L, "lcurses/curses.lua") || docall(L, /*nargs*/0, /*don't clean up stack*/0);
+  if (status != 0) return report(L, status);
+  if (lua_isnil(L, -1)) {
+    endwin();
+    printf("lcurses/curses.lua didn't return a module\n");
+    exit(1);
+  }
+  lua_setglobal(L, "curses");
   lua_gc(L, LUA_GCRESTART, 0);
   s->status = handle_luainit(L);
   if (s->status != 0) return 0;