inline lcurses maximally rather than minimally

Until now we had just the bare minimum bindings needed for the demos
built so far. Now we have all of lcurses building in place with minimal
changes.

The changes in this commit can run hanoi.lua when inlined into Lua 5.1,
but don't work with Teliva.
This commit is contained in:
Kartik K. Agaram 2021-11-19 19:11:03 -08:00
parent 9837d327f5
commit b43747ecef
12 changed files with 4991 additions and 4 deletions

View File

@ -28,7 +28,7 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
lundump.o lvm.o lzio.o \
kilo.o
LIB_O= lauxlib.o lbaselib.o lcurseslib.o ldblib.o liolib.o lmathlib.o \
loslib.o ltablib.o lstrlib.o loadlib.o linit.o
loslib.o ltablib.o lstrlib.o loadlib.o linit.o lcurses/curses.o
LUA_T= teliva
LUA_O= lua.o
@ -180,4 +180,8 @@ lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
ltm.h lzio.h lmem.h lopcodes.h lundump.h
lcurses/curses.o: lcurses/curses.c lcurses/window.c lcurses/chstr.c \
lcurses/_helpers.c lcurses/compat-5.2.c lcurses/compat-5.2.h \
lcurses/strlcpy.c
# (end of Makefile)

210
src/lcurses/_helpers.c Normal file
View File

@ -0,0 +1,210 @@
/*
* POSIX library for Lua 5.1, 5.2 & 5.3.
* (c) Gary V. Vaughan <gary@vaughan.pe>, 2013-2017
* (c) Reuben Thomas <rrt@sc3d.org> 2010-2013
* (c) Natanael Copa <natanael.copa@gmail.com> 2008-2010
* Clean up and bug fixes by Leo Razoumov <slonik.az@gmail.com> 2006-10-11
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> 07 Apr 2006 23:17:49
* Based on original by Claudio Terra for Lua 3.x.
* With contributions by Roberto Ierusalimschy.
* With documentation from Steve Donovan 2012
*/
#ifndef LCURSES__HELPERS_C
#define LCURSES__HELPERS_C 1
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h> /* for _POSIX_VERSION */
#include <ncurses.h>
#include <term.h>
/* NetBSD's default curses implementation is not quite complete. This
disables those missing functions unless linked to ncurses instead. */
#if defined NCURSES_VERSION || !defined __NetBSD__
# define LCURSES_POSIX_COMPLIANT 1
#endif
#include "../lua.h"
#include "../lualib.h"
#include "../lauxlib.h"
#if LUA_VERSION_NUM < 503
# define lua_isinteger lua_isnumber
# if LUA_VERSION_NUM == 501
# include "compat-5.2.c"
# endif
#endif
#if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503
# define lua_objlen lua_rawlen
# define lua_strlen lua_rawlen
# define luaL_openlib(L,n,l,nup) luaL_setfuncs((L),(l),(nup))
# define luaL_register(L,n,l) (luaL_newlib(L,l))
#endif
#ifndef STREQ
# define STREQ(a, b) (strcmp (a, b) == 0)
#endif
/* Mark unused parameters required only to match a function type
specification. */
#ifdef __GNUC__
# define LCURSES_UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define LCURSES_UNUSED(x) UNUSED_ ## x
#endif
/* LCURSES_STMT_BEG/END are used to create macros that expand to a
single compound statement in a portable way. */
#if defined __GNUC__ && !defined __STRICT_ANSI__ && !defined __cplusplus
# define LCURSES_STMT_BEG (void)(
# define LCURSES_STMT_END )
#else
# if (defined sun || defined __sun__)
# define LCURSES_STMT_BEG if (1)
# define LCURSES_STMT_END else (void)0
# else
# define LCURSES_STMT_BEG do
# define LCURSES_STMT_END while (0)
# endif
#endif
/* The extra indirection to these macros is required so that if the
arguments are themselves macros, they will get expanded too. */
#define LCURSES__SPLICE(_s, _t) _s##_t
#define LCURSES_SPLICE(_s, _t) LCURSES__SPLICE(_s, _t)
#define LCURSES__STR(_s) #_s
#define LCURSES_STR(_s) LCURSES__STR(_s)
/* The +1 is to step over the leading '_' that is required to prevent
premature expansion of MENTRY arguments if we didn't add it. */
#define LCURSES__STR_1(_s) (#_s + 1)
#define LCURSES_STR_1(_s) LCURSES__STR_1(_s)
#define LCURSES_CONST(_f) LCURSES_STMT_BEG { \
lua_pushinteger(L, _f); \
lua_setfield(L, -2, #_f); \
} LCURSES_STMT_END
#define LCURSES_FUNC(_s) {LCURSES_STR_1(_s), (_s)}
#define pushokresult(b) pushboolresult((int) (b) == OK)
#ifndef errno
extern int errno;
#endif
/* ========================= *
* Bad argument diagnostics. *
* ========================= */
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 lua_Integer
checkinteger(lua_State *L, int narg, const char *expected)
{
lua_Integer d = lua_tointeger(L, narg);
if (d == 0 && !lua_isinteger(L, narg))
argtypeerror(L, narg, expected);
return d;
}
static int
checkint(lua_State *L, int narg)
{
return (int)checkinteger(L, narg, "int");
}
static chtype
checkch(lua_State *L, int narg)
{
if (lua_isnumber(L, narg))
return (chtype)checkint(L, narg);
if (lua_isstring(L, narg))
return *lua_tostring(L, narg);
return argtypeerror(L, narg, "int or char");
}
static chtype
optch(lua_State *L, int narg, chtype def)
{
if (lua_isnoneornil(L, narg))
return def;
if (lua_isnumber(L, narg) || lua_isstring(L, narg))
return checkch(L, narg);
return argtypeerror(L, narg, "int or char or nil");
}
static int
optint(lua_State *L, int narg, lua_Integer def)
{
if (lua_isnoneornil(L, narg))
return (int) def;
return (int)checkinteger(L, narg, "int or nil");
}
#define pushboolresult(b) (lua_pushboolean(L, (b)), 1)
#define pushintresult(n) (lua_pushinteger(L, (n)), 1)
#define pushstringresult(s) (lua_pushstring(L, (s)), 1)
/* ================== *
* Utility functions. *
* ================== */
#define pushintegerfield(k,v) LCURSES_STMT_BEG { \
lua_pushinteger(L, (lua_Integer) v); lua_setfield(L, -2, k); \
} LCURSES_STMT_END
#define pushnumberfield(k,v) LCURSES_STMT_BEG { \
lua_pushnumber(L, (lua_Number) v); lua_setfield(L, -2, k); \
} LCURSES_STMT_END
#define pushstringfield(k,v) LCURSES_STMT_BEG { \
if (v) { \
lua_pushstring(L, (const char *) v); \
lua_setfield(L, -2, k); \
} \
} LCURSES_STMT_END
#define pushliteralfield(k,v) LCURSES_STMT_BEG { \
if (v) { \
lua_pushliteral(L, v); \
lua_setfield(L, -2, k); \
} \
} LCURSES_STMT_END
#define settypemetatable(t) LCURSES_STMT_BEG { \
if (luaL_newmetatable(L, t) == 1) \
pushliteralfield("_type", t); \
lua_setmetatable(L, -2); \
} LCURSES_STMT_END
#define setintegerfield(_p, _n) pushintegerfield(LCURSES_STR(_n), _p->_n)
#define setnumberfield(_p, _n) pushnumberfield(LCURSES_STR(_n), _p->_n)
#define setstringfield(_p, _n) pushstringfield(LCURSES_STR(_n), _p->_n)
#endif /*LCURSES__HELPERS_C*/

