209 lines
5.2 KiB
C
209 lines
5.2 KiB
C
/*
|
|
* 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 */
|
|
|
|
#ifdef __NetBSD__
|
|
#include <curses.h>
|
|
#else
|
|
#include <ncurses.h>
|
|
#endif
|
|
#include <term.h>
|
|
|
|
#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*/
|