diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1deafb0 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +# luaiconv - Performs character set conversions in Lua +# (c) 2005 Alexandre Erwin Ittner +# +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +CC=gcc +OUTFILE=libluaiconv.so +CFLAGS=-Wall +LFLAGS=-shared -llua -liconv + + +all: $(OUTFILE) + +libluagd.so: luaiconv.c + $(CC) -o $(OUTFILE) $(CFLAGS) $(LFLAGS) luaiconv.c + +install: $(OUTFILE) + cp $(OUTFILE) /usr/lib/ + +clean: + rm -f $(OUTFILE) *.o diff --git a/luaiconv.c b/luaiconv.c index 782cc77..c59f297 100644 --- a/luaiconv.c +++ b/luaiconv.c @@ -23,3 +23,101 @@ * */ + +#include +#include +#include +#include + +#define LIB_NAME "iconv" +#define ICONV_TYPENAME "iconv_t" + +#define getstring luaL_checkstring +#define getostring(L, i) luaL_optstring(L, i, NULL) + + +static void push_iconv_t(lua_State *L, iconv_t cd) +{ + lua_boxpointer(L, cd); + luaL_getmetatable(L, ICONV_TYPENAME); + lua_setmetatable(L, -2); +} + + +static iconv_t get_iconv_t(lua_State *L, int i) +{ + if(luaL_checkudata(L, i, ICONV_TYPENAME) != NULL) + { + iconv_t cd = lua_unboxpointer(L, i); + if(cd == (iconv_t) NULL) + luaL_error(L, "attempt to use an invalid " ICONV_TYPENAME); + return cd; + } + luaL_typerror(L, i, ICONV_TYPENAME); + return NULL; +} + + + + +static int Linconv_open(lua_State *L) +{ + const char *fromcode = getstring(L, 1); + const char *tocode = getstring(L, 2); + iconv_t cd iconv_open(tocode, fromcode); + if(cd != (iconv_t)(-1)) + push_iconv_t(L, cd); /* ok */ + else + lua_pushnil(L); /* erro */ + return 1; +} + + +static in Linconv_close(lua_State *L) +{ + iconv_t cd = get_iconv_t(L, 1); + if(iconv_close(cd) == 0) + lua_pushboolean(L, 1); /* ok */ + else + lua_pushnil(L); /* erro */ + return 1; +} + + + + + + + + +static const luaL_reg inconvFuncs[] = +{ + { "open", Linconv_open }, + { "new", Linconv_open }, + { "iconv", Linconv_open }, + { NULL, NULL } +}; + + +static const luaL_reg iconvMT[] = +{ + { "__gc", Liconv_close }, + { NULL, NULL } +}; + + + +int luaopen_iconv(lua_State *L) +{ + luaL_openlib(L, LIB_NAME, inconvFuncs, 0); + + lua_pushliteral(L, "metatable"); /* metatable */ + luaL_newmetatable(L, ICONV_TYPENAME); + lua_pushliteral(L, "__index"); + lua_pushvalue(L, -4); + lua_settable(L, -3); + luaL_openlib(L, NULL, iconvMT, 0); + lua_settable(L, -3); + + return 0; +} diff --git a/test_iconv.lua b/test_iconv.lua new file mode 100644 index 0000000..752ba6b --- /dev/null +++ b/test_iconv.lua @@ -0,0 +1,17 @@ + +cd = iconv.new("utf-8", "iso-8859-1") +-- cd = iconv.new("utf-8//IGNORE", "iso-8859-1") +-- cd = iconv.new("utf-8//TRANSLIT", "iso-8859-1") + +assert(cd, 'Invalid conversion') + +ret, err = cd:iconv('Isso é um teste com acentuação') + +if err == iconv.ERROR_INCOMPLETE then + print('Error: Incomplete input.') +elseif err == iconv.ERROR_INVALID then + print('Error: Invalid input.') +elseif err == nil then + print('Result: ', ret) +end +