Skip to content

Commit d92b49f

Browse files
committed
Add support for lua.raiseErrorType() and lua.where() to complete 100% Auxilary library coverage ⭐⭐⭐
1 parent b3cc713 commit d92b49f

File tree

3 files changed

+89
-50
lines changed

3 files changed

+89
-50
lines changed

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ you.
8383

8484
## Language Binding Coverage Progress
8585

86-
| API | Support |
87-
|-----------------------------|---------------------------------------|
88-
| Lua C API (`lua_*`) | 🎉 100% coverage<sup>†</sup> (92/92) |
89-
| Auxilary Library (`luaL_*`) | 🤩 96% coverage (46/48) |
90-
| LuaJIT Extensions | *No plans to implement.* |
86+
| API | Support |
87+
|-------------------------------|---------------------------------------|
88+
| Lua C API (`lua_*`) | 🎉 100% coverage<sup>†</sup> (92/92) |
89+
| Auxilary Library (`luaL_*`) | 🤩 100% coverage (48/48) |
90+
| Debug Interface (`lua_Debug`) | 0% coverage (0/12) |
91+
| LuaJIT Extensions | *No plans to implement.* |
9192

9293
*†: Coroutine yield/resume is not yet part of the public `zig-luajit` Zig API, see [#6][ISSUE-6].*
9394

@@ -267,8 +268,8 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
267268
| `luaL_unref` | ☑️ `lua.unref()` |
268269
| `luaL_register` | ☑️📢 `lua.registerLibrary()` |
269270
| `luaL_typename` | ☑️ `lua.getTypeNameAt()` |
270-
| `luaL_typerror` ||
271-
| `luaL_where` ||
271+
| `luaL_typerror` | ☑️📢 `lua.raiseErrorType()` |
272+
| `luaL_where` | ☑️ `lua.where()` |
272273

273274
## Additions to the API in `zig-luajit`
274275

src/lual_api.zig

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/root.zig

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -937,18 +937,18 @@ pub const Lua = opaque {
937937
}
938938

939939
fn typeIsNotString(t: Lua.Type) NotStringError {
940-
return switch (t) {
940+
switch (t) {
941941
.number, .string => unreachable,
942942

943-
.none => error.NoneIsNotString,
944-
.nil => error.NilIsNotString,
945-
.boolean => error.BooleanIsNotString,
946-
.light_userdata => error.LightUserdataIsNotString,
947-
.table => error.TableIsNotString,
948-
.function => error.FunctionIsNotString,
949-
.userdata => error.UserdataIsNotString,
950-
.thread => error.ThreadIsNotString,
951-
};
943+
.none => return error.NoneIsNotString,
944+
.nil => return error.NilIsNotString,
945+
.boolean => return error.BooleanIsNotString,
946+
.light_userdata => return error.LightUserdataIsNotString,
947+
.table => return error.TableIsNotString,
948+
.function => return error.FunctionIsNotString,
949+
.userdata => return error.UserdataIsNotString,
950+
.thread => return error.ThreadIsNotString,
951+
}
952952
}
953953

954954
/// Creates a new empty table and pushes it onto the stack. It is equivalent to calling `createTable` with
@@ -2364,6 +2364,32 @@ pub const Lua = opaque {
23642364
unreachable;
23652365
}
23662366

2367+
/// Raises an error with a message like "<location>: bad argument #<arg_n> to '<func>' (<type_name> expected, got <actual_type>)",
2368+
/// where `location` is produced by `where()`, `func` is the name of the current chunk, and `actual_type` is the type
2369+
/// name of the actual argument.
2370+
///
2371+
/// From: `int luaL_typerror(lua_State *L, int narg, const char *tname);`
2372+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_typerror
2373+
/// Stack Behavior: `[-0, +0, v]`
2374+
pub fn raiseErrorType(lua: *Lua, arg_n: i32, type_name: ?[:0]const u8) noreturn {
2375+
_ = c.luaL_typerror(asState(lua), arg_n, if (type_name) |t| t.ptr else null);
2376+
unreachable;
2377+
}
2378+
2379+
/// Pushes onto the stack a string identifying the current position of the control at the given level in the call stack.
2380+
/// Typically this string has the format: `chunkname:currentline:`.
2381+
///
2382+
/// Level 0 is the running function, level 1 is the function that called the running function, etc.
2383+
/// This function is used to build a prefix for error messages.
2384+
///
2385+
/// From: `void luaL_where(lua_State *L, int lvl);`
2386+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_where
2387+
/// Stack Behavior: `[-0, +1, m]`
2388+
pub fn where(lua: *Lua, level: i32) void {
2389+
assert(level >= 0);
2390+
return c.luaL_where(asState(lua), level);
2391+
}
2392+
23672393
/// Represents named functions that belong to a library that can be registered by a call to the `registerLibrary()`
23682394
/// function.
23692395
///
@@ -4458,6 +4484,51 @@ test "raiseErrorArgument() should return correct error messages" {
44584484
try std.testing.expectEqualSlices(u8, "bad argument #1 to '?' ((null))", try lua.toLString(-1));
44594485
}
44604486

4487+
test "raiseErrorType() should return correct error messages" {
4488+
const lua = try Lua.init(std.testing.allocator);
4489+
defer lua.deinit();
4490+
4491+
const T = struct {
4492+
fn FullError(l: *Lua) callconv(.c) i32 {
4493+
return l.raiseErrorType(1, "FOO");
4494+
}
4495+
fn NullError(l: *Lua) callconv(.c) i32 {
4496+
return l.raiseErrorType(1, null);
4497+
}
4498+
};
4499+
4500+
lua.pushCFunction(T.FullError);
4501+
lua.pushInteger(1);
4502+
try std.testing.expectError(error.Runtime, lua.callProtected(1, 1, 0));
4503+
try std.testing.expectEqualSlices(u8, "bad argument #1 to '?' (FOO expected, got number)", try lua.toLString(-1));
4504+
4505+
lua.pushCFunction(T.NullError);
4506+
lua.pushInteger(1);
4507+
try std.testing.expectError(error.Runtime, lua.callProtected(1, 1, 0));
4508+
try std.testing.expectEqualSlices(u8, "bad argument #1 to '?' ((null) expected, got number)", try lua.toLString(-1));
4509+
}
4510+
4511+
test "where() should report correct location" {
4512+
const lua = try Lua.init(std.testing.allocator);
4513+
defer lua.deinit();
4514+
4515+
const T = struct {
4516+
fn whereFn(l: *Lua) callconv(.c) i32 {
4517+
l.where(1);
4518+
return 1;
4519+
}
4520+
};
4521+
lua.registerFunction("whereFn", T.whereFn);
4522+
try lua.doString("actual = whereFn()");
4523+
4524+
try std.testing.expectEqual(Lua.Type.string, lua.getGlobal("actual"));
4525+
try std.testing.expectEqual(1, lua.getTop());
4526+
try std.testing.expectEqualStrings(
4527+
"[string \"actual = whereFn()\"]:1: ",
4528+
try lua.toLString(-1),
4529+
);
4530+
}
4531+
44614532
test "ref and unref in user table" {
44624533
const lua = try Lua.init(std.testing.allocator);
44634534
defer lua.deinit();

0 commit comments

Comments
 (0)