From 7248ca65a9fd0e7bdb6704a52e8bb364069a0250 Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Wed, 18 Oct 2023 01:32:42 +0200 Subject: [PATCH] fix(open): return an error on open/new The method would not return an error message, now it does, typically if a conversion is not supported. --- README.md | 21 ++++++++++++++++++--- luaiconv.c | 14 ++++++++++---- test_iconv.lua | 30 ++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a975d2f..1107266 100644 --- a/README.md +++ b/README.md @@ -55,14 +55,29 @@ call to load up the library (that, of course, must be installed in a directory f ## API documentation ```lua -cd = iconv.new(to, from) -cd = iconv.open(to, from) +cd, err = iconv.new(to, from) +cd, err = iconv.open(to, from) ``` Opens a new conversion descriptor, from the 'from' charset to the 'to' charset. Concatenating "//TRANSLIT" to the first argument will enable character transliteration and concatenating "//IGNORE" to the first argument will cause iconv to ignore any invalid characters found in the input string. -This function returns a new converter or nil on error. +The error code, may have any of the following values: + +* `nil` + + No error. Creation was successful. + +* `iconv.ERROR_INVALID` + + The conversion from `from` to `to` is not supported by the implementation. + +* `iconv.ERROR_UNKNOWN` + + There was an unknown error. + + +This function returns a new converter or nil+err on error. ```lua diff --git a/luaiconv.c b/luaiconv.c index eff93a9..fb84b19 100644 --- a/luaiconv.c +++ b/luaiconv.c @@ -92,11 +92,17 @@ static int Liconv_open(lua_State *L) const char *tocode = luaL_checkstring(L, 1); const char *fromcode = luaL_checkstring(L, 2); iconv_t cd = iconv_open(tocode, fromcode); - if (cd != (iconv_t)(-1)) + if (cd != (iconv_t)(-1)) { push_iconv_t(L, cd); /* ok */ - else + return 1; + } else { lua_pushnil(L); /* error */ - return 1; + if (errno == EINVAL) + lua_pushnumber(L, ERROR_INVALID); + else + lua_pushnumber(L, ERROR_UNKNOWN); + return 2; + }; } /* Use a fixed-size buffer in the stack to avoid a lot of small mallocs @@ -207,7 +213,7 @@ static int Liconv_close(lua_State *L) lua_pushboolean(L, 1); /* ok */ } else - lua_pushnil(L); /* error */ + lua_pushnil(L); /* error, called from __gc, so no need for error messsage */ return 1; } diff --git a/test_iconv.lua b/test_iconv.lua index b38e22f..03c7adf 100644 --- a/test_iconv.lua +++ b/test_iconv.lua @@ -76,20 +76,30 @@ local ebcdic = "\193\150\64\147\150\149\135\133\107\64\129\150\64\147\164\129" .. "\37" +local function ErrMsg(errno) + if errno == iconv.ERROR_INCOMPLETE then + return "Incomplete input." + elseif errno == iconv.ERROR_INVALID then + return "Invalid input." + elseif errno == iconv.ERROR_NO_MEMORY then + return "Failed to allocate memory." + elseif errno == iconv.ERROR_UNKNOWN then + return "There was an unknown error." + elseif errno == iconv.FINALIZED then + return "Handle was already finalized." + end + return "Unknown error: "..tostring(errno) +end + + local function check_one(to, from, text) print("\n-- Testing conversion from " .. from .. " to " .. to) - local cd = iconv.new(to .. "//TRANSLIT", from) - assert(cd, "Failed to create a converter object.") + local cd, errno = iconv.new(to .. "//TRANSLIT", from) + assert(cd, ("Failed to create a converter object: %s"):format(ErrMsg(errno))) local ostr, err = cd:iconv(text) - if err == iconv.ERROR_INCOMPLETE then - print("ERROR: Incomplete input.") - elseif err == iconv.ERROR_INVALID then - print("ERROR: Invalid input.") - elseif err == iconv.ERROR_NO_MEMORY then - print("ERROR: Failed to allocate memory.") - elseif err == iconv.ERROR_UNKNOWN then - print("ERROR: There was an unknown error.") + if err then + print(("ERROR: %s"):format(ErrMsg(err))) end print(ostr) end