|
Packit |
437b5e |
/*
|
|
Packit |
437b5e |
* POSIX library for Lua 5.1, 5.2 & 5.3.
|
|
Packit |
437b5e |
* (c) Gary V. Vaughan <gary@vaughan.pe>, 2013-2015
|
|
Packit |
437b5e |
* (c) Reuben Thomas <rrt@sc3d.org> 2010-2013
|
|
Packit |
437b5e |
* (c) Natanael Copa <natanael.copa@gmail.com> 2008-2010
|
|
Packit |
437b5e |
* Clean up and bug fixes by Leo Razoumov <slonik.az@gmail.com> 2006-10-11
|
|
Packit |
437b5e |
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> 07 Apr 2006 23:17:49
|
|
Packit |
437b5e |
* Based on original by Claudio Terra for Lua 3.x.
|
|
Packit |
437b5e |
* With contributions by Roberto Ierusalimschy.
|
|
Packit |
437b5e |
* With documentation from Steve Donovan 2012
|
|
Packit |
437b5e |
*/
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#ifndef LUAPOSIX__HELPERS_C
|
|
Packit |
437b5e |
#define LUAPOSIX__HELPERS_C 1
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <config.h>
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include <errno.h>
|
|
Packit |
437b5e |
#include <grp.h>
|
|
Packit |
437b5e |
#include <pwd.h>
|
|
Packit |
437b5e |
#include <stdlib.h>
|
|
Packit |
437b5e |
#include <string.h>
|
|
Packit |
437b5e |
#include <sys/stat.h>
|
|
Packit |
437b5e |
#include <unistd.h> /* for _POSIX_VERSION */
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if HAVE_CURSES
|
|
Packit |
437b5e |
# if HAVE_NCURSESW_CURSES_H
|
|
Packit |
437b5e |
# include <ncursesw/curses.h>
|
|
Packit |
437b5e |
# elif HAVE_NCURSESW_H
|
|
Packit |
437b5e |
# include <ncursesw.h>
|
|
Packit |
437b5e |
# elif HAVE_NCURSES_CURSES_H
|
|
Packit |
437b5e |
# include <ncurses/curses.h>
|
|
Packit |
437b5e |
# elif HAVE_NCURSES_H
|
|
Packit |
437b5e |
# include <ncurses.h>
|
|
Packit |
437b5e |
# elif HAVE_CURSES_H
|
|
Packit |
437b5e |
# include <curses.h>
|
|
Packit |
437b5e |
# endif
|
|
Packit |
437b5e |
#include <term.h>
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Some systems set _POSIX_C_SOURCE over _POSIX_VERSION! */
|
|
Packit |
437b5e |
#if _POSIX_C_SOURCE >= 200112L || _POSIX_VERSION >= 200112L || _XOPEN_SOURCE >= 600
|
|
Packit |
437b5e |
# define LPOSIX_2001_COMPLIANT 1
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
|
|
Packit |
437b5e |
# define LPOSIX_2008_COMPLIANT 1
|
|
Packit |
437b5e |
# ifndef LPOSIX_2001_COMPLIANT
|
|
Packit |
437b5e |
# define LPOSIX_2001_COMPLIANT
|
|
Packit |
437b5e |
# endif
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* NetBSD's default curses implementation is not quite complete. This
|
|
Packit |
437b5e |
disables those missing functions unless linked to ncurses instead. */
|
|
Packit |
437b5e |
#if defined NCURSES_VERSION || !defined __NetBSD__
|
|
Packit |
437b5e |
# define LPOSIX_CURSES_COMPLIANT 1
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#include "lua.h"
|
|
Packit |
437b5e |
#include "lualib.h"
|
|
Packit |
437b5e |
#include "lauxlib.h"
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if LUA_VERSION_NUM < 503
|
|
Packit |
437b5e |
# define lua_isinteger lua_isnumber
|
|
Packit |
437b5e |
# if LUA_VERSION_NUM == 501
|
|
Packit |
437b5e |
# include "compat-5.2.c"
|
|
Packit |
437b5e |
# endif
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503
|
|
Packit |
437b5e |
# define lua_objlen lua_rawlen
|
|
Packit |
437b5e |
# define lua_strlen lua_rawlen
|
|
Packit |
437b5e |
# define luaL_openlib(L,n,l,nup) luaL_setfuncs((L),(l),(nup))
|
|
Packit |
437b5e |
# define luaL_register(L,n,l) (luaL_newlib(L,l))
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#ifndef STREQ
|
|
Packit |
437b5e |
# define STREQ(a, b) (strcmp (a, b) == 0)
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Mark unused parameters required only to match a function type
|
|
Packit |
437b5e |
specification. */
|
|
Packit |
437b5e |
#ifdef __GNUC__
|
|
Packit |
437b5e |
# define LPOSIX_UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
|
|
Packit |
437b5e |
#else
|
|
Packit |
437b5e |
# define LPOSIX_UNUSED(x) UNUSED_ ## x
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* LPOSIX_STMT_BEG/END are used to create macros that expand to a
|
|
Packit |
437b5e |
single compound statement in a portable way. */
|
|
Packit |
437b5e |
#if defined __GNUC__ && !defined __STRICT_ANSI__ && !defined __cplusplus
|
|
Packit |
437b5e |
# define LPOSIX_STMT_BEG (void)(
|
|
Packit |
437b5e |
# define LPOSIX_STMT_END )
|
|
Packit |
437b5e |
#else
|
|
Packit |
437b5e |
# if (defined sun || defined __sun__)
|
|
Packit |
437b5e |
# define LPOSIX_STMT_BEG if (1)
|
|
Packit |
437b5e |
# define LPOSIX_STMT_END else (void)0
|
|
Packit |
437b5e |
# else
|
|
Packit |
437b5e |
# define LPOSIX_STMT_BEG do
|
|
Packit |
437b5e |
# define LPOSIX_STMT_END while (0)
|
|
Packit |
437b5e |
# endif
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* The extra indirection to these macros is required so that if the
|
|
Packit |
437b5e |
arguments are themselves macros, they will get expanded too. */
|
|
Packit |
437b5e |
#define LPOSIX__SPLICE(_s, _t) _s##_t
|
|
Packit |
437b5e |
#define LPOSIX_SPLICE(_s, _t) LPOSIX__SPLICE(_s, _t)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define LPOSIX__STR(_s) #_s
|
|
Packit |
437b5e |
#define LPOSIX_STR(_s) LPOSIX__STR(_s)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* The +1 is to step over the leading '_' that is required to prevent
|
|
Packit |
437b5e |
premature expansion of MENTRY arguments if we didn't add it. */
|
|
Packit |
437b5e |
#define LPOSIX__STR_1(_s) (#_s + 1)
|
|
Packit |
437b5e |
#define LPOSIX_STR_1(_s) LPOSIX__STR_1(_s)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define LPOSIX_CONST(_f) LPOSIX_STMT_BEG { \
|
|
Packit |
437b5e |
lua_pushinteger(L, _f); \
|
|
Packit |
437b5e |
lua_setfield(L, -2, #_f); \
|
|
Packit |
437b5e |
} LPOSIX_STMT_END
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define LPOSIX_FUNC(_s) {LPOSIX_STR_1(_s), (_s)}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushokresult(b) pushboolresult((int) (b) == OK)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#ifndef errno
|
|
Packit |
437b5e |
extern int errno;
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* ========================= *
|
|
Packit |
437b5e |
* Bad argument diagnostics. *
|
|
Packit |
437b5e |
* ========================= */
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
argtypeerror(lua_State *L, int narg, const char *expected)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *got = luaL_typename(L, narg);
|
|
Packit |
437b5e |
return luaL_argerror(L, narg,
|
|
Packit |
437b5e |
lua_pushfstring(L, "%s expected, got %s", expected, got));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static void
|
|
Packit |
437b5e |
checktype(lua_State *L, int narg, int t, const char *expected)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_type(L, narg) != t)
|
|
Packit |
437b5e |
argtypeerror (L, narg, expected);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static lua_Integer
|
|
Packit |
437b5e |
checkinteger(lua_State *L, int narg, const char *expected)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_Integer d = lua_tointeger(L, narg);
|
|
Packit |
437b5e |
if (d == 0 && !lua_isinteger(L, narg))
|
|
Packit |
437b5e |
argtypeerror(L, narg, expected);
|
|
Packit |
437b5e |
return d;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
checkint(lua_State *L, int narg)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
return (int)checkinteger(L, narg, "int");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static long
|
|
Packit |
437b5e |
checklong(lua_State *L, int narg)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
return (long)checkinteger(L, narg, "int");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#if HAVE_CURSES
|
|
Packit |
437b5e |
static chtype
|
|
Packit |
437b5e |
checkch(lua_State *L, int narg)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_isnumber(L, narg))
|
|
Packit |
437b5e |
return (chtype)checkint(L, narg);
|
|
Packit |
437b5e |
if (lua_isstring(L, narg))
|
|
Packit |
437b5e |
return *lua_tostring(L, narg);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
return argtypeerror(L, narg, "int or char");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static chtype
|
|
Packit |
437b5e |
optch(lua_State *L, int narg, chtype def)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, narg))
|
|
Packit |
437b5e |
return def;
|
|
Packit |
437b5e |
if (lua_isnumber(L, narg) || lua_isstring(L, narg))
|
|
Packit |
437b5e |
return checkch(L, narg);
|
|
Packit |
437b5e |
return argtypeerror(L, narg, "int or char or nil");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#endif
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
optboolean(lua_State *L, int narg, int def)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, narg))
|
|
Packit |
437b5e |
return def;
|
|
Packit |
437b5e |
checktype (L, narg, LUA_TBOOLEAN, "boolean or nil");
|
|
Packit |
437b5e |
return (int)lua_toboolean(L, narg);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
optint(lua_State *L, int narg, lua_Integer def)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, narg))
|
|
Packit |
437b5e |
return (int) def;
|
|
Packit |
437b5e |
return (int)checkinteger(L, narg, "int or nil");
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const char *
|
|
Packit |
437b5e |
optstring(lua_State *L, int narg, const char *def)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *s;
|
|
Packit |
437b5e |
if (lua_isnoneornil(L, narg))
|
|
Packit |
437b5e |
return def;
|
|
Packit |
437b5e |
s = lua_tolstring(L, narg, NULL);
|
|
Packit |
437b5e |
if (!s)
|
|
Packit |
437b5e |
argtypeerror(L, narg, "string or nil");
|
|
Packit |
437b5e |
return s;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static void
|
|
Packit |
437b5e |
checknargs(lua_State *L, int maxargs)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int nargs = lua_gettop(L);
|
|
Packit |
437b5e |
lua_pushfstring(L, "no more than %d argument%s expected, got %d",
|
|
Packit |
437b5e |
maxargs, maxargs == 1 ? "" : "s", nargs);
|
|
Packit |
437b5e |
luaL_argcheck(L, nargs <= maxargs, maxargs + 1, lua_tostring (L, -1));
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Try a lua_getfield from the table on the given index. On success the field
|
|
Packit |
437b5e |
* is pushed and 0 is returned, on failure nil and an error message is pushed and 2
|
|
Packit |
437b5e |
* is returned */
|
|
Packit |
437b5e |
static void
|
|
Packit |
437b5e |
checkfieldtype(lua_State *L, int index, const char *k, int expect_type, const char *expected)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int got_type;
|
|
Packit |
437b5e |
lua_getfield(L, index, k);
|
|
Packit |
437b5e |
got_type = lua_type(L, -1);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
if (expected == NULL)
|
|
Packit |
437b5e |
expected = lua_typename(L, expect_type);
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
lua_pushfstring(L, "%s expected for field '%s', got %s",
|
|
Packit |
437b5e |
expected, k, got_type == LUA_TNIL ? "no value" : lua_typename(L, got_type));
|
|
Packit |
437b5e |
luaL_argcheck(L, got_type == expect_type, index, lua_tostring(L, -1));
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define NEXT_IKEY -2
|
|
Packit |
437b5e |
#define NEXT_IVALUE -1
|
|
Packit |
437b5e |
static void
|
|
Packit |
437b5e |
checkismember(lua_State *L, int index, int n, const char *const S[])
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
/* Diagnose non-string type field names. */
|
|
Packit |
437b5e |
int got_type = lua_type(L, NEXT_IKEY);
|
|
Packit |
437b5e |
luaL_argcheck(L, lua_isstring(L, NEXT_IKEY), index,
|
|
Packit |
437b5e |
lua_pushfstring(L, "invalid %s field name", lua_typename(L, got_type)));
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Check field name is listed in S. */
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *k = lua_tostring(L, NEXT_IKEY);
|
|
Packit |
437b5e |
int i;
|
|
Packit |
437b5e |
for (i = 0; i < n; ++i)
|
|
Packit |
437b5e |
if (STREQ(S[i], k)) return;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* Diagnose invalid field name. */
|
|
Packit |
437b5e |
luaL_argcheck(L, 0, index,
|
|
Packit |
437b5e |
lua_pushfstring(L, "invalid field name '%s'", lua_tostring(L, NEXT_IKEY)));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#undef NEXT_IKEY
|
|
Packit |
437b5e |
#undef NEXT_IVALUE
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static void
|
|
Packit |
437b5e |
checkfieldnames(lua_State *L, int index, int n, const char * const S[])
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1))
|
|
Packit |
437b5e |
checkismember(L, index, n, S);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
#define checkfieldnames(L,i,S) (checkfieldnames)(L,i,sizeof(S)/sizeof(*S),S)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
checkintfield(lua_State *L, int index, const char *k)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int r;
|
|
Packit |
437b5e |
checkfieldtype(L, index, k, LUA_TNUMBER, "int");
|
|
Packit |
437b5e |
r = lua_tointeger(L, -1);
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
return r;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
checknumberfield(lua_State *L, int index, const char *k)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int r;
|
|
Packit |
437b5e |
checkfieldtype(L, index, k, LUA_TNUMBER, "number");
|
|
Packit |
437b5e |
r = lua_tonumber(L, -1);
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
return r;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const char *
|
|
Packit |
437b5e |
checkstringfield(lua_State *L, int index, const char *k)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *r;
|
|
Packit |
437b5e |
checkfieldtype(L, index, k, LUA_TSTRING, NULL);
|
|
Packit |
437b5e |
r = lua_tostring(L, -1);
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
return r;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
optintfield(lua_State *L, int index, const char *k, int def)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
int got_type;
|
|
Packit |
437b5e |
lua_getfield(L, index, k);
|
|
Packit |
437b5e |
got_type = lua_type(L, -1);
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
if (got_type == LUA_TNONE || got_type == LUA_TNIL)
|
|
Packit |
437b5e |
return def;
|
|
Packit |
437b5e |
return checkintfield(L, index, k);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static const char *
|
|
Packit |
437b5e |
optstringfield(lua_State *L, int index, const char *k, const char *def)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
const char *r;
|
|
Packit |
437b5e |
int got_type;
|
|
Packit |
437b5e |
got_type = lua_type(L, -1);
|
|
Packit |
437b5e |
lua_pop(L, 1);
|
|
Packit |
437b5e |
if (got_type == LUA_TNONE || got_type == LUA_TNIL)
|
|
Packit |
437b5e |
return def;
|
|
Packit |
437b5e |
return checkstringfield(L, index, k);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
pusherror(lua_State *L, const char *info)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushnil(L);
|
|
Packit |
437b5e |
if (info==NULL)
|
|
Packit |
437b5e |
lua_pushstring(L, strerror(errno));
|
|
Packit |
437b5e |
else
|
|
Packit |
437b5e |
lua_pushfstring(L, "%s: %s", info, strerror(errno));
|
|
Packit |
437b5e |
lua_pushinteger(L, errno);
|
|
Packit |
437b5e |
return 3;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushboolresult(b) (lua_pushboolean(L, (b)), 1)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushintresult(n) (lua_pushinteger(L, (n)), 1)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushstringresult(s) (lua_pushstring(L, (s)), 1)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
pushresult(lua_State *L, int i, const char *info)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
if (i==-1)
|
|
Packit |
437b5e |
return pusherror(L, info);
|
|
Packit |
437b5e |
return pushintresult(i);
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static void
|
|
Packit |
437b5e |
badoption(lua_State *L, int i, const char *what, int option)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
luaL_argerror(L, i,
|
|
Packit |
437b5e |
lua_pushfstring(L, "invalid %s option '%c'", what, option));
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
/* ================== *
|
|
Packit |
437b5e |
* Utility functions. *
|
|
Packit |
437b5e |
* ================== */
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
static int
|
|
Packit |
437b5e |
binding_notimplemented(lua_State *L, const char *fname, const char *libname)
|
|
Packit |
437b5e |
{
|
|
Packit |
437b5e |
lua_pushnil(L);
|
|
Packit |
437b5e |
lua_pushfstring(L, "'%s' is not implemented by host %s library",
|
|
Packit |
437b5e |
fname, libname);
|
|
Packit |
437b5e |
return 2;
|
|
Packit |
437b5e |
}
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushintegerfield(k,v) LPOSIX_STMT_BEG { \
|
|
Packit |
437b5e |
lua_pushinteger(L, (lua_Integer) v); lua_setfield(L, -2, k); \
|
|
Packit |
437b5e |
} LPOSIX_STMT_END
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushnumberfield(k,v) LPOSIX_STMT_BEG { \
|
|
Packit |
437b5e |
lua_pushnumber(L, (lua_Number) v); lua_setfield(L, -2, k); \
|
|
Packit |
437b5e |
} LPOSIX_STMT_END
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushstringfield(k,v) LPOSIX_STMT_BEG { \
|
|
Packit |
437b5e |
if (v) { \
|
|
Packit |
437b5e |
lua_pushstring(L, (const char *) v); \
|
|
Packit |
437b5e |
lua_setfield(L, -2, k); \
|
|
Packit |
437b5e |
} \
|
|
Packit |
437b5e |
} LPOSIX_STMT_END
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define pushliteralfield(k,v) LPOSIX_STMT_BEG { \
|
|
Packit |
437b5e |
if (v) { \
|
|
Packit |
437b5e |
lua_pushliteral(L, v); \
|
|
Packit |
437b5e |
lua_setfield(L, -2, k); \
|
|
Packit |
437b5e |
} \
|
|
Packit |
437b5e |
} LPOSIX_STMT_END
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define settypemetatable(t) LPOSIX_STMT_BEG { \
|
|
Packit |
437b5e |
if (luaL_newmetatable(L, t) == 1) \
|
|
Packit |
437b5e |
pushliteralfield("_type", t); \
|
|
Packit |
437b5e |
lua_setmetatable(L, -2); \
|
|
Packit |
437b5e |
} LPOSIX_STMT_END
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#define setintegerfield(_p, _n) pushintegerfield(LPOSIX_STR(_n), _p->_n)
|
|
Packit |
437b5e |
#define setnumberfield(_p, _n) pushnumberfield(LPOSIX_STR(_n), _p->_n)
|
|
Packit |
437b5e |
#define setstringfield(_p, _n) pushstringfield(LPOSIX_STR(_n), _p->_n)
|
|
Packit |
437b5e |
|
|
Packit |
437b5e |
#endif /*LUAPOSIX__HELPERS_C*/
|