From: Alexander Turenko <alexander.turenko@tarantool.org> To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Cc: tarantool-patches@dev.tarantool.org, Alexander Turenko <alexander.turenko@tarantool.org> Subject: [Tarantool-patches] [PATCH v3 03/16] module api/lua: add luaL_iscdata() function Date: Tue, 13 Oct 2020 02:23:10 +0300 [thread overview] Message-ID: <78be0c27f3d7f28da615c98603889551a72cfca2.1602541394.git.alexander.turenko@tarantool.org> (raw) In-Reply-To: <cover.1602541394.git.alexander.turenko@tarantool.org> It is useful to provide a module specific error when cdata expected, but a value of another type is passed. Alternative would be using of lua_type() to check against LUA_TCDATA, but this constant is not exposed for modules. See more in the luaL_iscdata() API comment. Part of #5273 --- src/exports.h | 1 + src/lua/utils.c | 6 +++ src/lua/utils.h | 20 ++++++++++ test/app-tap/module_api.c | 22 +++++++++++ test/app-tap/module_api.test.lua | 63 +++++++++++++++++++++++++++++++- 5 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/exports.h b/src/exports.h index 7861bb529..01c1aa83e 100644 --- a/src/exports.h +++ b/src/exports.h @@ -356,6 +356,7 @@ EXPORT(luaL_findtable) EXPORT(luaL_getmetafield) EXPORT(luaL_gsub) EXPORT(luaL_iscallable) +EXPORT(luaL_iscdata) EXPORT(luaL_loadbuffer) EXPORT(luaL_loadbufferx) EXPORT(luaL_loadfile) diff --git a/src/lua/utils.c b/src/lua/utils.c index 399bec6c6..3e1c491f8 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -113,6 +113,12 @@ luaL_pushuuid(struct lua_State *L) return luaL_pushcdata(L, CTID_UUID); } +int +luaL_iscdata(struct lua_State *L, int idx) +{ + return lua_type(L, idx) == LUA_TCDATA; +} + void * luaL_checkcdata(struct lua_State *L, int idx, uint32_t *ctypeid) { diff --git a/src/lua/utils.h b/src/lua/utils.h index 7e02a05f2..e80e2b1a2 100644 --- a/src/lua/utils.h +++ b/src/lua/utils.h @@ -78,6 +78,26 @@ luaL_pushuuid(struct lua_State *L); /** \cond public */ +/** + * Checks whether a value on the Lua stack is a cdata. + * + * Unlike <luaL_checkcdata>() this function does not raise an + * error. It is useful to raise a domain specific error. + * + * Lua API and module API don't expose LUA_TCDATA constant. + * We have no guarantee that this constant will remain the same in + * future LuaJIT versions. So this function should be used in + * modules instead of `lua_type(L, idx) == LUA_TCDATA`. + * + * @param L Lua state. + * @param idx Acceptable index on the Lua stack. + * + * @retval 1 If the value at the given index is a cdata. + * @retval 0 Otherwise. + */ +LUA_API int +luaL_iscdata(struct lua_State *L, int idx); + /** * @brief Push cdata of given \a ctypeid onto the stack. * CTypeID must be used from FFI at least once. Allocated memory returned diff --git a/test/app-tap/module_api.c b/test/app-tap/module_api.c index 12d20e886..fa5388ba0 100644 --- a/test/app-tap/module_api.c +++ b/test/app-tap/module_api.c @@ -455,6 +455,27 @@ test_iscallable(lua_State *L) return 1; } +static int +test_iscdata(struct lua_State *L) +{ + assert(lua_gettop(L) == 2); + + int exp = lua_toboolean(L, 2); + + /* Basic test. */ + int res = luaL_iscdata(L, 1); + int ok = res == exp; + assert(lua_gettop(L) == 2); + + /* Use negative index. */ + res = luaL_iscdata(L, -2); + ok = ok && res == exp; + assert(lua_gettop(L) == 2); + + lua_pushboolean(L, res == exp); + return 1; +} + /* {{{ test_box_region */ /** @@ -562,6 +583,7 @@ luaopen_module_api(lua_State *L) {"test_state", test_state}, {"test_tostring", test_tostring}, {"iscallable", test_iscallable}, + {"iscdata", test_iscdata}, {"test_box_region", test_box_region}, {NULL, NULL} }; diff --git a/test/app-tap/module_api.test.lua b/test/app-tap/module_api.test.lua index 08e8add35..0231dc3b0 100755 --- a/test/app-tap/module_api.test.lua +++ b/test/app-tap/module_api.test.lua @@ -116,8 +116,68 @@ local function test_iscallable(test, module) end end +local function test_iscdata(test, module) + local ffi = require('ffi') + ffi.cdef([[ + struct foo { int bar; }; + ]]) + + local cases = { + { + obj = nil, + exp = false, + description = 'nil', + }, + { + obj = 1, + exp = false, + description = 'number', + }, + { + obj = 'hello', + exp = false, + description = 'string', + }, + { + obj = {}, + exp = false, + description = 'table', + }, + { + obj = function() end, + exp = false, + description = 'function', + }, + { + obj = ffi.new('struct foo'), + exp = true, + description = 'cdata', + }, + { + obj = ffi.new('struct foo *'), + exp = true, + description = 'cdata pointer', + }, + { + obj = ffi.new('struct foo &'), + exp = true, + description = 'cdata reference', + }, + { + obj = 1LL, + exp = true, + description = 'cdata number', + }, + } + + test:plan(#cases) + for _, case in ipairs(cases) do + test:ok(module.iscdata(case.obj, case.exp), case.description) + end +end + local test = require('tap').test("module_api", function(test) - test:plan(25) + test:plan(26) local status, module = pcall(require, 'module_api') test:is(status, true, "module") test:ok(status, "module is loaded") @@ -143,6 +203,7 @@ local test = require('tap').test("module_api", function(test) test:test("pushcdata", test_pushcdata, module) test:test("iscallable", test_iscallable, module) + test:test("iscdata", test_iscdata, module) space:drop() end) -- 2.25.0
next prev parent reply other threads:[~2020-10-12 23:23 UTC|newest] Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-12 23:23 [Tarantool-patches] [PATCH v3 00/16] module api: extend for external key_def Lua module Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 01/16] module api: get rid of typedef redefinitions Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 02/16] module api: expose box region Alexander Turenko 2020-10-14 23:41 ` Vladislav Shpilevoy 2020-10-15 13:17 ` Alexander Turenko 2020-10-12 23:23 ` Alexander Turenko [this message] 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 04/16] lua: factor out tuple encoding from luaT_tuple_new Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 05/16] lua: don't raise a Lua error from luaT_tuple_new() Alexander Turenko 2020-10-14 23:41 ` Vladislav Shpilevoy 2020-10-15 13:17 ` Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 06/16] module api/lua: add luaT_tuple_encode() Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 07/16] module api/lua: expose luaT_tuple_new() Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 08/16] module api/lua: add API_EXPORT to tuple functions Alexander Turenko 2020-10-14 23:41 ` Vladislav Shpilevoy 2020-10-15 2:35 ` Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 09/16] module api: add API_EXPORT to key_def functions Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 10/16] module api: add box_key_def_new_v2() Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 11/16] module api: add box_key_def_dump_parts() Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 12/16] module api: expose box_key_def_validate_tuple() Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 13/16] module api: expose box_key_def_merge() Alexander Turenko 2020-10-14 23:41 ` Vladislav Shpilevoy 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 14/16] module api: expose box_key_def_extract_key() Alexander Turenko 2020-10-14 23:41 ` Vladislav Shpilevoy 2020-10-15 2:39 ` Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 15/16] module api: add box_key_def_validate_key() Alexander Turenko 2020-10-14 23:41 ` Vladislav Shpilevoy 2020-10-15 13:18 ` Alexander Turenko 2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 16/16] module api: add box_key_def_validate_full_key() Alexander Turenko 2020-10-14 23:41 ` [Tarantool-patches] [PATCH v3 00/16] module api: extend for external key_def Lua module Vladislav Shpilevoy 2020-10-15 3:09 ` Alexander Turenko 2020-10-15 13:19 ` Alexander Turenko 2020-10-16 6:05 ` Alexander Turenko 2020-10-15 20:12 ` Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=78be0c27f3d7f28da615c98603889551a72cfca2.1602541394.git.alexander.turenko@tarantool.org \ --to=alexander.turenko@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v3 03/16] module api/lua: add luaL_iscdata() function' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox