summaryrefslogtreecommitdiff
path: root/uvim/src/if_lua.c
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-04 12:41:27 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-04 12:41:27 +0300
commit4f2d36194b4f299aa7509d815c07121039ea833b (patch)
treef3ded014bad3a4c76ff6a22b8726ebaab68c3d13 /uvim/src/if_lua.c
parent5b578e70c314723a3cde5c9bfc2be0bf1dadc93b (diff)
downloadProject-Tick-4f2d36194b4f299aa7509d815c07121039ea833b.tar.gz
Project-Tick-4f2d36194b4f299aa7509d815c07121039ea833b.zip
NOISSUE change uvim folder name to mnv
Signed-off-by: Mehmet Samet Duman <yongdohyun@projecttick.org>
Diffstat (limited to 'uvim/src/if_lua.c')
-rw-r--r--uvim/src/if_lua.c2835
1 files changed, 0 insertions, 2835 deletions
diff --git a/uvim/src/if_lua.c b/uvim/src/if_lua.c
deleted file mode 100644
index 9443f0c3ae..0000000000
--- a/uvim/src/if_lua.c
+++ /dev/null
@@ -1,2835 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4 noet:
- *
- * MNV - MNV is not Vim by Bram Moolenaar
- *
- * Lua interface by Luis Carvalho
- *
- * Do ":help uganda" in MNV to read copying and usage conditions.
- * Do ":help credits" in MNV to see a list of people who contributed.
- * See README.txt for an overview of the MNV source code.
- */
-
-#include "mnv.h"
-#include "version.h"
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#if __STDC_VERSION__ >= 199901L
-# define LUAV_INLINE inline
-#else
-# define LUAV_INLINE
-#endif
-
-// Only do the following when the feature is enabled. Needed for "make
-// depend".
-#if defined(FEAT_LUA)
-
-# define LUAMNV_CHUNKNAME "mnv chunk"
-# define LUAMNV_NAME "mnv"
-# define LUAMNV_EVALNAME "luaeval"
-# define LUAMNV_EVALHEADER "local _A=select(1,...) return "
-
-# ifdef LUA_RELEASE
-# define LUAMNV_VERSION LUA_RELEASE
-# else
-# define LUAMNV_VERSION LUA_VERSION
-# endif
-
-typedef buf_T *luaV_Buffer;
-typedef win_T *luaV_Window;
-typedef dict_T *luaV_Dict;
-typedef list_T *luaV_List;
-typedef blob_T *luaV_Blob;
-typedef struct {
- char_u *name; // funcref
- dict_T *self; // selfdict
-} luaV_Funcref;
-typedef int (*msgfunc_T)(char *);
-
-typedef struct {
- int lua_funcref; // ref to a lua func
- int lua_tableref; // ref to a lua table if metatable else LUA_NOREF. used
- // for __call
- lua_State *L;
-} luaV_CFuncState;
-
-static const char LUAMNV_DICT[] = "dict";
-static const char LUAMNV_LIST[] = "list";
-static const char LUAMNV_BLOB[] = "blob";
-static const char LUAMNV_FUNCREF[] = "funcref";
-static const char LUAMNV_BUFFER[] = "buffer";
-static const char LUAMNV_WINDOW[] = "window";
-static const char LUAMNV_FREE[] = "luaV_free";
-static const char LUAMNV_LUAEVAL[] = "luaV_luaeval";
-static const char LUAMNV_SETREF[] = "luaV_setref";
-
-static const char LUA___CALL[] = "__call";
-
-// get/setudata manage references to mnv userdata in a cache table through
-// object pointers (light userdata). The cache table itself is retrieved
-// from the registry.
-
-static const char LUAMNV_UDATA_CACHE[] = "luaV_udata_cache";
-
-# define luaV_getfield(L, s) \
- lua_pushlightuserdata((L), (void *)(s)); \
- lua_rawget((L), LUA_REGISTRYINDEX)
-# define luaV_checksandbox(L) \
- if (sandbox) luaL_error((L), "not allowed in sandbox")
-# define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
-# define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
-# define luaV_checktypval(L, a, v, msg) \
- do { \
- if (luaV_totypval(L, a, v) == FAIL) \
- luaL_error(L, msg ": cannot convert value"); \
- } while (0)
-
-static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
-static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
-static luaV_Blob *luaV_pushblob(lua_State *L, blob_T *blo);
-static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
-static int luaV_call_lua_func(int argcount, typval_T *argvars, typval_T *rettv, void *state);
-static void luaV_call_lua_func_free(void *state);
-
-# if LUA_VERSION_NUM <= 501
-# define luaV_register(L, l) luaL_register(L, NULL, l)
-# define luaL_typeerror luaL_typerror
-# else
-# define luaV_register(L, l) luaL_setfuncs(L, l, 0)
-# endif
-
-# ifdef DYNAMIC_LUA
-
-# ifdef MSWIN
-# define load_dll mnvLoadLib
-# define symbol_from_dll GetProcAddress
-# define close_dll FreeLibrary
-# define load_dll_error GetWin32Error
-# else
-# include <dlfcn.h>
-# define HANDLE void*
-# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
-# define symbol_from_dll dlsym
-# define close_dll dlclose
-# define load_dll_error dlerror
-# endif
-
-// lauxlib
-# if LUA_VERSION_NUM <= 501
-# define luaL_register dll_luaL_register
-# define luaL_prepbuffer dll_luaL_prepbuffer
-# define luaL_openlib dll_luaL_openlib
-# define luaL_typerror dll_luaL_typerror
-# define luaL_loadfile dll_luaL_loadfile
-# define luaL_loadbuffer dll_luaL_loadbuffer
-# else
-# define luaL_prepbuffsize dll_luaL_prepbuffsize
-# define luaL_setfuncs dll_luaL_setfuncs
-# define luaL_loadfilex dll_luaL_loadfilex
-# define luaL_loadbufferx dll_luaL_loadbufferx
-# define luaL_argerror dll_luaL_argerror
-# endif
-# if LUA_VERSION_NUM >= 504
-# define luaL_typeerror dll_luaL_typeerror
-# endif
-# define luaL_checkany dll_luaL_checkany
-# define luaL_checklstring dll_luaL_checklstring
-# define luaL_checkinteger dll_luaL_checkinteger
-# define luaL_optinteger dll_luaL_optinteger
-# define luaL_checktype dll_luaL_checktype
-# define luaL_error dll_luaL_error
-# define luaL_newstate dll_luaL_newstate
-# define luaL_buffinit dll_luaL_buffinit
-# define luaL_addlstring dll_luaL_addlstring
-# define luaL_pushresult dll_luaL_pushresult
-# define luaL_loadstring dll_luaL_loadstring
-# define luaL_ref dll_luaL_ref
-# define luaL_unref dll_luaL_unref
-// lua
-# if LUA_VERSION_NUM <= 501
-# define lua_tonumber dll_lua_tonumber
-# define lua_tointeger dll_lua_tointeger
-# define lua_call dll_lua_call
-# define lua_pcall dll_lua_pcall
-# else
-# define lua_tonumberx dll_lua_tonumberx
-# define lua_tointegerx dll_lua_tointegerx
-# define lua_callk dll_lua_callk
-# define lua_pcallk dll_lua_pcallk
-# define lua_getglobal dll_lua_getglobal
-# define lua_setglobal dll_lua_setglobal
-# endif
-# if LUA_VERSION_NUM <= 502
-# define lua_replace dll_lua_replace
-# define lua_remove dll_lua_remove
-# endif
-# if LUA_VERSION_NUM >= 503
-# define lua_rotate dll_lua_rotate
-# define lua_copy dll_lua_copy
-# endif
-# define lua_typename dll_lua_typename
-# define lua_close dll_lua_close
-# define lua_gettop dll_lua_gettop
-# define lua_settop dll_lua_settop
-# define lua_pushvalue dll_lua_pushvalue
-# define lua_isnumber dll_lua_isnumber
-# define lua_isstring dll_lua_isstring
-# define lua_type dll_lua_type
-# define lua_rawequal dll_lua_rawequal
-# define lua_toboolean dll_lua_toboolean
-# define lua_tolstring dll_lua_tolstring
-# define lua_touserdata dll_lua_touserdata
-# define lua_pushnil dll_lua_pushnil
-# define lua_pushnumber dll_lua_pushnumber
-# define lua_pushinteger dll_lua_pushinteger
-# define lua_pushlstring dll_lua_pushlstring
-# define lua_pushstring dll_lua_pushstring
-# define lua_pushfstring dll_lua_pushfstring
-# define lua_pushcclosure dll_lua_pushcclosure
-# define lua_pushboolean dll_lua_pushboolean
-# define lua_pushlightuserdata dll_lua_pushlightuserdata
-# define lua_getfield dll_lua_getfield
-# define lua_rawget dll_lua_rawget
-# define lua_rawgeti dll_lua_rawgeti
-# define lua_createtable dll_lua_createtable
-# define lua_settable dll_lua_settable
-# if LUA_VERSION_NUM >= 504
-# define lua_newuserdatauv dll_lua_newuserdatauv
-# else
-# define lua_newuserdata dll_lua_newuserdata
-# endif
-# define lua_getmetatable dll_lua_getmetatable
-# define lua_setfield dll_lua_setfield
-# define lua_rawset dll_lua_rawset
-# define lua_rawseti dll_lua_rawseti
-# define lua_setmetatable dll_lua_setmetatable
-# define lua_next dll_lua_next
-// libs
-# define luaopen_base dll_luaopen_base
-# define luaopen_table dll_luaopen_table
-# define luaopen_string dll_luaopen_string
-# define luaopen_math dll_luaopen_math
-# define luaopen_io dll_luaopen_io
-# define luaopen_os dll_luaopen_os
-# define luaopen_package dll_luaopen_package
-# define luaopen_debug dll_luaopen_debug
-# define luaL_openlibs dll_luaL_openlibs
-
-// lauxlib
-# if LUA_VERSION_NUM <= 501
-void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
-char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
-void (*dll_luaL_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
-int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
-int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
-int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
-# else
-char *(*dll_luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
-void (*dll_luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
-int (*dll_luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
-int (*dll_luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
-int (*dll_luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
-# endif
-# if LUA_VERSION_NUM >= 504
-int (*dll_luaL_typeerror) (lua_State *L, int narg, const char *tname);
-# endif
-void (*dll_luaL_checkany) (lua_State *L, int narg);
-const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
-lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
-lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
-void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
-int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
-lua_State *(*dll_luaL_newstate) (void);
-void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
-void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
-void (*dll_luaL_pushresult) (luaL_Buffer *B);
-int (*dll_luaL_loadstring) (lua_State *L, const char *s);
-int (*dll_luaL_ref) (lua_State *L, int idx);
-# if LUA_VERSION_NUM <= 502
-void (*dll_luaL_unref) (lua_State *L, int idx, int n);
-# else
-void (*dll_luaL_unref) (lua_State *L, int idx, lua_Integer n);
-# endif
-// lua
-# if LUA_VERSION_NUM <= 501
-lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
-lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
-void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
-int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
-# else
-lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
-lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
-void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
- lua_CFunction k);
-int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
- int ctx, lua_CFunction k);
-void (*dll_lua_getglobal) (lua_State *L, const char *var);
-void (*dll_lua_setglobal) (lua_State *L, const char *var);
-# endif
-# if LUA_VERSION_NUM <= 502
-void (*dll_lua_replace) (lua_State *L, int idx);
-void (*dll_lua_remove) (lua_State *L, int idx);
-# endif
-# if LUA_VERSION_NUM >= 503
-void (*dll_lua_rotate) (lua_State *L, int idx, int n);
-void (*dll_lua_copy) (lua_State *L, int fromidx, int toidx);
-# endif
-const char *(*dll_lua_typename) (lua_State *L, int tp);
-void (*dll_lua_close) (lua_State *L);
-int (*dll_lua_gettop) (lua_State *L);
-void (*dll_lua_settop) (lua_State *L, int idx);
-void (*dll_lua_pushvalue) (lua_State *L, int idx);
-int (*dll_lua_isnumber) (lua_State *L, int idx);
-int (*dll_lua_isstring) (lua_State *L, int idx);
-int (*dll_lua_type) (lua_State *L, int idx);
-int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
-int (*dll_lua_toboolean) (lua_State *L, int idx);
-const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
-void *(*dll_lua_touserdata) (lua_State *L, int idx);
-void (*dll_lua_pushnil) (lua_State *L);
-void (*dll_lua_pushnumber) (lua_State *L, lua_Number n);
-void (*dll_lua_pushinteger) (lua_State *L, lua_Integer n);
-void (*dll_lua_pushlstring) (lua_State *L, const char *s, size_t l);
-void (*dll_lua_pushstring) (lua_State *L, const char *s);
-const char *(*dll_lua_pushfstring) (lua_State *L, const char *fmt, ...);
-void (*dll_lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
-void (*dll_lua_pushboolean) (lua_State *L, int b);
-void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
-void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
-# if LUA_VERSION_NUM <= 502
-void (*dll_lua_rawget) (lua_State *L, int idx);
-void (*dll_lua_rawgeti) (lua_State *L, int idx, int n);
-# else
-int (*dll_lua_rawget) (lua_State *L, int idx);
-int (*dll_lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
-# endif
-void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
-void (*dll_lua_settable) (lua_State *L, int idx);
-# if LUA_VERSION_NUM >= 504
-void *(*dll_lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue);
-# else
-void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
-# endif
-int (*dll_lua_getmetatable) (lua_State *L, int objindex);
-void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
-void (*dll_lua_rawset) (lua_State *L, int idx);
-# if LUA_VERSION_NUM <= 502
-void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
-# else
-void (*dll_lua_rawseti) (lua_State *L, int idx, lua_Integer n);
-# endif
-int (*dll_lua_setmetatable) (lua_State *L, int objindex);
-int (*dll_lua_next) (lua_State *L, int idx);
-// libs
-int (*dll_luaopen_base) (lua_State *L);
-int (*dll_luaopen_table) (lua_State *L);
-int (*dll_luaopen_string) (lua_State *L);
-int (*dll_luaopen_math) (lua_State *L);
-int (*dll_luaopen_io) (lua_State *L);
-int (*dll_luaopen_os) (lua_State *L);
-int (*dll_luaopen_package) (lua_State *L);
-int (*dll_luaopen_debug) (lua_State *L);
-void (*dll_luaL_openlibs) (lua_State *L);
-
-typedef void **luaV_function;
-typedef struct {
- const char *name;
- luaV_function func;
-} luaV_Reg;
-
-static const luaV_Reg luaV_dll[] = {
- // lauxlib
-# if LUA_VERSION_NUM <= 501
- {"luaL_register", (luaV_function) &dll_luaL_register},
- {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
- {"luaL_openlib", (luaV_function) &dll_luaL_openlib},
- {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
- {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
- {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
-# else
- {"luaL_prepbuffsize", (luaV_function) &dll_luaL_prepbuffsize},
- {"luaL_setfuncs", (luaV_function) &dll_luaL_setfuncs},
- {"luaL_loadfilex", (luaV_function) &dll_luaL_loadfilex},
- {"luaL_loadbufferx", (luaV_function) &dll_luaL_loadbufferx},
- {"luaL_argerror", (luaV_function) &dll_luaL_argerror},
-# endif
-# if LUA_VERSION_NUM >= 504
- {"luaL_typeerror", (luaV_function) &dll_luaL_typeerror},
-# endif
- {"luaL_checkany", (luaV_function) &dll_luaL_checkany},
- {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
- {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
- {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
- {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
- {"luaL_error", (luaV_function) &dll_luaL_error},
- {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
- {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
- {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
- {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
- {"luaL_loadstring", (luaV_function) &dll_luaL_loadstring},
- {"luaL_ref", (luaV_function) &dll_luaL_ref},
- {"luaL_unref", (luaV_function) &dll_luaL_unref},
- // lua
-# if LUA_VERSION_NUM <= 501
- {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
- {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
- {"lua_call", (luaV_function) &dll_lua_call},
- {"lua_pcall", (luaV_function) &dll_lua_pcall},
-# else
- {"lua_tonumberx", (luaV_function) &dll_lua_tonumberx},
- {"lua_tointegerx", (luaV_function) &dll_lua_tointegerx},
- {"lua_callk", (luaV_function) &dll_lua_callk},
- {"lua_pcallk", (luaV_function) &dll_lua_pcallk},
- {"lua_getglobal", (luaV_function) &dll_lua_getglobal},
- {"lua_setglobal", (luaV_function) &dll_lua_setglobal},
-# endif
-# if LUA_VERSION_NUM <= 502
- {"lua_replace", (luaV_function) &dll_lua_replace},
- {"lua_remove", (luaV_function) &dll_lua_remove},
-# endif
-# if LUA_VERSION_NUM >= 503
- {"lua_rotate", (luaV_function) &dll_lua_rotate},
- {"lua_copy", (luaV_function) &dll_lua_copy},
-# endif
- {"lua_typename", (luaV_function) &dll_lua_typename},
- {"lua_close", (luaV_function) &dll_lua_close},
- {"lua_gettop", (luaV_function) &dll_lua_gettop},
- {"lua_settop", (luaV_function) &dll_lua_settop},
- {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
- {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
- {"lua_isstring", (luaV_function) &dll_lua_isstring},
- {"lua_type", (luaV_function) &dll_lua_type},
- {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
- {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
- {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
- {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
- {"lua_pushnil", (luaV_function) &dll_lua_pushnil},
- {"lua_pushnumber", (luaV_function) &dll_lua_pushnumber},
- {"lua_pushinteger", (luaV_function) &dll_lua_pushinteger},
- {"lua_pushlstring", (luaV_function) &dll_lua_pushlstring},
- {"lua_pushstring", (luaV_function) &dll_lua_pushstring},
- {"lua_pushfstring", (luaV_function) &dll_lua_pushfstring},
- {"lua_pushcclosure", (luaV_function) &dll_lua_pushcclosure},
- {"lua_pushboolean", (luaV_function) &dll_lua_pushboolean},
- {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
- {"lua_getfield", (luaV_function) &dll_lua_getfield},
- {"lua_rawget", (luaV_function) &dll_lua_rawget},
- {"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
- {"lua_createtable", (luaV_function) &dll_lua_createtable},
- {"lua_settable", (luaV_function) &dll_lua_settable},
-# if LUA_VERSION_NUM >= 504
- {"lua_newuserdatauv", (luaV_function) &dll_lua_newuserdatauv},
-# else
- {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
-# endif
- {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
- {"lua_setfield", (luaV_function) &dll_lua_setfield},
- {"lua_rawset", (luaV_function) &dll_lua_rawset},
- {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
- {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
- {"lua_next", (luaV_function) &dll_lua_next},
- // libs
- {"luaopen_base", (luaV_function) &dll_luaopen_base},
- {"luaopen_table", (luaV_function) &dll_luaopen_table},
- {"luaopen_string", (luaV_function) &dll_luaopen_string},
- {"luaopen_math", (luaV_function) &dll_luaopen_math},
- {"luaopen_io", (luaV_function) &dll_luaopen_io},
- {"luaopen_os", (luaV_function) &dll_luaopen_os},
- {"luaopen_package", (luaV_function) &dll_luaopen_package},
- {"luaopen_debug", (luaV_function) &dll_luaopen_debug},
- {"luaL_openlibs", (luaV_function) &dll_luaL_openlibs},
- {NULL, NULL}
-};
-
-static HANDLE hinstLua = NULL;
-
- static int
-lua_link_init(char *libname, int verbose)
-{
- const luaV_Reg *reg;
- if (hinstLua) return OK;
- hinstLua = load_dll(libname);
- if (!hinstLua)
- {
- if (verbose)
- semsg(_(e_could_not_load_library_str_str), libname, load_dll_error());
- return FAIL;
- }
- for (reg = luaV_dll; reg->func; reg++)
- {
- if ((*reg->func = symbol_from_dll(hinstLua, reg->name)) == NULL)
- {
- close_dll(hinstLua);
- hinstLua = 0;
- if (verbose)
- semsg(_(e_could_not_load_library_function_str), reg->name);
- return FAIL;
- }
- }
- return OK;
-}
-# endif // DYNAMIC_LUA
-
-# if defined(DYNAMIC_LUA)
- int
-lua_enabled(int verbose)
-{
- return lua_link_init((char *)p_luadll, verbose) == OK;
-}
-# endif
-
-# if LUA_VERSION_NUM > 501 && LUA_VERSION_NUM < 504
- static int
-luaL_typeerror(lua_State *L, int narg, const char *tname)
-{
- const char *msg = lua_pushfstring(L, "%s expected, got %s",
- tname, luaL_typename(L, narg));
- return luaL_argerror(L, narg, msg);
-}
-# endif
-
- static LUAV_INLINE void
-luaV_getudata(lua_State *L, void *v)
-{
- lua_pushlightuserdata(L, (void *) LUAMNV_UDATA_CACHE);
- lua_rawget(L, LUA_REGISTRYINDEX); // now the cache table is at the top of the stack
- lua_pushlightuserdata(L, v);
- lua_rawget(L, -2);
- lua_remove(L, -2); // remove the cache table from the stack
-}
-
- static LUAV_INLINE void
-luaV_setudata(lua_State *L, void *v)
-{
- lua_pushlightuserdata(L, (void *) LUAMNV_UDATA_CACHE);
- lua_rawget(L, LUA_REGISTRYINDEX); // cache table is at -1
- lua_pushlightuserdata(L, v); // ...now at -2
- lua_pushvalue(L, -3); // copy the userdata (cache at -3)
- lua_rawset(L, -3); // consumes two stack items
- lua_pop(L, 1); // and remove the cache table
-}
-
-// ======= Internal =======
-
- static void
-luaV_newmetatable(lua_State *L, const char *tname)
-{
- lua_newtable(L);
- lua_pushlightuserdata(L, (void *) tname);
- lua_pushvalue(L, -2);
- lua_rawset(L, LUA_REGISTRYINDEX);
-}
-
- static void *
-luaV_toudata(lua_State *L, int ud, const char *tname)
-{
- void *p = lua_touserdata(L, ud);
-
- if (p == NULL)
- return NULL;
-
- // value is userdata
- if (lua_getmetatable(L, ud)) // does it have a metatable?
- {
- luaV_getfield(L, tname); // get metatable
- if (lua_rawequal(L, -1, -2)) // MTs match?
- {
- lua_pop(L, 2); // MTs
- return p;
- }
- }
-
- return NULL;
-}
-
- static void *
-luaV_checkcache(lua_State *L, void *p)
-{
- luaV_getudata(L, p);
- if (lua_isnil(L, -1)) luaL_error(L, "invalid object");
- lua_pop(L, 1);
- return p;
-}
-
-# define luaV_unbox(L,luatyp,ud) (*((luatyp *) lua_touserdata((L),(ud))))
-
-# define luaV_checkvalid(L,luatyp,ud) \
- luaV_checkcache((L), (void *) luaV_unbox((L),luatyp,(ud)))
-
- static void *
-luaV_checkudata(lua_State *L, int ud, const char *tname)
-{
- void *p = luaV_toudata(L, ud, tname);
- if (p == NULL) luaL_typeerror(L, ud, tname);
- return p;
-}
-
- static void
-luaV_pushtypval(lua_State *L, typval_T *tv)
-{
- if (tv == NULL)
- {
- lua_pushnil(L);
- return;
- }
- switch (tv->v_type)
- {
- case VAR_STRING:
- lua_pushstring(L, tv->vval.v_string == NULL
- ? "" : (char *)tv->vval.v_string);
- break;
- case VAR_NUMBER:
- lua_pushinteger(L, (int) tv->vval.v_number);
- break;
- case VAR_FLOAT:
- lua_pushnumber(L, (lua_Number) tv->vval.v_float);
- break;
- case VAR_LIST:
- luaV_pushlist(L, tv->vval.v_list);
- break;
- case VAR_DICT:
- luaV_pushdict(L, tv->vval.v_dict);
- break;
- case VAR_BOOL:
- case VAR_SPECIAL:
- if (tv->vval.v_number <= VVAL_TRUE)
- lua_pushboolean(L, (int) tv->vval.v_number);
- else
- lua_pushnil(L);
- break;
- case VAR_FUNC:
- luaV_pushfuncref(L, tv->vval.v_string);
- break;
- case VAR_PARTIAL:
- // TODO: handle partial arguments
- luaV_pushfuncref(L, partial_name(tv->vval.v_partial));
- break;
-
- case VAR_BLOB:
- luaV_pushblob(L, tv->vval.v_blob);
- break;
- default:
- lua_pushnil(L);
- }
-}
-
-/*
- * Converts lua value at 'pos' to typval 'tv'.
- * Returns OK or FAIL.
- */
- static int
-luaV_totypval(lua_State *L, int pos, typval_T *tv)
-{
- int status = OK;
-
- tv->v_lock = 0;
-
- switch (lua_type(L, pos))
- {
- case LUA_TBOOLEAN:
- tv->v_type = VAR_BOOL;
- tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
- break;
- case LUA_TNIL:
- tv->v_type = VAR_SPECIAL;
- tv->vval.v_number = VVAL_NULL;
- break;
- case LUA_TSTRING:
- tv->v_type = VAR_STRING;
- tv->vval.v_string = mnv_strsave((char_u *) lua_tostring(L, pos));
- break;
- case LUA_TNUMBER:
- {
- const lua_Number n = lua_tonumber(L, pos);
-
- if (n > (lua_Number)INT64_MAX || n < (lua_Number)INT64_MIN
- || ((lua_Number)((varnumber_T)n)) != n)
- {
- tv->v_type = VAR_FLOAT;
- tv->vval.v_float = (float_T)n;
- }
- else
- {
- tv->v_type = VAR_NUMBER;
- tv->vval.v_number = (varnumber_T)n;
- }
- }
- break;
- case LUA_TFUNCTION:
- {
- char_u *name;
- luaV_CFuncState *state;
-
- lua_pushvalue(L, pos);
- state = ALLOC_CLEAR_ONE(luaV_CFuncState);
- state->lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
- state->L = L;
- state->lua_tableref = LUA_NOREF;
- name = register_cfunc(&luaV_call_lua_func,
- &luaV_call_lua_func_free, state);
- tv->v_type = VAR_FUNC;
- tv->vval.v_string = mnv_strsave(name);
- break;
- }
- case LUA_TTABLE:
- {
- int lua_tableref;
-
- lua_pushvalue(L, pos);
- lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX);
- if (lua_getmetatable(L, pos))
- {
- lua_getfield(L, -1, LUA___CALL);
- if (lua_isfunction(L, -1))
- {
- char_u *name;
- int lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
- luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
-
- state->lua_funcref = lua_funcref;
- state->L = L;
- state->lua_tableref = lua_tableref;
- name = register_cfunc(&luaV_call_lua_func,
- &luaV_call_lua_func_free, state);
- tv->v_type = VAR_FUNC;
- tv->vval.v_string = mnv_strsave(name);
- break;
- }
- }
- tv->v_type = VAR_NUMBER;
- tv->vval.v_number = 0;
- status = FAIL;
- break;
- }
- case LUA_TUSERDATA:
- {
- void *p = lua_touserdata(L, pos);
-
- if (lua_getmetatable(L, pos)) // has metatable?
- {
- // check list
- luaV_getfield(L, LUAMNV_LIST);
- if (lua_rawequal(L, -1, -2))
- {
- tv->v_type = VAR_LIST;
- tv->vval.v_list = *((luaV_List *) p);
- ++tv->vval.v_list->lv_refcount;
- lua_pop(L, 2); // MTs
- break;
- }
- // check dict
- luaV_getfield(L, LUAMNV_DICT);
- if (lua_rawequal(L, -1, -3))
- {
- tv->v_type = VAR_DICT;
- tv->vval.v_dict = *((luaV_Dict *) p);
- ++tv->vval.v_dict->dv_refcount;
- lua_pop(L, 3); // MTs
- break;
- }
- // check blob
- luaV_getfield(L, LUAMNV_BLOB);
- if (lua_rawequal(L, -1, -4))
- {
- tv->v_type = VAR_BLOB;
- tv->vval.v_blob = *((luaV_Blob *) p);
- ++tv->vval.v_blob->bv_refcount;
- lua_pop(L, 4); // MTs
- break;
- }
- // check funcref
- luaV_getfield(L, LUAMNV_FUNCREF);
- if (lua_rawequal(L, -1, -5))
- {
- luaV_Funcref *f = (luaV_Funcref *) p;
-
- func_ref(f->name);
- tv->v_type = VAR_FUNC;
- tv->vval.v_string = mnv_strsave(f->name);
- lua_pop(L, 5); // MTs
- break;
- }
- lua_pop(L, 4); // MTs
- }
- }
- // FALLTHROUGH
- default:
- tv->v_type = VAR_NUMBER;
- tv->vval.v_number = 0;
- status = FAIL;
- }
- return status;
-}
-
-/*
- * similar to luaL_addlstring, but replaces \0 with \n if toline and
- * \n with \0 otherwise
- */
- static void
-luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline)
-{
- while (l--)
- {
- if (*s == '\0' && toline)
- luaL_addchar(b, '\n');
- else if (*s == '\n' && !toline)
- luaL_addchar(b, '\0');
- else
- luaL_addchar(b, *s);
- s++;
- }
-}
-
- static void
-luaV_pushline(lua_State *L, buf_T *buf, linenr_T n)
-{
- const char *s = (const char *) ml_get_buf(buf, n, FALSE);
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- luaV_addlstring(&b, s, strlen(s), 0);
- luaL_pushresult(&b);
-}
-
- static char_u *
-luaV_toline(lua_State *L, int pos)
-{
- size_t l;
- const char *s = lua_tolstring(L, pos, &l);
-
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- luaV_addlstring(&b, s, l, 1);
- luaL_pushresult(&b);
- return (char_u *) lua_tostring(L, -1);
-}
-
-/*
- * pops a string s from the top of the stack and calls mf(t) for pieces t of
- * s separated by newlines
- */
- static void
-luaV_msgfunc(lua_State *L, msgfunc_T mf)
-{
- luaL_Buffer b;
- size_t l;
- const char *p, *s = lua_tolstring(L, -1, &l);
- luaL_buffinit(L, &b);
- luaV_addlstring(&b, s, l, 0);
- luaL_pushresult(&b);
- // break string
- p = s = lua_tolstring(L, -1, &l);
- while (l--)
- {
- if (*p++ == '\0') // break?
- {
- mf((char *)s);
- s = p;
- }
- }
- mf((char *)s);
- lua_pop(L, 2); // original and modified strings
-}
-
-# define luaV_newtype(typ,tname,luatyp,luatname) \
- static luatyp * \
- luaV_new##tname(lua_State *L, typ *obj) \
- { \
- luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
- *o = obj; \
- luaV_setudata(L, obj); /* cache[obj] = udata */ \
- luaV_getfield(L, luatname); \
- lua_setmetatable(L, -2); \
- return o; \
- }
-
-# define luaV_pushtype(typ,tname,luatyp) \
- static luatyp * \
- luaV_push##tname(lua_State *L, typ *obj) \
- { \
- luatyp *o = NULL; \
- if (obj == NULL) \
- lua_pushnil(L); \
- else \
- { \
- luaV_getudata(L, obj); \
- if (lua_isnil(L, -1)) /* not interned? */ \
- { \
- lua_pop(L, 1); \
- o = luaV_new##tname(L, obj); \
- } \
- else \
- o = (luatyp *) lua_touserdata(L, -1); \
- } \
- return o; \
- }
-
-# define luaV_type_tostring(tname,luatname) \
- static int \
- luaV_##tname##_tostring(lua_State *L) \
- { \
- lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
- return 1; \
- }
-
-// ======= List type =======
-
- static luaV_List *
-luaV_newlist(lua_State *L, list_T *lis)
-{
- luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
- *l = lis;
- lis->lv_refcount++; // reference in Lua
- luaV_setudata(L, lis); // cache[lis] = udata
- luaV_getfield(L, LUAMNV_LIST);
- lua_setmetatable(L, -2);
- return l;
-}
-
-luaV_pushtype(list_T, list, luaV_List)
-luaV_type_tostring(list, LUAMNV_LIST)
-
- static int
-luaV_list_len(lua_State *L)
-{
- list_T *l = luaV_unbox(L, luaV_List, 1);
- lua_pushinteger(L, (int) list_len(l));
- return 1;
-}
-
- static int
-luaV_list_iter(lua_State *L)
-{
- listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(1));
- if (li == NULL) return 0;
- luaV_pushtypval(L, &li->li_tv);
- lua_pushlightuserdata(L, (void *) li->li_next);
- lua_replace(L, lua_upvalueindex(1));
- return 1;
-}
-
- static int
-luaV_list_call(lua_State *L)
-{
- list_T *l = luaV_unbox(L, luaV_List, 1);
- lua_pushlightuserdata(L, (void *) l->lv_first);
- lua_pushcclosure(L, luaV_list_iter, 1);
- return 1;
-}
-
- static int
-luaV_list_index(lua_State *L)
-{
- list_T *l = luaV_unbox(L, luaV_List, 1);
- if (lua_isnumber(L, 2)) // list item?
- {
- long n = (long) luaL_checkinteger(L, 2);
- listitem_T *li;
-
- // Lua array index starts with 1 while MNV uses 0, subtract 1 to
- // normalize.
- n -= 1;
- li = list_find(l, n);
- if (li == NULL)
- lua_pushnil(L);
- else
- luaV_pushtypval(L, &li->li_tv);
- }
- else if (lua_isstring(L, 2)) // method?
- {
- const char *s = lua_tostring(L, 2);
- if (strncmp(s, "add", 3) == 0
- || strncmp(s, "insert", 6) == 0)
- {
- lua_getmetatable(L, 1);
- lua_getfield(L, -1, s);
- }
- else
- lua_pushnil(L);
- }
- else
- lua_pushnil(L);
- return 1;
-}
-
- static int
-luaV_list_newindex(lua_State *L)
-{
- list_T *l = luaV_unbox(L, luaV_List, 1);
- long n = (long) luaL_checkinteger(L, 2);
- listitem_T *li;
-
- // Lua array index starts with 1 while MNV uses 0, subtract 1 to normalize.
- n -= 1;
-
- if (l->lv_lock)
- luaL_error(L, "list is locked");
- li = list_find(l, n);
- if (li == NULL)
- {
- if (!lua_isnil(L, 3))
- {
- typval_T v;
- luaV_checktypval(L, 3, &v, "inserting list item");
- if (list_insert_tv(l, &v, li) == FAIL)
- luaL_error(L, "failed to add item to list");
- clear_tv(&v);
- }
- }
- else
- {
- if (lua_isnil(L, 3)) // remove?
- {
- mnvlist_remove(l, li, li);
- listitem_free(l, li);
- }
- else
- {
- typval_T v;
- luaV_checktypval(L, 3, &v, "setting list item");
- clear_tv(&li->li_tv);
- li->li_tv = v;
- }
- }
- return 0;
-}
-
- static int
-luaV_list_add(lua_State *L)
-{
- luaV_List *lis = luaV_checkudata(L, 1, LUAMNV_LIST);
- list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
- typval_T v;
- if (l->lv_lock)
- luaL_error(L, "list is locked");
- lua_settop(L, 2);
- luaV_checktypval(L, 2, &v, "adding list item");
- if (list_append_tv(l, &v) == FAIL)
- luaL_error(L, "failed to add item to list");
- clear_tv(&v);
- lua_settop(L, 1);
- return 1;
-}
-
- static int
-luaV_list_insert(lua_State *L)
-{
- luaV_List *lis = luaV_checkudata(L, 1, LUAMNV_LIST);
- list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
- long pos = (long) luaL_optinteger(L, 3, 0);
- listitem_T *li = NULL;
- typval_T v;
- if (l->lv_lock)
- luaL_error(L, "list is locked");
- if (pos < l->lv_len)
- {
- li = list_find(l, pos);
- if (li == NULL)
- luaL_error(L, "invalid position");
- }
- lua_settop(L, 2);
- luaV_checktypval(L, 2, &v, "inserting list item");
- if (list_insert_tv(l, &v, li) == FAIL)
- luaL_error(L, "failed to add item to list");
- clear_tv(&v);
- lua_settop(L, 1);
- return 1;
-}
-
-static const luaL_Reg luaV_List_mt[] = {
- {"__tostring", luaV_list_tostring},
- {"__len", luaV_list_len},
- {"__call", luaV_list_call},
- {"__index", luaV_list_index},
- {"__newindex", luaV_list_newindex},
- {"add", luaV_list_add},
- {"insert", luaV_list_insert},
- {NULL, NULL}
-};
-
-
-// ======= Dict type =======
-
- static luaV_Dict *
-luaV_newdict(lua_State *L, dict_T *dic)
-{
- luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
- *d = dic;
- dic->dv_refcount++; // reference in Lua
- luaV_setudata(L, dic); // cache[dic] = udata
- luaV_getfield(L, LUAMNV_DICT);
- lua_setmetatable(L, -2);
- return d;
-}
-
-luaV_pushtype(dict_T, dict, luaV_Dict)
-luaV_type_tostring(dict, LUAMNV_DICT)
-
- static int
-luaV_dict_len(lua_State *L)
-{
- dict_T *d = luaV_unbox(L, luaV_Dict, 1);
- lua_pushinteger(L, (int) dict_len(d));
- return 1;
-}
-
- static int
-luaV_dict_iter(lua_State *L UNUSED)
-{
-# ifdef FEAT_EVAL
- hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(1));
- int n = lua_tointeger(L, lua_upvalueindex(2));
- dictitem_T *di;
- if (n <= 0) return 0;
- while (HASHITEM_EMPTY(hi)) hi++;
- di = dict_lookup(hi);
- lua_pushstring(L, (char *) hi->hi_key);
- luaV_pushtypval(L, &di->di_tv);
- lua_pushlightuserdata(L, (void *) (hi + 1));
- lua_replace(L, lua_upvalueindex(1));
- lua_pushinteger(L, n - 1);
- lua_replace(L, lua_upvalueindex(2));
- return 2;
-# else
- return 0;
-# endif
-}
-
- static int
-luaV_dict_call(lua_State *L)
-{
- dict_T *d = luaV_unbox(L, luaV_Dict, 1);
- hashtab_T *ht = &d->dv_hashtab;
- lua_pushlightuserdata(L, (void *) ht->ht_array);
- lua_pushinteger(L, ht->ht_used); // # remaining items
- lua_pushcclosure(L, luaV_dict_iter, 2);
- return 1;
-}
-
- static int
-luaV_dict_index(lua_State *L)
-{
- dict_T *d = luaV_unbox(L, luaV_Dict, 1);
- char_u *key = (char_u *) luaL_checkstring(L, 2);
- dictitem_T *di = dict_find(d, key, -1);
-
- if (di == NULL)
- {
- lua_pushnil(L);
- return 1;
- }
-
- luaV_pushtypval(L, &di->di_tv);
- if (di->di_tv.v_type == VAR_FUNC) // funcref?
- {
- luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1);
- f->self = d; // keep "self" reference
- d->dv_refcount++;
- }
-
- return 1;
-}
-
- static int
-luaV_dict_newindex(lua_State *L)
-{
- dict_T *d = luaV_unbox(L, luaV_Dict, 1);
- char_u *key = (char_u *) luaL_checkstring(L, 2);
- dictitem_T *di;
- typval_T tv;
-
- if (d->dv_lock)
- luaL_error(L, "dict is locked");
- if (key == NULL)
- return 0;
- if (*key == NUL)
- luaL_error(L, "empty key");
- if (!lua_isnil(L, 3)) // read value?
- {
- luaV_checktypval(L, 3, &tv, "setting dict item");
- if (d->dv_scope == VAR_DEF_SCOPE && tv.v_type == VAR_FUNC)
- {
- clear_tv(&tv);
- luaL_error(L, "cannot assign funcref to builtin scope");
- }
- }
- di = dict_find(d, key, -1);
- if (di == NULL) // non-existing key?
- {
- if (lua_isnil(L, 3))
- return 0;
- di = dictitem_alloc(key);
- if (di == NULL)
- {
- clear_tv(&tv);
- return 0;
- }
- if (dict_add(d, di) == FAIL)
- {
- mnv_free(di);
- clear_tv(&tv);
- return 0;
- }
- }
- else
- clear_tv(&di->di_tv);
- if (lua_isnil(L, 3)) // remove?
- {
- hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key);
- hash_remove(&d->dv_hashtab, hi, "Lua new index");
- dictitem_free(di);
- }
- else
- di->di_tv = tv;
- return 0;
-}
-
-static const luaL_Reg luaV_Dict_mt[] = {
- {"__tostring", luaV_dict_tostring},
- {"__len", luaV_dict_len},
- {"__call", luaV_dict_call},
- {"__index", luaV_dict_index},
- {"__newindex", luaV_dict_newindex},
- {NULL, NULL}
-};
-
-
-// ======= Blob type =======
-
- static luaV_Blob *
-luaV_newblob(lua_State *L, blob_T *blo)
-{
- luaV_Blob *b = (luaV_Blob *) lua_newuserdata(L, sizeof(luaV_Blob));
- *b = blo;
- blo->bv_refcount++; // reference in Lua
- luaV_setudata(L, blo); // cache[blo] = udata
- luaV_getfield(L, LUAMNV_BLOB);
- lua_setmetatable(L, -2);
- return b;
-}
-
-luaV_pushtype(blob_T, blob, luaV_Blob)
-luaV_type_tostring(blob, LUAMNV_BLOB)
-
- static int
-luaV_blob_gc(lua_State *L)
-{
- blob_T *b = luaV_unbox(L, luaV_Blob, 1);
- blob_unref(b);
- return 0;
-}
-
- static int
-luaV_blob_len(lua_State *L)
-{
- blob_T *b = luaV_unbox(L, luaV_Blob, 1);
- lua_pushinteger(L, (int) blob_len(b));
- return 1;
-}
-
- static int
-luaV_blob_index(lua_State *L)
-{
- blob_T *b = luaV_unbox(L, luaV_Blob, 1);
- if (lua_isnumber(L, 2))
- {
- int idx = luaL_checkinteger(L, 2);
- if (idx < blob_len(b))
- lua_pushnumber(L, (lua_Number) blob_get(b, idx));
- else
- lua_pushnil(L);
- }
- else if (lua_isstring(L, 2))
- {
- const char *s = lua_tostring(L, 2);
- if (strncmp(s, "add", 3) == 0)
- {
- lua_getmetatable(L, 1);
- lua_getfield(L, -1, s);
- }
- else
- lua_pushnil(L);
- }
- else
- lua_pushnil(L);
- return 1;
-}
-
- static int
-luaV_blob_newindex(lua_State *L)
-{
- blob_T *b = luaV_unbox(L, luaV_Blob, 1);
- if (b->bv_lock)
- luaL_error(L, "blob is locked");
-
- if (!lua_isnumber(L, 2))
- return 0;
-
- long len = blob_len(b);
- int idx = luaL_checkinteger(L, 2);
- int val = luaL_checkinteger(L, 3);
- if (idx < len || (idx == len && ga_grow(&b->bv_ga, 1) == OK))
- {
- blob_set(b, idx, (char_u) val);
- if (idx == len)
- ++b->bv_ga.ga_len;
- }
- else
- luaL_error(L, "index out of range");
-
- return 0;
-}
-
- static int
-luaV_blob_add(lua_State *L)
-{
- luaV_Blob *blo = luaV_checkudata(L, 1, LUAMNV_BLOB);
- blob_T *b = (blob_T *) luaV_checkcache(L, (void *) *blo);
- if (b->bv_lock)
- luaL_error(L, "blob is locked");
- lua_settop(L, 2);
- if (!lua_isstring(L, 2))
- luaL_error(L, "string expected, got %s", luaL_typename(L, 2));
- else
- {
- size_t i, l = 0;
- const char *s = lua_tolstring(L, 2, &l);
-
- if (ga_grow(&b->bv_ga, (int)l) == OK)
- for (i = 0; i < l; ++i)
- ga_append(&b->bv_ga, s[i]);
- }
- lua_settop(L, 1);
- return 1;
-}
-
-static const luaL_Reg luaV_Blob_mt[] = {
- {"__tostring", luaV_blob_tostring},
- {"__gc", luaV_blob_gc},
- {"__len", luaV_blob_len},
- {"__index", luaV_blob_index},
- {"__newindex", luaV_blob_newindex},
- {"add", luaV_blob_add},
- {NULL, NULL}
-};
-
-
-// ======= Funcref type =======
-
- static luaV_Funcref *
-luaV_newfuncref(lua_State *L, char_u *name)
-{
- luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref));
-
- if (name != NULL)
- {
- func_ref(name);
- f->name = mnv_strsave(name);
- }
- f->self = NULL;
- luaV_getfield(L, LUAMNV_FUNCREF);
- lua_setmetatable(L, -2);
- return f;
-}
-
- static luaV_Funcref *
-luaV_pushfuncref(lua_State *L, char_u *name)
-{
- return luaV_newfuncref(L, name);
-}
-
-
-luaV_type_tostring(funcref, LUAMNV_FUNCREF)
-
- static int
-luaV_funcref_gc(lua_State *L)
-{
- luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
-
- func_unref(f->name);
- mnv_free(f->name);
- // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self"
- // will be (or has been already) freed by MNV's garbage collection.
- return 0;
-}
-
-// equivalent to string(funcref)
- static int
-luaV_funcref_len(lua_State *L)
-{
- luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
-
- lua_pushstring(L, (const char *) f->name);
- return 1;
-}
-
- static int
-luaV_funcref_call(lua_State *L)
-{
- luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
- int i, n = lua_gettop(L) - 1; // #args
- int status = FAIL;
- typval_T args;
- typval_T rettv;
-
- args.v_type = VAR_LIST;
- args.vval.v_list = list_alloc();
- rettv.v_type = VAR_UNKNOWN; // as in clear_tv
- if (args.vval.v_list != NULL)
- {
- typval_T v;
-
- for (i = 0; i < n; i++)
- {
- luaV_checktypval(L, i + 2, &v, "calling funcref");
- list_append_tv(args.vval.v_list, &v);
- clear_tv(&v);
- }
- status = func_call(f->name, &args, NULL, f->self, &rettv);
- if (status == OK)
- luaV_pushtypval(L, &rettv);
- clear_tv(&args);
- clear_tv(&rettv);
- }
- if (status != OK)
- luaL_error(L, "cannot call funcref");
- return 1;
-}
-
-static const luaL_Reg luaV_Funcref_mt[] = {
- {"__tostring", luaV_funcref_tostring},
- {"__gc", luaV_funcref_gc},
- {"__len", luaV_funcref_len},
- {"__call", luaV_funcref_call},
- {NULL, NULL}
-};
-
-
-// ======= Buffer type =======
-
-luaV_newtype(buf_T, buffer, luaV_Buffer, LUAMNV_BUFFER)
-luaV_pushtype(buf_T, buffer, luaV_Buffer)
-luaV_type_tostring(buffer, LUAMNV_BUFFER)
-
- static int
-luaV_buffer_len(lua_State *L)
-{
- buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
- lua_pushinteger(L, b->b_ml.ml_line_count);
- return 1;
-}
-
- static int
-luaV_buffer_call(lua_State *L)
-{
- buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
- lua_settop(L, 1);
- set_curbuf(b, DOBUF_SPLIT);
- return 1;
-}
-
- static int
-luaV_buffer_index(lua_State *L)
-{
- buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
- linenr_T n = (linenr_T) lua_tointeger(L, 2);
- if (n > 0 && n <= b->b_ml.ml_line_count)
- luaV_pushline(L, b, n);
- else if (lua_isstring(L, 2))
- {
- const char *s = lua_tostring(L, 2);
- if (strncmp(s, "name", 4) == 0)
- lua_pushstring(L, (b->b_sfname == NULL)
- ? "" : (char *) b->b_sfname);
- else if (strncmp(s, "fname", 5) == 0)
- lua_pushstring(L, (b->b_ffname == NULL)
- ? "" : (char *) b->b_ffname);
- else if (strncmp(s, "number", 6) == 0)
- lua_pushinteger(L, b->b_fnum);
- // methods
- else if (strncmp(s, "insert", 6) == 0
- || strncmp(s, "next", 4) == 0
- || strncmp(s, "previous", 8) == 0
- || strncmp(s, "isvalid", 7) == 0)
- {
- lua_getmetatable(L, 1);
- lua_getfield(L, -1, s);
- }
- else
- lua_pushnil(L);
- }
- else
- lua_pushnil(L);
- return 1;
-}
-
- static int
-luaV_buffer_newindex(lua_State *L)
-{
- buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
- linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
-# ifdef HAVE_SANDBOX
- luaV_checksandbox(L);
-# endif
- if (n < 1 || n > b->b_ml.ml_line_count)
- luaL_error(L, "invalid line number");
- if (lua_isnil(L, 3)) // delete line
- {
- buf_T *buf = curbuf;
- curbuf = b;
- if (u_savedel(n, 1L) == FAIL)
- {
- curbuf = buf;
- luaL_error(L, "cannot save undo information");
- }
- else if (ml_delete(n) == FAIL)
- {
- curbuf = buf;
- luaL_error(L, "cannot delete line");
- }
- else
- {
- deleted_lines_mark(n, 1L);
- if (b == curwin->w_buffer) // fix cursor in current window?
- {
- if (curwin->w_cursor.lnum >= n)
- {
- if (curwin->w_cursor.lnum > n)
- {
- curwin->w_cursor.lnum -= 1;
- check_cursor_col();
- }
- else
- check_cursor();
- changed_cline_bef_curs();
- }
- invalidate_botline();
- }
- }
- curbuf = buf;
- }
- else if (lua_isstring(L, 3)) // update line
- {
- buf_T *buf = curbuf;
- curbuf = b;
- if (u_savesub(n) == FAIL)
- {
- curbuf = buf;
- luaL_error(L, "cannot save undo information");
- }
- else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL)
- {
- curbuf = buf;
- luaL_error(L, "cannot replace line");
- }
- else
- changed_bytes(n, 0);
- curbuf = buf;
- if (b == curwin->w_buffer)
- check_cursor_col();
- }
- else
- luaL_error(L, "wrong argument to change line");
- return 0;
-}
-
- static int
-luaV_buffer_insert(lua_State *L)
-{
- luaV_Buffer *lb = luaV_checkudata(L, 1, LUAMNV_BUFFER);
- buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb);
- linenr_T last = b->b_ml.ml_line_count;
- linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
- buf_T *buf;
- luaL_checktype(L, 2, LUA_TSTRING);
-# ifdef HAVE_SANDBOX
- luaV_checksandbox(L);
-# endif
- // fix insertion line
- if (n < 0) n = 0;
- if (n > last) n = last;
- // insert
- buf = curbuf;
- curbuf = b;
- if (u_save(n, n + 1) == FAIL)
- {
- curbuf = buf;
- luaL_error(L, "cannot save undo information");
- }
- else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL)
- {
- curbuf = buf;
- luaL_error(L, "cannot insert line");
- }
- else
- appended_lines_mark(n, 1L);
- curbuf = buf;
- update_screen(UPD_VALID);
- return 0;
-}
-
- static int
-luaV_buffer_next(lua_State *L)
-{
- luaV_Buffer *b = luaV_checkudata(L, 1, LUAMNV_BUFFER);
- buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
- luaV_pushbuffer(L, buf->b_next);
- return 1;
-}
-
- static int
-luaV_buffer_previous(lua_State *L)
-{
- luaV_Buffer *b = luaV_checkudata(L, 1, LUAMNV_BUFFER);
- buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
- luaV_pushbuffer(L, buf->b_prev);
- return 1;
-}
-
- static int
-luaV_buffer_isvalid(lua_State *L)
-{
- luaV_Buffer *b = luaV_checkudata(L, 1, LUAMNV_BUFFER);
- luaV_getudata(L, *b);
- lua_pushboolean(L, !lua_isnil(L, -1));
- return 1;
-}
-
-static const luaL_Reg luaV_Buffer_mt[] = {
- {"__tostring", luaV_buffer_tostring},
- {"__len", luaV_buffer_len},
- {"__call", luaV_buffer_call},
- {"__index", luaV_buffer_index},
- {"__newindex", luaV_buffer_newindex},
- {"insert", luaV_buffer_insert},
- {"next", luaV_buffer_next},
- {"previous", luaV_buffer_previous},
- {"isvalid", luaV_buffer_isvalid},
- {NULL, NULL}
-};
-
-
-// ======= Window type =======
-
-luaV_newtype(win_T, window, luaV_Window, LUAMNV_WINDOW)
-luaV_pushtype(win_T, window, luaV_Window)
-luaV_type_tostring(window, LUAMNV_WINDOW)
-
- static int
-luaV_window_call(lua_State *L)
-{
- win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
- lua_settop(L, 1);
- win_goto(w);
- return 1;
-}
-
- static int
-luaV_window_index(lua_State *L)
-{
- win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
- const char *s = luaL_checkstring(L, 2);
- if (strncmp(s, "buffer", 6) == 0)
- luaV_pushbuffer(L, w->w_buffer);
- else if (strncmp(s, "line", 4) == 0)
- lua_pushinteger(L, w->w_cursor.lnum);
- else if (strncmp(s, "col", 3) == 0)
- lua_pushinteger(L, w->w_cursor.col + 1);
- else if (strncmp(s, "width", 5) == 0)
- lua_pushinteger(L, w->w_width);
- else if (strncmp(s, "height", 6) == 0)
- lua_pushinteger(L, w->w_height);
- // methods
- else if (strncmp(s, "next", 4) == 0
- || strncmp(s, "previous", 8) == 0
- || strncmp(s, "isvalid", 7) == 0)
- {
- lua_getmetatable(L, 1);
- lua_getfield(L, -1, s);
- }
- else
- lua_pushnil(L);
- return 1;
-}
-
- static int
-luaV_window_newindex(lua_State *L)
-{
- win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
- const char *s = luaL_checkstring(L, 2);
- int v = luaL_checkinteger(L, 3);
- if (strncmp(s, "line", 4) == 0)
- {
-# ifdef HAVE_SANDBOX
- luaV_checksandbox(L);
-# endif
- if (v < 1 || v > w->w_buffer->b_ml.ml_line_count)
- luaL_error(L, "line out of range");
- w->w_cursor.lnum = v;
- update_screen(UPD_VALID);
- }
- else if (strncmp(s, "col", 3) == 0)
- {
-# ifdef HAVE_SANDBOX
- luaV_checksandbox(L);
-# endif
- w->w_cursor.col = v - 1;
- w->w_set_curswant = TRUE;
- update_screen(UPD_VALID);
- }
- else if (strncmp(s, "width", 5) == 0)
- {
- win_T *win = curwin;
-# ifdef FEAT_GUI
- need_mouse_correct = TRUE;
-# endif
- curwin = w;
- win_setwidth(v);
- curwin = win;
- }
- else if (strncmp(s, "height", 6) == 0)
- {
- win_T *win = curwin;
-# ifdef FEAT_GUI
- need_mouse_correct = TRUE;
-# endif
- curwin = w;
- win_setheight(v);
- curwin = win;
- }
- else
- luaL_error(L, "invalid window property: `%s'", s);
- return 0;
-}
-
- static int
-luaV_window_next(lua_State *L)
-{
- luaV_Window *w = luaV_checkudata(L, 1, LUAMNV_WINDOW);
- win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
- luaV_pushwindow(L, win->w_next);
- return 1;
-}
-
- static int
-luaV_window_previous(lua_State *L)
-{
- luaV_Window *w = luaV_checkudata(L, 1, LUAMNV_WINDOW);
- win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
- luaV_pushwindow(L, win->w_prev);
- return 1;
-}
-
- static int
-luaV_window_isvalid(lua_State *L)
-{
- luaV_Window *w = luaV_checkudata(L, 1, LUAMNV_WINDOW);
- luaV_getudata(L, *w);
- lua_pushboolean(L, !lua_isnil(L, -1));
- return 1;
-}
-
-static const luaL_Reg luaV_Window_mt[] = {
- {"__tostring", luaV_window_tostring},
- {"__call", luaV_window_call},
- {"__index", luaV_window_index},
- {"__newindex", luaV_window_newindex},
- {"next", luaV_window_next},
- {"previous", luaV_window_previous},
- {"isvalid", luaV_window_isvalid},
- {NULL, NULL}
-};
-
-
-// ======= MNV module =======
-
- static int
-luaV_print(lua_State *L)
-{
- int i, n = lua_gettop(L); // nargs
- const char *s;
- size_t l;
- garray_T msg_ga;
-
- ga_init2(&msg_ga, 1, 128);
- lua_getglobal(L, "tostring");
- for (i = 1; i <= n; i++)
- {
- lua_pushvalue(L, -1); // tostring
- lua_pushvalue(L, i); // arg
- lua_call(L, 1, 1);
- s = lua_tolstring(L, -1, &l);
- if (s == NULL)
- return luaL_error(L, "cannot convert to string");
- if (i > 1)
- ga_append(&msg_ga, ' '); // use space instead of tab
- ga_concat_len(&msg_ga, (char_u *)s, l);
- lua_pop(L, 1);
- }
- // Replace any "\n" with "\0"
- for (i = 0; i < msg_ga.ga_len; i++)
- if (((char *)msg_ga.ga_data)[i] == '\n')
- ((char *)msg_ga.ga_data)[i] = '\0';
- lua_pushlstring(L, msg_ga.ga_data, msg_ga.ga_len);
- if (!got_int)
- luaV_msg(L);
-
- ga_clear(&msg_ga);
- return 0;
-}
-
- static int
-luaV_debug(lua_State *L)
-{
- lua_settop(L, 0);
- lua_getglobal(L, "mnv");
- lua_getfield(L, -1, "eval");
- lua_remove(L, -2); // mnv.eval at position 1
- for (;;)
- {
- const char *input;
- size_t l;
- lua_pushvalue(L, 1); // mnv.eval
- lua_pushliteral(L, "input('lua_debug> ')");
- lua_call(L, 1, 1); // return string
- input = lua_tolstring(L, -1, &l);
- if (l == 0 || strcmp(input, "cont") == 0)
- return 0;
- msg_putchar('\n'); // avoid outputting on input line
- if (luaL_loadbuffer(L, input, l, "=(debug command)")
- || lua_pcall(L, 0, 0, 0))
- luaV_emsg(L);
- lua_settop(L, 1); // remove eventual returns, but keep mnv.eval
- }
-}
-
- static dict_T *
-luaV_get_var_scope(lua_State *L)
-{
- const char *scope = luaL_checkstring(L, 1);
- dict_T *dict = NULL;
-
- if (STRICMP((char *)scope, "g") == 0)
- dict = get_globvar_dict();
- else if (STRICMP((char *)scope, "v") == 0)
- dict = get_mnvvar_dict();
- else if (STRICMP((char *)scope, "b") == 0)
- dict = curbuf->b_vars;
- else if (STRICMP((char *)scope, "w") == 0)
- dict = curwin->w_vars;
- else if (STRICMP((char *)scope, "t") == 0)
- dict = curtab->tp_vars;
- else
- {
- luaL_error(L, "invalid scope %s", scope);
- return NULL;
- }
-
- return dict;
-}
-
- static int
-luaV_setvar(lua_State *L)
-{
- dict_T *dict;
- dictitem_T *di;
- size_t len;
- char *name;
- int del;
- char *error = NULL;
-
- name = (char *)luaL_checklstring(L, 3, &len);
- del = (lua_gettop(L) < 4) || lua_isnil(L, 4);
-
- dict = luaV_get_var_scope(L);
- if (dict == NULL)
- return 0;
-
- di = dict_find(dict, (char_u *)name, (int)len);
- if (di != NULL)
- {
- if (di->di_flags & DI_FLAGS_RO)
- error = "variable is read-only";
- else if (di->di_flags & DI_FLAGS_LOCK)
- error = "variable is locked";
- else if (del && di->di_flags & DI_FLAGS_FIX)
- error = "variable is fixed";
- if (error != NULL)
- return luaL_error(L, error);
- }
- else if (dict->dv_lock)
- return luaL_error(L, "Dictionary is locked");
-
- if (del)
- {
- // Delete the key
- if (di == NULL)
- // Doesn't exist, nothing to do
- return 0;
- // Delete the entry
- dictitem_remove(dict, di, "Lua delete variable");
- }
- else
- {
- // Update the key
- typval_T tv;
-
- // Convert the lua value to a MNV script type in the temporary variable
- lua_pushvalue(L, 4);
- if (luaV_totypval(L, -1, &tv) == FAIL)
- return luaL_error(L, "Couldn't convert lua value");
-
- if (di == NULL)
- {
- // Need to create an entry
- di = dictitem_alloc((char_u *)name);
- if (di == NULL)
- {
- clear_tv(&tv);
- return 0;
- }
- // Update the value
- copy_tv(&tv, &di->di_tv);
- if (dict_add(dict, di) == FAIL)
- {
- dictitem_free(di);
- clear_tv(&tv);
- return luaL_error(L, "Couldn't add to dictionary");
- }
- }
- else
- {
- int type_error = FALSE;
- if (dict == get_mnvvar_dict()
- && !before_set_vvar((char_u *)name, di, &tv, TRUE, &type_error))
- {
- clear_tv(&tv);
- if (type_error)
- return luaL_error(L,
- "Setting v:%s to value with wrong type", name);
- return 0;
- }
- // Clear the old value
- clear_tv(&di->di_tv);
- // Update the value
- copy_tv(&tv, &di->di_tv);
- }
-
- // Clear the temporary variable
- clear_tv(&tv);
- }
-
- return 0;
-}
-
- static int
-luaV_getvar(lua_State *L)
-{
- dict_T *dict = luaV_get_var_scope(L);
- size_t len;
- const char *name = luaL_checklstring(L, 3, &len);
- dictitem_T *di = dict_find(dict, (char_u *)name, (int)len);
-
- if (di == NULL)
- return 0; // nil
-
- luaV_pushtypval(L, &di->di_tv);
- return 1;
-}
-
- static int
-luaV_command(lua_State *L)
-{
- char_u *s = mnv_strsave((char_u *)luaL_checkstring(L, 1));
-
- execute_cmds_from_string(s);
- mnv_free(s);
- update_screen(UPD_VALID);
- return 0;
-}
-
- static int
-luaV_eval(lua_State *L)
-{
- typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL);
-
- if (tv == NULL) luaL_error(L, "invalid expression");
- luaV_pushtypval(L, tv);
- free_tv(tv);
- return 1;
-}
-
- static int
-luaV_beep(lua_State *L UNUSED)
-{
- mnv_beep(BO_LANG);
- return 0;
-}
-
- static int
-luaV_line(lua_State *L)
-{
- luaV_pushline(L, curbuf, curwin->w_cursor.lnum);
- return 1;
-}
-
- static int
-luaV_list(lua_State *L)
-{
- list_T *l;
- int initarg = !lua_isnoneornil(L, 1);
-
- if (initarg && lua_type(L, 1) != LUA_TTABLE)
- luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
-
- l = list_alloc();
- if (l == NULL)
- {
- lua_pushnil(L);
- return 1;
- }
-
- luaV_newlist(L, l);
- if (!initarg)
- return 1;
-
- // traverse table to init list
- int notnil, i = 0;
- typval_T v;
- do
- {
- lua_rawgeti(L, 1, ++i);
- notnil = !lua_isnil(L, -1);
- if (notnil)
- {
- luaV_checktypval(L, -1, &v, "mnv.list");
- list_append_tv(l, &v);
- clear_tv(&v);
- }
- lua_pop(L, 1); // value
- } while (notnil);
-
- return 1;
-}
-
- static int
-luaV_dict(lua_State *L)
-{
- dict_T *d;
- int initarg = !lua_isnoneornil(L, 1);
-
- if (initarg && lua_type(L, 1) != LUA_TTABLE)
- luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
-
- d = dict_alloc();
- if (d == NULL)
- {
- lua_pushnil(L);
- return 1;
- }
-
- luaV_newdict(L, d);
- if (!initarg)
- return 1;
-
- // traverse table to init dict
- lua_pushnil(L);
- while (lua_next(L, 1))
- {
- char_u *key;
- dictitem_T *di;
- typval_T v;
-
- lua_pushvalue(L, -2); // dup key in case it's a number
- key = (char_u *) lua_tostring(L, -1);
- if (key == NULL)
- {
- lua_pushnil(L);
- return 1;
- }
- if (*key == NUL)
- luaL_error(L, "table has empty key");
- luaV_checktypval(L, -2, &v, "mnv.dict"); // value
- di = dictitem_alloc(key);
- if (di == NULL || dict_add(d, di) == FAIL)
- {
- mnv_free(di);
- lua_pushnil(L);
- return 1;
- }
- di->di_tv = v;
- lua_pop(L, 2); // key copy and value
- }
-
- return 1;
-}
-
- static int
-luaV_blob(lua_State *L)
-{
- blob_T *b;
- int initarg = !lua_isnoneornil(L, 1);
-
- if (initarg && !lua_isstring(L, 1))
- luaL_error(L, "string expected, got %s", luaL_typename(L, 1));
-
- b = blob_alloc();
- if (b == NULL)
- {
- lua_pushnil(L);
- return 1;
- }
-
- luaV_newblob(L, b);
- if (!initarg)
- return 1;
-
- // traverse table to init blob
- size_t i, l = 0;
- const char *s = lua_tolstring(L, 1, &l);
-
- if (ga_grow(&b->bv_ga, (int)l) == OK)
- for (i = 0; i < l; ++i)
- ga_append(&b->bv_ga, s[i]);
-
- return 1;
-}
-
- static int
-luaV_funcref(lua_State *L)
-{
- const char *name = luaL_checkstring(L, 1);
- // note: not checking if function exists (needs function_exists)
- if (name == NULL || *name == NUL || MNV_ISDIGIT(*name))
- luaL_error(L, "invalid function name: %s", name);
- luaV_newfuncref(L, (char_u *) name);
- return 1;
-}
-
- static int
-luaV_buffer(lua_State *L)
-{
- buf_T *buf;
- if (lua_isstring(L, 1)) // get by number or name?
- {
- if (lua_isnumber(L, 1)) // by number?
- {
- int n = lua_tointeger(L, 1);
- FOR_ALL_BUFFERS(buf)
- if (buf->b_fnum == n) break;
- }
- else // by name
- {
- size_t l;
- const char *s = lua_tolstring(L, 1, &l);
- FOR_ALL_BUFFERS(buf)
- {
- if (buf->b_ffname == NULL || buf->b_sfname == NULL)
- {
- if (l == 0) break;
- }
- else if (strncmp(s, (char *)buf->b_ffname, l) == 0
- || strncmp(s, (char *)buf->b_sfname, l) == 0)
- break;
- }
- }
- }
- else
- buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; // first buffer?
- luaV_pushbuffer(L, buf);
- return 1;
-}
-
- static int
-luaV_window(lua_State *L)
-{
- win_T *win;
- if (lua_isnumber(L, 1)) // get by number?
- {
- int n = lua_tointeger(L, 1);
- for (win = firstwin; win != NULL; win = win->w_next, n--)
- if (n == 1) break;
- }
- else
- win = (lua_toboolean(L, 1)) ? firstwin : curwin; // first window?
- luaV_pushwindow(L, win);
- return 1;
-}
-
- static int
-luaV_open(lua_State *L)
-{
- char_u *s = NULL;
-# ifdef HAVE_SANDBOX
- luaV_checksandbox(L);
-# endif
- if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1);
- luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED));
- return 1;
-}
-
- static int
-luaV_type(lua_State *L)
-{
- luaL_checkany(L, 1);
- if (lua_type(L, 1) == LUA_TUSERDATA) // check mnv udata?
- {
- lua_settop(L, 1);
- if (lua_getmetatable(L, 1))
- {
- luaV_getfield(L, LUAMNV_LIST);
- if (lua_rawequal(L, -1, 2))
- {
- lua_pushstring(L, "list");
- return 1;
- }
- luaV_getfield(L, LUAMNV_DICT);
- if (lua_rawequal(L, -1, 2))
- {
- lua_pushstring(L, "dict");
- return 1;
- }
- luaV_getfield(L, LUAMNV_BLOB);
- if (lua_rawequal(L, -1, 2))
- {
- lua_pushstring(L, "blob");
- return 1;
- }
- luaV_getfield(L, LUAMNV_FUNCREF);
- if (lua_rawequal(L, -1, 2))
- {
- lua_pushstring(L, "funcref");
- return 1;
- }
- luaV_getfield(L, LUAMNV_BUFFER);
- if (lua_rawequal(L, -1, 2))
- {
- lua_pushstring(L, "buffer");
- return 1;
- }
- luaV_getfield(L, LUAMNV_WINDOW);
- if (lua_rawequal(L, -1, 2))
- {
- lua_pushstring(L, "window");
- return 1;
- }
- }
- }
- lua_pushstring(L, luaL_typename(L, 1)); // fallback
- return 1;
-}
-
- static int
-luaV_call(lua_State *L)
-{
- int argc = lua_gettop(L) - 1;
- size_t funcname_len;
- char_u *funcname;
- char *error = NULL;
- typval_T rettv;
- typval_T argv[MAX_FUNC_ARGS + 1];
- int i = 0;
-
- if (argc > MAX_FUNC_ARGS)
- return luaL_error(L, "Function called with too many arguments");
-
- funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len);
-
- for (; i < argc; i++)
- {
- if (luaV_totypval(L, i + 2, &argv[i]) == FAIL)
- {
- error = "lua: cannot convert value";
- goto free_mnv_args;
- }
- }
-
- argv[argc].v_type = VAR_UNKNOWN;
-
- if (call_mnv_function(funcname, argc, argv, &rettv) == FAIL)
- {
- error = "lua: call_mnv_function failed";
- goto free_mnv_args;
- }
-
- luaV_pushtypval(L, &rettv);
- clear_tv(&rettv);
-
-free_mnv_args:
- while (i > 0)
- clear_tv(&argv[--i]);
-
- if (error == NULL)
- return 1;
- else
- return luaL_error(L, error);
-}
-
-/*
- * Return the MNV version as a Lua table
- */
- static int
-luaV_version(lua_State *L)
-{
- lua_newtable(L);
- lua_pushstring(L, "major");
- lua_pushinteger(L, MNV_VERSION_MAJOR);
- lua_settable(L, -3);
- lua_pushstring(L, "minor");
- lua_pushinteger(L, MNV_VERSION_MINOR);
- lua_settable(L, -3);
- lua_pushstring(L, "patch");
- lua_pushinteger(L, highest_patch());
- lua_settable(L, -3);
- return 1;
-}
-
-static const luaL_Reg luaV_module[] = {
- {"command", luaV_command},
- {"eval", luaV_eval},
- {"beep", luaV_beep},
- {"line", luaV_line},
- {"list", luaV_list},
- {"dict", luaV_dict},
- {"blob", luaV_blob},
- {"funcref", luaV_funcref},
- {"buffer", luaV_buffer},
- {"window", luaV_window},
- {"open", luaV_open},
- {"type", luaV_type},
- {"call", luaV_call},
- {"_getvar", luaV_getvar},
- {"_setvar", luaV_setvar},
- {"version", luaV_version},
- {"lua_version", NULL},
- {NULL, NULL}
-};
-
-/*
- * for freeing list, dict, buffer and window objects; lightuserdata as arg
- */
- static int
-luaV_free(lua_State *L)
-{
- lua_pushnil(L);
- luaV_setudata(L, lua_touserdata(L, 1));
- return 0;
-}
-
- static int
-luaV_luaeval(lua_State *L)
-{
- luaL_Buffer b;
- size_t l;
- const char *str = lua_tolstring(L, 1, &l);
- typval_T *arg = (typval_T *) lua_touserdata(L, 2);
- typval_T *rettv = (typval_T *) lua_touserdata(L, 3);
- luaL_buffinit(L, &b);
- luaL_addlstring(&b, LUAMNV_EVALHEADER, sizeof(LUAMNV_EVALHEADER) - 1);
- luaL_addlstring(&b, str, l);
- luaL_pushresult(&b);
- str = lua_tolstring(L, -1, &l);
- if (luaL_loadbuffer(L, str, l, LUAMNV_EVALNAME)) // compile error?
- {
- luaV_emsg(L);
- return 0;
- }
- luaV_pushtypval(L, arg);
- if (lua_pcall(L, 1, 1, 0)) // running error?
- {
- luaV_emsg(L);
- return 0;
- }
- if (luaV_totypval(L, -1, rettv) == FAIL)
- emsg("luaeval: cannot convert value");
- return 0;
-}
-
- static int
-luaV_setref(lua_State *L)
-{
- int copyID = lua_tointeger(L, 1);
- int abort = FALSE;
-
- lua_pushlightuserdata(L, (void *) LUAMNV_UDATA_CACHE);
- lua_rawget(L, LUA_REGISTRYINDEX); // the cache table
-
- luaV_getfield(L, LUAMNV_LIST);
- luaV_getfield(L, LUAMNV_DICT);
- luaV_getfield(L, LUAMNV_FUNCREF);
- lua_pushnil(L);
- // traverse cache table
- while (!abort && lua_next(L, 2) != 0)
- {
- lua_getmetatable(L, -1);
- if (lua_rawequal(L, -1, 3)) // list?
- {
- list_T *l = (list_T *)lua_touserdata(L, 6); // key
-
- abort = set_ref_in_list(l, copyID);
- }
- else if (lua_rawequal(L, -1, 4)) // dict?
- {
- dict_T *d = (dict_T *)lua_touserdata(L, 6); // key
-
- abort = set_ref_in_dict(d, copyID);
- }
- else if (lua_rawequal(L, -1, 5)) // funcref?
- {
- luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 6); // key
-
- abort = set_ref_in_dict(f->self, copyID);
- }
- lua_pop(L, 2); // metatable and value
- }
- lua_pushinteger(L, abort);
- return 1;
-}
-
- static int
-luaV_pushversion(lua_State *L)
-{
- int major = 0;
- int minor = 0;
- int patch = 0;
- char s[16];
-
- sscanf(LUAMNV_VERSION, "Lua %d.%d.%d", &major, &minor, &patch);
- mnv_snprintf(s, sizeof(s), "%d.%d.%d", major, minor, patch);
- lua_pushstring(L, s);
- return 0;
-}
-
-# define LUA_MNV_FN_CODE \
- "mnv.fn = setmetatable({}, {\n"\
- " __index = function (t, key)\n"\
- " local function _fn(...)\n"\
- " return mnv.call(key, ...)\n"\
- " end\n"\
- " t[key] = _fn\n"\
- " return _fn\n"\
- " end\n"\
- " })"
-
-# define LUA_MNV_UPDATE_PACKAGE_PATHS \
- "local last_mnv_paths = {}\n"\
- "mnv._update_package_paths = function ()\n"\
- " local cur_mnv_paths = {}\n"\
- " local function split(s, delimiter)\n"\
- " result = {}\n"\
- " for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\
- " table.insert(result, match)\n"\
- " end\n"\
- " return result\n"\
- " end\n"\
- " local rtps = split(mnv.eval('&runtimepath'), ',')\n"\
- " local sep = package.config:sub(1, 1)\n"\
- " for _, key in ipairs({'path', 'cpath'}) do\n"\
- " local orig_str = package[key] .. ';'\n"\
- " local pathtrails_ordered = {}\n"\
- " -- Note: ignores trailing item without trailing `;`. Not using something\n"\
- " -- simpler in order to preserve empty items (stand for default path).\n"\
- " local orig = {}\n"\
- " for s in orig_str:gmatch('([^;]*);') do\n"\
- " orig[#orig + 1] = s\n"\
- " end\n"\
- " if key == 'path' then\n"\
- " -- /?.lua and /?/init.lua\n"\
- " pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\
- " else\n"\
- " local pathtrails = {}\n"\
- " for _, s in ipairs(orig) do\n"\
- " -- Find out path patterns. pathtrail should contain something like\n"\
- " -- /?.so, \?.dll. This allows not to bother determining what correct\n"\
- " -- suffixes are.\n"\
- " local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\
- " if pathtrail and not pathtrails[pathtrail] then\n"\
- " pathtrails[pathtrail] = true\n"\
- " pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\
- " end\n"\
- " end\n"\
- " end\n"\
- " local new = {}\n"\
- " for _, rtp in ipairs(rtps) do\n"\
- " if not rtp:match(';') then\n"\
- " for _, pathtrail in pairs(pathtrails_ordered) do\n"\
- " local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\
- " -- Always keep paths from &runtimepath at the start:\n"\
- " -- append them here disregarding orig possibly containing one of them.\n"\
- " new[#new + 1] = new_path\n"\
- " cur_mnv_paths[new_path] = true\n"\
- " end\n"\
- " end\n"\
- " end\n"\
- " for _, orig_path in ipairs(orig) do\n"\
- " -- Handle removing obsolete paths originating from &runtimepath: such\n"\
- " -- paths either belong to cur_nmnv_paths and were already added above or\n"\
- " -- to last_nmnv_paths and should not be added at all if corresponding\n"\
- " -- entry was removed from &runtimepath list.\n"\
- " if not (cur_mnv_paths[orig_path] or last_mnv_paths[orig_path]) then\n"\
- " new[#new + 1] = orig_path\n"\
- " end\n"\
- " end\n"\
- " package[key] = table.concat(new, ';')\n"\
- " end\n"\
- " last_mnv_paths = cur_mnv_paths\n"\
- "end"
-
-# define LUA_MNV_SETUP_VARIABLE_DICTS \
- "do\n"\
- " local function make_dict_accessor(scope)\n"\
- " local mt = {}\n"\
- " function mt:__newindex(k, v)\n"\
- " return mnv._setvar(scope, 0, k, v)\n"\
- " end\n"\
- " function mt:__index(k)\n"\
- " return mnv._getvar(scope, 0, k)\n"\
- " end\n"\
- " return setmetatable({}, mt)\n"\
- " end\n"\
- " mnv.g = make_dict_accessor('g')\n"\
- " mnv.v = make_dict_accessor('v')\n"\
- " mnv.b = make_dict_accessor('b')\n"\
- " mnv.w = make_dict_accessor('w')\n"\
- " mnv.t = make_dict_accessor('t')\n"\
- "end"
-
- static int
-luaopen_mnv(lua_State *L)
-{
- lua_newtable(L); // cache table
- lua_newtable(L); // cache table's metatable
- lua_pushstring(L, "v");
- lua_setfield(L, -2, "__mode");
- lua_setmetatable(L, -2); // cache is weak-valued
- // put the cache table in the registry for luaV_get/setudata()
- lua_pushlightuserdata(L, (void *) LUAMNV_UDATA_CACHE);
- lua_pushvalue(L, -2);
- lua_rawset(L, LUA_REGISTRYINDEX);
- lua_pop(L, 1); // we don't need the cache table here anymore
- // print
- lua_pushcfunction(L, luaV_print);
- lua_setglobal(L, "print");
- // debug.debug
- lua_getglobal(L, "debug");
- lua_pushcfunction(L, luaV_debug);
- lua_setfield(L, -2, "debug");
- lua_pop(L, 1);
- // free
- lua_pushlightuserdata(L, (void *) LUAMNV_FREE);
- lua_pushcfunction(L, luaV_free);
- lua_rawset(L, LUA_REGISTRYINDEX);
- // luaeval
- lua_pushlightuserdata(L, (void *) LUAMNV_LUAEVAL);
- lua_pushcfunction(L, luaV_luaeval);
- lua_rawset(L, LUA_REGISTRYINDEX);
- // setref
- lua_pushlightuserdata(L, (void *) LUAMNV_SETREF);
- lua_pushcfunction(L, luaV_setref);
- lua_rawset(L, LUA_REGISTRYINDEX);
- // register
- luaV_newmetatable(L, LUAMNV_LIST);
- luaV_register(L, luaV_List_mt);
- lua_pop(L, 1);
- luaV_newmetatable(L, LUAMNV_DICT);
- luaV_register(L, luaV_Dict_mt);
- lua_pop(L, 1);
- luaV_newmetatable(L, LUAMNV_BLOB);
- luaV_register(L, luaV_Blob_mt);
- lua_pop(L, 1);
- luaV_newmetatable(L, LUAMNV_FUNCREF);
- luaV_register(L, luaV_Funcref_mt);
- lua_pop(L, 1);
- luaV_newmetatable(L, LUAMNV_BUFFER);
- luaV_register(L, luaV_Buffer_mt);
- lua_pop(L, 1);
- luaV_newmetatable(L, LUAMNV_WINDOW);
- luaV_register(L, luaV_Window_mt);
- lua_pop(L, 1);
- lua_newtable(L); // mnv table
- luaV_register(L, luaV_module);
- luaV_pushversion(L);
- lua_setfield(L, -2, "lua_version");
- lua_setglobal(L, LUAMNV_NAME);
- // custom code
- (void)luaL_dostring(L, LUA_MNV_FN_CODE);
- (void)luaL_dostring(L, LUA_MNV_UPDATE_PACKAGE_PATHS);
- (void)luaL_dostring(L, LUA_MNV_SETUP_VARIABLE_DICTS);
-
- lua_getglobal(L, LUAMNV_NAME);
- lua_getfield(L, -1, "_update_package_paths");
-
- if (lua_pcall(L, 0, 0, 0))
- luaV_emsg(L);
-
- return 0;
-}
-
- static lua_State *
-luaV_newstate(void)
-{
- lua_State *L = luaL_newstate();
- luaL_openlibs(L); // core libs
- lua_pushcfunction(L, luaopen_mnv); // mnv
- lua_call(L, 0, 0);
- return L;
-}
-
- static void
-luaV_setrange(lua_State *L, int line1, int line2)
-{
- lua_getglobal(L, LUAMNV_NAME);
- lua_pushinteger(L, line1);
- lua_setfield(L, -2, "firstline");
- lua_pushinteger(L, line2);
- lua_setfield(L, -2, "lastline");
- lua_pop(L, 1); // mnv table
-}
-
-
-// ======= Interface =======
-
-static lua_State *L = NULL;
-
- static int
-lua_isopen(void)
-{
- return L != NULL;
-}
-
- static int
-lua_init(void)
-{
- if (lua_isopen())
- return OK;
-
-# ifdef DYNAMIC_LUA
- if (!lua_enabled(TRUE))
- {
- emsg(_("Lua library cannot be loaded."));
- return FAIL;
- }
-# endif
- L = luaV_newstate();
-
- return OK;
-}
-
- void
-lua_end(void)
-{
- if (!lua_isopen())
- return;
-
- lua_close(L);
- L = NULL;
-}
-
-/*
- * ex commands
- */
- void
-ex_lua(exarg_T *eap)
-{
- char *script = (char *)script_get(eap, eap->arg);
-
- if (!eap->skip && lua_init() == OK)
- {
- char *s = script != NULL ? script : (char *)eap->arg;
-
- luaV_setrange(L, eap->line1, eap->line2);
- if (luaL_loadbuffer(L, s, strlen(s), LUAMNV_CHUNKNAME)
- || lua_pcall(L, 0, 0, 0))
- luaV_emsg(L);
- }
- if (script != NULL)
- mnv_free(script);
-}
-
- void
-ex_luado(exarg_T *eap)
-{
- linenr_T l;
- const char *s = (const char *) eap->arg;
- luaL_Buffer b;
- size_t len;
- buf_T *was_curbuf = curbuf;
-
- if (lua_init() == FAIL) return;
- if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
- {
- emsg(_("cannot save undo information"));
- return;
- }
- luaV_setrange(L, eap->line1, eap->line2);
- luaL_buffinit(L, &b);
- luaL_addlstring(&b, "return function(line, linenr) ", 30); // header
- luaL_addlstring(&b, s, strlen(s));
- luaL_addlstring(&b, " end", 4); // footer
- luaL_pushresult(&b);
- s = lua_tolstring(L, -1, &len);
- if (luaL_loadbuffer(L, s, len, LUAMNV_CHUNKNAME))
- {
- luaV_emsg(L);
- lua_pop(L, 1); // function body
- return;
- }
- lua_call(L, 0, 1);
- lua_replace(L, -2); // function -> body
- for (l = eap->line1; l <= eap->line2; l++)
- {
- // Check the line number, the command may have deleted lines.
- if (l > curbuf->b_ml.ml_line_count)
- break;
-
- lua_pushvalue(L, -1); // function
- luaV_pushline(L, curbuf, l); // current line as arg
- lua_pushinteger(L, l); // current line number as arg
- if (lua_pcall(L, 2, 1, 0))
- {
- luaV_emsg(L);
- break;
- }
-
- // Catch the command switching to another buffer.
- // Check the line number, the command may have deleted lines.
- if (curbuf != was_curbuf || l > curbuf->b_ml.ml_line_count)
- break;
-
- if (lua_isstring(L, -1)) // update line?
- {
-# ifdef HAVE_SANDBOX
- luaV_checksandbox(L);
-# endif
- ml_replace(l, luaV_toline(L, -1), TRUE);
- changed_bytes(l, 0);
- lua_pop(L, 1); // result from luaV_toline
- }
- lua_pop(L, 1); // line
- }
- lua_pop(L, 1); // function
- check_cursor();
- update_screen(UPD_NOT_VALID);
-}
-
- void
-ex_luafile(exarg_T *eap)
-{
- if (lua_init() == FAIL)
- return;
- if (!eap->skip)
- {
- luaV_setrange(L, eap->line1, eap->line2);
- if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0))
- luaV_emsg(L);
- }
-}
-
-# define luaV_freetype(typ,tname) \
- void \
- lua_##tname##_free(typ *o) \
- { \
- if (!lua_isopen()) return; \
- luaV_getfield(L, LUAMNV_FREE); \
- lua_pushlightuserdata(L, (void *) o); \
- lua_call(L, 1, 0); \
- }
-
-luaV_freetype(buf_T, buffer)
-luaV_freetype(win_T, window)
-
- void
-do_luaeval(char_u *str, typval_T *arg, typval_T *rettv)
-{
- lua_init();
- luaV_getfield(L, LUAMNV_LUAEVAL);
- lua_pushstring(L, (char *) str);
- lua_pushlightuserdata(L, (void *) arg);
- lua_pushlightuserdata(L, (void *) rettv);
- lua_call(L, 3, 0);
-}
-
- int
-set_ref_in_lua(int copyID)
-{
- int aborted = 0;
-
- if (!lua_isopen())
- return 0;
-
- luaV_getfield(L, LUAMNV_SETREF);
- // call the function with 1 arg, getting 1 result back
- lua_pushinteger(L, copyID);
- lua_call(L, 1, 1);
- // get the result
- aborted = lua_tointeger(L, -1);
- // pop result off the stack
- lua_pop(L, 1);
-
- return aborted;
-}
-
- void
-update_package_paths_in_lua(void)
-{
- if (!lua_isopen())
- return;
-
- lua_getglobal(L, "mnv");
- lua_getfield(L, -1, "_update_package_paths");
-
- if (lua_pcall(L, 0, 0, 0))
- luaV_emsg(L);
-}
-
-/*
- * Native C function callback
- */
- static int
-luaV_call_lua_func(
- int argcount,
- typval_T *argvars,
- typval_T *rettv,
- void *state)
-{
- int i;
- int luaargcount = argcount;
- luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
- lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
-
- if (funcstate->lua_tableref != LUA_NOREF)
- {
- // First arg for metatable __call method is a table
- luaargcount += 1;
- lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
- }
-
- for (i = 0; i < argcount; ++i)
- luaV_pushtypval(funcstate->L, &argvars[i]);
-
- if (lua_pcall(funcstate->L, luaargcount, 1, 0))
- {
- luaV_emsg(funcstate->L);
- return (int)FCERR_OTHER;
- }
-
- luaV_checktypval(funcstate->L, -1, rettv, "get return value");
- return (int)FCERR_NONE;
-}
-
-/*
- * Free up any lua references held by the func state.
- */
- static void
-luaV_call_lua_func_free(void *state)
-{
- luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
- luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
- funcstate->L = NULL;
- if (funcstate->lua_tableref != LUA_NOREF)
- luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
- MNV_CLEAR(funcstate);
-}
-
-#endif