293
src/lcurses/chstr.c Normal file
View File

@ -0,0 +1,293 @@
/*
* Curses binding for Lua 5.1, 5.2 & 5.3.
*
* (c) Gary V. Vaughan <gary@vaughan.pe> 2013-2017
* (c) Reuben Thomas <rrt@sc3d.org> 2009-2012
* (c) Tiago Dionizio <tiago.dionizio AT gmail.com> 2004-2007
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/***
Curses attributed string buffers.
An array of characters, plus associated curses attributes and
colors at each position.
Although marginally useful alone, the constants used to set colors
and attributes in `chstr` buffers are not defined until **after**
`curses.initscr ()` has been called.
@classmod curses.chstr
*/
#ifndef LCURSES_CHSTR_C
#define LCURSES_CHSTR_C 1
#include "_helpers.c"
static const char *CHSTRMETA = "curses:chstr";
typedef struct
{
unsigned int len;
chtype str[1];
} chstr;
#define CHSTR_SIZE(len) (sizeof(chstr) + len * sizeof(chtype))
/* create new chstr object and leave it in the lua stack */
static chstr *
chstr_new(lua_State *L, int len)
{
chstr *cs;
if (len < 1)
return luaL_error(L, "invalid chstr length"), NULL;
cs = lua_newuserdata(L, CHSTR_SIZE(len));
luaL_getmetatable(L, CHSTRMETA);
lua_setmetatable(L, -2);
cs->len = len;
return cs;
}
/* get chstr from lua (convert if needed) */
static chstr *
checkchstr(lua_State *L, int narg)
{
chstr *cs = (chstr*)luaL_checkudata(L, narg, CHSTRMETA);
if (cs)
return cs;
luaL_argerror(L, narg, "bad curses chstr");
/*NOTREACHED*/
return NULL;
}
/***
Change the contents of the chstr.
@function set_str
@int o offset to start of change
@string s characters to insert into *cs* at *o*
@int[opt=A_NORMAL] attr attributes for changed elements
@int[opt=1] rep repeat count
@usage
cs = curses.chstr (10)
cs:set_str(0, "0123456789", curses.A_BOLD)
*/
static int
Cset_str(lua_State *L)
{
chstr *cs = checkchstr(L, 1);
int offset = checkint(L, 2);
const char *str = luaL_checkstring(L, 3);
int len = lua_strlen(L, 3);
int attr = optint(L, 4, A_NORMAL);
int rep = optint(L, 5, 1);
int i;
if (offset < 0)
return 0;
while (rep-- > 0 && offset <= (int)cs->len)
{
if (offset + len - 1 > (int)cs->len)
len = cs->len - offset + 1;
for (i = 0; i < len; ++i)
cs->str[offset + i] = str[i] | attr;
offset += len;
}
return 0;
}
/***
Set a character in the buffer.
*ch* can be a one-character string, or an integer from `string.byte`
@function set_ch
@int o offset to start of change
@param int|string ch character to insert
@int[opt=A_NORMAL] attr attributes for changed elements
@int[opt=1] rep repeat count
@usage
-- Write a bold 'A' followed by normal 'a' chars to a new buffer
size = 10
cs = curses.chstr (size)
cs:set_ch(0, 'A', curses.A_BOLD)
cs:set_ch(1, 'a', curses.A_NORMAL, size - 1)
*/
static int
Cset_ch(lua_State *L)
{
chstr* cs = checkchstr(L, 1);
int offset = checkint(L, 2);
chtype ch = checkch(L, 3);
int attr = optint(L, 4, A_NORMAL);
int rep = optint(L, 5, 1);
while (rep-- > 0)
{
if (offset < 0 || offset >= (int) cs->len)
return 0;
cs->str[offset] = ch | attr;
++offset;
}
return 0;
}
/***
Get information from the chstr.
@function get
@int o offset from start of *cs*
@treturn int character at offset *o* in *cs*
@treturn int bitwise-OR of attributes at offset *o* in *cs*
@treturn int colorpair at offset *o* in *cs*
@usage
cs = curses.chstr (10)
cs:set_ch(0, 'A', curses.A_BOLD, 10)
--> 65 2097152 0
print (cs:get (9))
*/
static int
Cget(lua_State *L)
{
chstr* cs = checkchstr(L, 1);
int offset = checkint(L, 2);
chtype ch;
if (offset < 0 || offset >= (int) cs->len)
return 0;
ch = cs->str[offset];
lua_pushinteger(L, ch & A_CHARTEXT);
lua_pushinteger(L, ch & A_ATTRIBUTES);
lua_pushinteger(L, ch & A_COLOR);
return 3;
}
/***
Retrieve chstr length.
@function len
@tparam chstr cs buffer to act on
@treturn int length of *cs*
@usage
cs = curses.chstr (123)
--> 123
print (cs:len ())
*/
static int
Clen(lua_State *L)
{
chstr *cs = checkchstr(L, 1);
return pushintresult(cs->len);
}
/***
Duplicate chstr.
@function dup
@treturn chstr duplicate of *cs*
@usage
dup = cs:dup ()
*/
static int
Cdup(lua_State *L)
{
chstr *cs = checkchstr(L, 1);
chstr *ncs = chstr_new(L, cs->len);
memcpy(ncs->str, cs->str, CHSTR_SIZE(cs->len));
return 1;
}
/***
Initialise a new chstr.
@function __call
@int len buffer length
@treturn chstr a new chstr filled with spaces
@usage
cs = curses.chstr (10)
*/
static int
C__call(lua_State *L)
{
int len = checkint(L, 2);
chstr* ncs = chstr_new(L, len);
memset(ncs->str, ' ', len * sizeof(chtype));
return 1;
}
static const luaL_Reg curses_chstr_fns[] =
{
LCURSES_FUNC( Clen ),
LCURSES_FUNC( Cset_ch ),
LCURSES_FUNC( Cset_str ),
LCURSES_FUNC( Cget ),
LCURSES_FUNC( Cdup ),
{ NULL, NULL }
};
LUALIB_API int
luaopen_curses_chstr(lua_State *L)
{
int t, mt;
luaL_register(L, "curses.chstr", curses_chstr_fns);
t = lua_gettop(L);
lua_createtable(L, 0, 1); /* u = {} */
lua_pushcfunction(L, C__call);
lua_setfield(L, -2, "__call"); /* u.__call = C__call */
lua_setmetatable(L, -2); /* setmetatable (t, u) */
luaL_newmetatable(L, CHSTRMETA);
mt = lua_gettop(L);
lua_pushvalue(L, mt);
lua_setfield(L, -2, "__index"); /* mt.__index = mt */
lua_pushliteral(L, "CursesChstr");
lua_setfield(L, -2, "_type"); /* mt._type = "CursesChstr" */
/* for k,v in pairs(t) do mt[k]=v end */
for (lua_pushnil(L); lua_next(L, t) != 0;)
lua_setfield(L, mt, lua_tostring(L, -2));
lua_pop(L, 1); /* pop mt */
return 1;
}
#endif /*!LCURSES_CHSTR_C*/

