luaocc/main.c

61 lines
1.4 KiB
C

#include <stdlib.h>
#include <opencc/opencc.h>
#include <lua.h>
#include <lauxlib.h>
static opencc_t *L_checkocc(lua_State *L, int i) {
opencc_t *cc = luaL_checkudata(L, i, "luaocc");
luaL_argcheck(L, cc != NULL, 1, "expected instance of opencc_t");
return cc;
}
static int L_open(lua_State *L) {
const char *fn = luaL_optstring(L, 1, NULL);
opencc_t *cc = (opencc_t*) lua_newuserdata(L, sizeof(opencc_t));
*cc = opencc_open(fn);
luaL_getmetatable(L, "luaocc");
lua_setmetatable(L, -2);
return 1;
}
static int L_convert(lua_State *L) {
opencc_t *cc = L_checkocc(L, 1);
size_t l;
const char *s = luaL_checklstring(L, 2, &l);
char *c = opencc_convert_utf8(*cc, s, l);
lua_pushstring(L, c);
opencc_convert_utf8_free(c);
return 1;
}
/* This function should not be publicly available as the user may otherwise hold an invalid reference to an opencc_t instance */
static int L_close(lua_State *L) {
opencc_t *cc = L_checkocc(L, 1);
opencc_close(*cc);
return 0;
}
static const struct luaL_Reg occlib[] = {
{"open", L_open},
{"convert", L_convert},
{NULL, NULL}
};
static const struct luaL_Reg occmt[] = {
{"__call", L_convert},
{"__gc", L_close},
{NULL, NULL}
};
#if (LUA_VERSION_NUM >= 502)
#define luaL_register(L, _, l) luaL_setfuncs(L, l, 0)
#endif
int luaopen_luaocc(lua_State *L) {
luaL_newmetatable(L, "luaocc");
luaL_register(L, NULL, occmt);
lua_newtable(L);
luaL_register(L, NULL, occlib);
return 1;
}