682
src/lcurses/compat-5.2.c Normal file
View File

@ -0,0 +1,682 @@
#include <errno.h>
#include <string.h>
#include "../lua.h"
#include "../lauxlib.h"
#include "compat-5.2.h"
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501
int lua_absindex (lua_State *L, int i) {
if (i < 0 && i > LUA_REGISTRYINDEX)
i += lua_gettop(L) + 1;
return i;
}
void lua_copy (lua_State *L, int from, int to) {
int abs_to = lua_absindex(L, to);
luaL_checkstack(L, 1, "not enough stack slots");
lua_pushvalue(L, from);
lua_replace(L, abs_to);
}
void lua_rawgetp (lua_State *L, int i, const void *p) {
int abs_i = lua_absindex(L, i);
lua_pushlightuserdata(L, (void*)p);
lua_rawget(L, abs_i);
}
void lua_rawsetp (lua_State *L, int i, const void *p) {
int abs_i = lua_absindex(L, i);
luaL_checkstack(L, 1, "not enough stack slots");
lua_pushlightuserdata(L, (void*)p);
lua_insert(L, -2);
lua_rawset(L, abs_i);
}
void *luaL_testudata (lua_State *L, int i, const char *tname) {
void *p = lua_touserdata(L, i);
luaL_checkstack(L, 2, "not enough stack slots");
if (p == NULL || !lua_getmetatable(L, i))
return NULL;
else {
int res = 0;
luaL_getmetatable(L, tname);
res = lua_rawequal(L, -1, -2);
lua_pop(L, 2);
if (!res)
p = NULL;
}
return p;
}
lua_Number lua_tonumberx (lua_State *L, int i, int *isnum) {
lua_Number n = lua_tonumber(L, i);
if (isnum != NULL) {
*isnum = (n != 0 || lua_isnumber(L, i));
}
return n;
}
#define PACKAGE_KEY "_COMPAT52_PACKAGE"
static void push_package_table (lua_State *L) {
lua_pushliteral(L, PACKAGE_KEY);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
/* try to get package table from globals */
lua_pushliteral(L, "package");
lua_rawget(L, LUA_GLOBALSINDEX);
if (lua_istable(L, -1)) {
lua_pushliteral(L, PACKAGE_KEY);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
}
}
}
void lua_getuservalue (lua_State *L, int i) {
luaL_checktype(L, i, LUA_TUSERDATA);
luaL_checkstack(L, 2, "not enough stack slots");
lua_getfenv(L, i);
lua_pushvalue(L, LUA_GLOBALSINDEX);
if (lua_rawequal(L, -1, -2)) {
lua_pop(L, 1);
lua_pushnil(L);
lua_replace(L, -2);
} else {
lua_pop(L, 1);
push_package_table(L);
if (lua_rawequal(L, -1, -2)) {
lua_pop(L, 1);
lua_pushnil(L);
lua_replace(L, -2);
} else
lua_pop(L, 1);
}
}
void lua_setuservalue (lua_State *L, int i) {
luaL_checktype(L, i, LUA_TUSERDATA);
if (lua_isnil(L, -1)) {
luaL_checkstack(L, 1, "not enough stack slots");
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_replace(L, -2);
}
lua_setfenv(L, i);
}
/*
** Adapted from Lua 5.2.0
*/
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
luaL_checkstack(L, nup+1, "too many upvalues");
for (; l->name != NULL; l++) { /* fill the table with given functions */
int i;
lua_pushstring(L, l->name);
for (i = 0; i < nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -(nup + 1));
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
}
lua_pop(L, nup); /* remove upvalues */
}
void luaL_setmetatable (lua_State *L, const char *tname) {
luaL_checkstack(L, 1, "not enough stack slots");
luaL_getmetatable(L, tname);
lua_setmetatable(L, -2);
}
int luaL_getsubtable (lua_State *L, int i, const char *name) {
int abs_i = lua_absindex(L, i);
luaL_checkstack(L, 3, "not enough stack slots");
lua_pushstring(L, name);
lua_gettable(L, abs_i);
if (lua_istable(L, -1))
return 1;
lua_pop(L, 1);
lua_newtable(L);
lua_pushstring(L, name);
lua_pushvalue(L, -2);
lua_settable(L, abs_i);
return 0;
}
#if !defined(COMPAT52_IS_LUAJIT)
static int countlevels (lua_State *L) {
lua_Debug ar;
int li = 1, le = 1;
/* find an upper bound */
while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
/* do a binary search */
while (li < le) {
int m = (li + le)/2;
if (lua_getstack(L, m, &ar)) li = m + 1;
else le = m;
}
return le - 1;
}
static int findfield (lua_State *L, int objidx, int level) {
if (level == 0 || !lua_istable(L, -1))
return 0; /* not found */
lua_pushnil(L); /* start 'next' loop */
while (lua_next(L, -2)) { /* for each pair in table */
if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
if (lua_rawequal(L, objidx, -1)) { /* found object? */
lua_pop(L, 1); /* remove value (but keep name) */
return 1;
}
else if (findfield(L, objidx, level - 1)) { /* try recursively */
lua_remove(L, -2); /* remove table (but keep name) */
lua_pushliteral(L, ".");
lua_insert(L, -2); /* place '.' between the two names */
lua_concat(L, 3);
return 1;
}
}
lua_pop(L, 1); /* remove value */
}
return 0; /* not found */
}
static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
int top = lua_gettop(L);
lua_getinfo(L, "f", ar); /* push function */
lua_pushvalue(L, LUA_GLOBALSINDEX);
if (findfield(L, top + 1, 2)) {
lua_copy(L, -1, top + 1); /* move name to proper place */
lua_pop(L, 2); /* remove pushed values */
return 1;
}
else {
lua_settop(L, top); /* remove function and global table */
return 0;
}
}
static void pushfuncname (lua_State *L, lua_Debug *ar) {
if (*ar->namewhat != '\0') /* is there a name? */
lua_pushfstring(L, "function " LUA_QS, ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushliteral(L, "main chunk");
else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
}
else
lua_pushliteral(L, "?");
}
else
lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
}
#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */
void luaL_traceback (lua_State *L, lua_State *L1,
const char *msg, int level) {
lua_Debug ar;
int top = lua_gettop(L);
int numlevels = countlevels(L1);
int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
if (msg) lua_pushfstring(L, "%s\n", msg);
lua_pushliteral(L, "stack traceback:");
while (lua_getstack(L1, level++, &ar)) {
if (level == mark) { /* too many levels? */
lua_pushliteral(L, "\n\t..."); /* add a '...' */
level = numlevels - LEVELS2; /* and skip to last ones */
}
else {
lua_getinfo(L1, "Slnt", &ar);
lua_pushfstring(L, "\n\t%s:", ar.short_src);
if (ar.currentline > 0)
lua_pushfstring(L, "%d:", ar.currentline);
lua_pushliteral(L, " in ");
pushfuncname(L, &ar);
lua_concat(L, lua_gettop(L) - top);
}
}
lua_concat(L, lua_gettop(L) - top);
}
#endif
void luaL_checkversion (lua_State *L) {
(void)L;
}
#if !defined(COMPAT52_IS_LUAJIT)
int luaL_fileresult (lua_State *L, int stat, const char *fname) {
int en = errno; /* calls to Lua API may change this value */
if (stat) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
else
lua_pushstring(L, strerror(en));
lua_pushnumber(L, (lua_Number)en);
return 3;
}
}
#endif
#endif /* Lua 5.0 or Lua 5.1 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
#include <limits.h>
typedef LUAI_INT32 LUA_INT32;
/********************************************************************/
/* extract of 5.2's luaconf.h */
/* detects proper defines for faster unsigned<->number conversion */
/* see copyright notice at the end of this file */
/********************************************************************/
#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
#define LUA_WIN /* enable goodies for regular Windows platforms */
#endif
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
/* Microsoft compiler on a Pentium (32 bit) ? */
#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
#define LUA_MSASMTRICK
#define LUA_IEEEENDIAN 0
#define LUA_NANTRICK
/* pentium 32 bits? */
#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
#define LUA_IEEE754TRICK
#define LUA_IEEELL
#define LUA_IEEEENDIAN 0
#define LUA_NANTRICK
/* pentium 64 bits? */
#elif defined(__x86_64) /* }{ */
#define LUA_IEEE754TRICK
#define LUA_IEEEENDIAN 0
#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */
#define LUA_IEEE754TRICK
#define LUA_IEEEENDIAN 1
#else /* }{ */
/* assume IEEE754 and a 32-bit integer type */
#define LUA_IEEE754TRICK
#endif /* } */
#endif /* } */
/********************************************************************/
/* extract of 5.2's llimits.h */
/* gives us lua_number2unsigned and lua_unsigned2number */
/* see copyright notice at the end of this file */
/********************************************************************/
#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */
/* trick with Microsoft assembler for X86 */
#define lua_number2unsigned(i,n) \
{__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
#elif defined(LUA_IEEE754TRICK) /* }{ */
/* the next trick should work on any machine using IEEE754 with
a 32-bit int type */
union compat52_luai_Cast { double l_d; LUA_INT32 l_p[2]; };
#if !defined(LUA_IEEEENDIAN) /* { */
#define LUAI_EXTRAIEEE \
static const union compat52_luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33)
#else
#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN
#define LUAI_EXTRAIEEE /* empty */
#endif /* } */
#define lua_number2int32(i,n,t) \
{ LUAI_EXTRAIEEE \
volatile union compat52_luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
(i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned)
#endif /* } */
/* the following definitions always work, but may be slow */
#if !defined(lua_number2unsigned) /* { */
/* the following definition assures proper modulo behavior */
#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
#include <math.h>
#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
#define lua_number2unsigned(i,n) \
((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
#else
#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n))
#endif
#endif /* } */
#if !defined(lua_unsigned2number)
/* on several machines, coercion from unsigned to double is slow,
so it may be worth to avoid */
#define lua_unsigned2number(u) \
(((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
#endif
/********************************************************************/
static void compat52_call_lua (lua_State *L, char const code[], size_t len,
int nargs, int nret) {
lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
if (lua_type(L, -1) != LUA_TFUNCTION) {
lua_pop(L, 1);
if (luaL_loadbuffer(L, code, len, "=none"))
lua_error(L);
lua_pushvalue(L, -1);
lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
}
lua_insert(L, -nargs-1);
lua_call(L, nargs, nret);
}
static const char compat52_arith_code[] = {
'l', 'o', 'c', 'a', 'l', ' ', 'o', 'p', ',', 'a', ',', 'b',
'=', '.', '.', '.', '\n',
'i', 'f', ' ', 'o', 'p', '=', '=', '0', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '+', 'b', '\n',
'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '1', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '-', 'b', '\n',
'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '2', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '*', 'b', '\n',
'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '3', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '/', 'b', '\n',
'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '4', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '%', 'b', '\n',
'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '5', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '^', 'b', '\n',
'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '6', ' ',
't', 'h', 'e', 'n', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', '-', 'a', '\n',
'e', 'n', 'd', '\n', '\0'
};
void lua_arith (lua_State *L, int op) {
if (op < LUA_OPADD && op > LUA_OPUNM)
luaL_error(L, "invalid 'op' argument for lua_arith");
luaL_checkstack(L, 5, "not enough stack slots");
if (op == LUA_OPUNM)
lua_pushvalue(L, -1);
lua_pushnumber(L, op);
lua_insert(L, -3);
compat52_call_lua(L, compat52_arith_code,
sizeof(compat52_arith_code)-1, 3, 1);
}
static const char compat52_compare_code[] = {
'l', 'o', 'c', 'a', 'l', ' ', 'a', ',', 'b', '=', '.', '.', '.', '\n',
'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '<', '=', 'b', '\n', '\0'
};
int lua_compare (lua_State *L, int idx1, int idx2, int op) {
int result = 0;
switch (op) {
case LUA_OPEQ:
return lua_equal(L, idx1, idx2);
case LUA_OPLT:
return lua_lessthan(L, idx1, idx2);
case LUA_OPLE:
luaL_checkstack(L, 5, "not enough stack slots");
idx1 = lua_absindex(L, idx1);
idx2 = lua_absindex(L, idx2);
lua_pushvalue(L, idx1);
lua_pushvalue(L, idx2);
compat52_call_lua(L, (void*)compat52_compare_code,
sizeof(compat52_compare_code)-1, 2, 1);
result = lua_toboolean(L, -1);
lua_pop(L, 1);
return result;
default:
luaL_error(L, "invalid 'op' argument for lua_compare");
}
return 0;
}
void lua_pushunsigned (lua_State *L, lua_Unsigned n) {
lua_pushnumber(L, lua_unsigned2number(n));
}
lua_Unsigned luaL_checkunsigned (lua_State *L, int i) {
lua_Unsigned result;
lua_Number n = lua_tonumber(L, i);
if (n == 0 && !lua_isnumber(L, i))
luaL_checktype(L, i, LUA_TNUMBER);
lua_number2unsigned(result, n);
return result;
}
lua_Unsigned lua_tounsignedx (lua_State *L, int i, int *isnum) {
lua_Unsigned result;
lua_Number n = lua_tonumberx(L, i, isnum);
lua_number2unsigned(result, n);
return result;
}
lua_Unsigned luaL_optunsigned (lua_State *L, int i, lua_Unsigned def) {
return luaL_opt(L, luaL_checkunsigned, i, def);
}
lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum) {
lua_Integer n = lua_tointeger(L, i);
if (isnum != NULL) {
*isnum = (n != 0 || lua_isnumber(L, i));
}
return n;
}
void lua_len (lua_State *L, int i) {
switch (lua_type(L, i)) {
case LUA_TSTRING: /* fall through */
case LUA_TTABLE:
if (!luaL_callmeta(L, i, "__len"))
lua_pushnumber(L, (int)lua_objlen(L, i));
break;
case LUA_TUSERDATA:
if (luaL_callmeta(L, i, "__len"))
break;
/* maybe fall through */
default:
luaL_error(L, "attempt to get length of a %s value",
lua_typename(L, lua_type(L, i)));
}
}
int luaL_len (lua_State *L, int i) {
int res = 0, isnum = 0;
luaL_checkstack(L, 1, "not enough stack slots");
lua_len(L, i);
res = (int)lua_tointegerx(L, -1, &isnum);
lua_pop(L, 1);
if (!isnum)
luaL_error(L, "object length is not a number");
return res;
}
const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
if (!luaL_callmeta(L, idx, "__tostring")) {
int t = lua_type(L, idx);
switch (t) {
case LUA_TNIL:
lua_pushliteral(L, "nil");
break;
case LUA_TSTRING:
case LUA_TNUMBER:
lua_pushvalue(L, idx);
break;
case LUA_TBOOLEAN:
if (lua_toboolean(L, idx))
lua_pushliteral(L, "true");
else
lua_pushliteral(L, "false");
break;
default:
lua_pushfstring(L, "%s: %p", lua_typename(L, t),
lua_topointer(L, idx));
break;
}
}
return lua_tolstring(L, -1, len);
}
void luaL_requiref (lua_State *L, char const* modname,
lua_CFunction openf, int glb) {
luaL_checkstack(L, 3, "not enough stack slots");
lua_pushcfunction(L, openf);
lua_pushstring(L, modname);
lua_call(L, 1, 1);
lua_getglobal(L, "package");
lua_getfield(L, -1, "loaded");
lua_replace(L, -2);
lua_pushvalue(L, -2);
lua_setfield(L, -2, modname);
lua_pop(L, 1);
if (glb) {
lua_pushvalue(L, -1);
lua_setglobal(L, modname);
}
}
void luaL_buffinit (lua_State *L, luaL_Buffer_52 *B) {
/* make it crash if used via pointer to a 5.1-style luaL_Buffer */
B->b.p = NULL;
B->b.L = NULL;
B->b.lvl = 0;
/* reuse the buffer from the 5.1-style luaL_Buffer though! */
B->ptr = B->b.buffer;
B->capacity = LUAL_BUFFERSIZE;
B->nelems = 0;
B->L2 = L;
}
char *luaL_prepbuffsize (luaL_Buffer_52 *B, size_t s) {
if (B->capacity - B->nelems < s) { /* needs to grow */
char* newptr = NULL;
size_t newcap = B->capacity * 2;
if (newcap - B->nelems < s)
newcap = B->nelems + s;
if (newcap < B->capacity) /* overflow */
luaL_error(B->L2, "buffer too large");
newptr = lua_newuserdata(B->L2, newcap);
memcpy(newptr, B->ptr, B->nelems);
if (B->ptr != B->b.buffer)
lua_replace(B->L2, -2); /* remove old buffer */
B->ptr = newptr;
B->capacity = newcap;
}
return B->ptr+B->nelems;
}
void luaL_addlstring (luaL_Buffer_52 *B, const char *s, size_t l) {
memcpy(luaL_prepbuffsize(B, l), s, l);
luaL_addsize(B, l);
}
void luaL_addvalue (luaL_Buffer_52 *B) {
size_t len = 0;
const char *s = lua_tolstring(B->L2, -1, &len);
if (!s)
luaL_error(B->L2, "cannot convert value to string");
if (B->ptr != B->b.buffer)
lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
luaL_addlstring(B, s, len);
lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
}
void luaL_pushresult (luaL_Buffer_52 *B) {
lua_pushlstring(B->L2, B->ptr, B->nelems);
if (B->ptr != B->b.buffer)
lua_replace(B->L2, -2); /* remove userdata buffer */
}
#endif /* LUA_VERSION_NUM == 501 */
/*********************************************************************
* This file contains parts of Lua 5.2's source code:
*
* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/

168
src/lcurses/compat-5.2.h Normal file
View File

@ -0,0 +1,168 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "../lua.h"
#include "../lauxlib.h"
#include "../lualib.h"
#if !defined(LUA_VERSION_NUM)
/* Lua 5.0 */
#define LUA_QL(x) "'" x "'"
#define LUA_QS LUA_QL("%s")
#define luaL_Reg luaL_reg
#define luaL_opt(L, f, n, d) \
(lua_isnoneornil(L, n) ? (d) : f(L, n))
#define luaL_addchar(B,c) \
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))
#endif /* Lua 5.0 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
/* Lua 5.1 */
/* PUC-Rio Lua uses lconfig_h as include guard for luaconf.h,
* LuaJIT uses luaconf_h. If you use PUC-Rio's include files
* but LuaJIT's library, you will need to define the macro
* COMPAT52_IS_LUAJIT yourself! */
#if !defined(COMPAT52_IS_LUAJIT) && defined(luaconf_h)
#define COMPAT52_IS_LUAJIT
#endif
/* LuaJIT doesn't define these unofficial macros ... */
#if !defined(LUAI_INT32)
#include <limits.h>
#if INT_MAX-20 < 32760
#define LUAI_INT32 long
#define LUAI_UINT32 unsigned long
#elif INT_MAX > 2147483640L
#define LUAI_INT32 int
#define LUAI_UINT32 unsigned int
#else
#error "could not detect suitable lua_Unsigned datatype"
#endif
#endif
#define LUA_OPADD 0
#define LUA_OPSUB 1
#define LUA_OPMUL 2
#define LUA_OPDIV 3
#define LUA_OPMOD 4
#define LUA_OPPOW 5
#define LUA_OPUNM 6
#define LUA_OPEQ 0
#define LUA_OPLT 1
#define LUA_OPLE 2
typedef LUAI_UINT32 lua_Unsigned;
typedef struct luaL_Buffer_52 {
luaL_Buffer b; /* make incorrect code crash! */
char *ptr;
size_t nelems;
size_t capacity;
lua_State *L2;
} luaL_Buffer_52;
#define luaL_Buffer luaL_Buffer_52
typedef struct luaL_Stream {
FILE *f;
/* The following field is for LuaJIT which adds a uint32_t field
* to file handles. */
lua_Unsigned type;
lua_CFunction closef;
} luaL_Stream;
#define lua_tounsigned(L, i) lua_tounsignedx(L, i, NULL)
#define lua_rawlen(L, i) lua_objlen(L, i)
void lua_arith (lua_State *L, int op);
int lua_compare (lua_State *L, int idx1, int idx2, int op);
void lua_pushunsigned (lua_State *L, lua_Unsigned n);
lua_Unsigned luaL_checkunsigned (lua_State *L, int i);
lua_Unsigned lua_tounsignedx (lua_State *L, int i, int *isnum);
lua_Unsigned luaL_optunsigned (lua_State *L, int i, lua_Unsigned def);
lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum);
void lua_len (lua_State *L, int i);
int luaL_len (lua_State *L, int i);
const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
void luaL_requiref (lua_State *L, char const* modname, lua_CFunction openf, int glb);
#define luaL_buffinit luaL_buffinit_52
void luaL_buffinit (lua_State *L, luaL_Buffer_52 *B);
#define luaL_prepbuffsize luaL_prepbuffsize_52
char *luaL_prepbuffsize (luaL_Buffer_52 *B, size_t s);
#define luaL_addlstring luaL_addlstring_52
void luaL_addlstring (luaL_Buffer_52 *B, const char *s, size_t l);
#define luaL_addvalue luaL_addvalue_52
void luaL_addvalue (luaL_Buffer_52 *B);
#define luaL_pushresult luaL_pushresult_52
void luaL_pushresult (luaL_Buffer_52 *B);
#undef luaL_buffinitsize
#define luaL_buffinitsize(L, B, s) \
(luaL_buffinit(L, B), luaL_prepbuffsize(B, s))
#undef luaL_prepbuffer
#define luaL_prepbuffer(B) \
luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
#undef luaL_addchar
#define luaL_addchar(B, c) \
((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize(B, 1)), \
((B)->ptr[(B)->nelems++] = (c)))
#undef luaL_addsize
#define luaL_addsize(B, s) \
((B)->nelems += (s))
#undef luaL_addstring
#define luaL_addstring(B, s) \
luaL_addlstring(B, s, strlen(s))
#undef luaL_pushresultsize
#define luaL_pushresultsize(B, s) \
(luaL_addsize(B, s), luaL_pushresult(B))
#endif /* Lua 5.1 */
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501
/* Lua 5.0 *or* 5.1 */
#define LUA_OK 0
#define lua_pushglobaltable(L) \
lua_pushvalue(L, LUA_GLOBALSINDEX)
#define luaL_newlib(L, l) \
(lua_newtable((L)),luaL_setfuncs((L), (l), 0))
void luaL_checkversion (lua_State *L);
#endif /* Lua 5.0 *or* 5.1 */
int lua_absindex (lua_State *L, int i);
void lua_copy (lua_State *L, int from, int to);
void lua_rawgetp (lua_State *L, int i, const void *p);
void lua_rawsetp (lua_State *L, int i, const void *p);
void *luaL_testudata (lua_State *L, int i, const char *tname);
lua_Number lua_tonumberx (lua_State *L, int i, int *isnum);
void lua_getuservalue (lua_State *L, int i);
void lua_setuservalue (lua_State *L, int i);
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
void luaL_setmetatable (lua_State *L, const char *tname);
int luaL_getsubtable (lua_State *L, int i, const char *name);
void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level);
int luaL_fileresult (lua_State *L, int stat, const char *fname);

1555
src/lcurses/curses.c Normal file

File diff suppressed because it is too large Load Diff

58
src/lcurses/curses.lua Normal file
View File

@ -0,0 +1,58 @@
--- 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.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.getyx () return curses.stdscr():getyx() end
function M.keypad (b) return curses.stdscr():keypad(b) end
function M.move (y,x) return curses.stdscr():move(y,x) end
function M.refresh () return curses.stdscr():refresh() end
function M.timeout (t) return curses.stdscr():timeout(t) end
return M

76
src/lcurses/strlcpy.c Normal file
View File

@ -0,0 +1,76 @@
/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LCURSES_STRLCPY_C
#define LCURSES_STRLCPY_C 1
#ifndef HAVE_STRLCPY
#if defined LIBC_SCCS && ! defined lint
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
static size_t strlcpy(char *dst, const char *src, size_t siz);
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
static size_t strlcpy(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
#endif /* !HAVE_STRLCPY */
#endif /* !LCURSES_STRLCPY_C */

1940
src/lcurses/window.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ static const luaL_Reg lualibs[] = {
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_CURSESLIBNAME, luaopen_curses},
{LUA_CURSESLIBNAME, luaopen_curses_c},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};

View File

@ -650,6 +650,7 @@ static int pmain (lua_State *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");
lua_gc(L, LUA_GCRESTART, 0);
s->status = handle_luainit(L);
if (s->status != 0) return 0;

View File

@ -33,8 +33,8 @@ LUALIB_API int (luaopen_string) (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUALIB_API int (luaopen_math) (lua_State *L);
#define LUA_CURSESLIBNAME "curses"
LUALIB_API int (luaopen_curses) (lua_State *L);
#define LUA_CURSESLIBNAME "curses_c"
LUALIB_API int (luaopen_curses_c) (lua_State *L);
#define LUA_DBLIBNAME "debug"
LUALIB_API int (luaopen_debug) (lua_State *L);