Skip to content

Commit ec0e790

Browse files
committed
Add support for lua.checkLString() and lua.checkLStringOptional()
1 parent 6cde0cd commit ec0e790

File tree

3 files changed

+105
-21
lines changed

3 files changed

+105
-21
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ you.
8686
| API | Support |
8787
|-----------------------------|---------------------------------------|
8888
| Lua C API (`lua_*`) | 🎉 100% coverage<sup>†</sup> (92/92) |
89-
| Auxilary Library (`luaL_*`) | 42% coverage (21/48) |
89+
| Auxilary Library (`luaL_*`) | 44% coverage (23/48) |
9090
| LuaJIT Extensions | *No plans to implement.* |
9191

9292
*†: Coroutine yield/resume is not yet part of the public `zig-luajit` Zig API, see [#6][ISSUE-6].*
@@ -216,6 +216,11 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
216216

217217
### Auxilary Library Coverage (`luaL_`)
218218

219+
| C Type Definition | Available in `zig-luajit` |
220+
|----------------------------|---------------------------------------------------------------------|
221+
| `luaL_Buffer` ||
222+
| `luaL_Reg` ||
223+
219224
| C API Symbol | Available in `zig-luajit` |
220225
|--------------|---------------------------|
221226
| `luaL_addchar` ||
@@ -225,7 +230,6 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
225230
| `luaL_addvalue` ||
226231
| `luaL_argcheck` | ☑️📢 `lua.checkArgument()` |
227232
| `luaL_argerror` ||
228-
| `luaL_Buffer` ||
229233
| `luaL_buffinit` ||
230234
| `luaL_callmeta` ||
231235
| `luaL_checkany` | ☑️ `lua.checkAny()`|
@@ -254,15 +258,14 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
254258
| `luaL_optinteger` | ☑️📢 `lua.checkIntegerOptional()` |
255259
| `luaL_optint` | 🆖 please use `lua.checkIntegerOptional()` |
256260
| `luaL_optlong` | 🆖 please use `lua.checkIntegerOptional()` |
257-
| `luaL_optlstring` ||
261+
| `luaL_optlstring` | ☑️📢 `lua.checkLStringOptional()` |
258262
| `luaL_optnumber` | ☑️📢 `lua.checkNumberOptional()` |
259-
| `luaL_optstring` ||
263+
| `luaL_optstring` | ☑️📢 `lua.checkStringOptional()` |
260264
| `luaL_prepbuffer` ||
261265
| `luaL_pushresult` ||
262266
| `luaL_ref` | ☑️ `lua.ref()` |
263267
| `luaL_unref` | ☑️ `lua.unref()` |
264268
| `luaL_register` ||
265-
| `luaL_Reg` ||
266269
| `luaL_typename` | ☑️ `lua.typeName()` |
267270
| `luaL_typerror` ||
268271
| `luaL_where` ||

src/lual_api.zig

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -166,22 +166,6 @@ pub fn newMetatable(lua: *Lua, tname: [*:0]const u8) i32;
166166
/// Stack Behavior: `[-0, +0, -]`
167167
pub fn newState() ?*Lua;
168168

169-
/// If the function argument narg is a string, returns this string. If this argument is absent or is nil,
170-
/// returns d. Otherwise, raises an error. If l is not null, fills the position *l with the result's length.
171-
///
172-
/// From: `const char *luaL_optlstring(lua_State *L, int narg, const char *d, size_t *l);`
173-
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_optlstring
174-
/// Stack Behavior: `[-0, +0, v]`
175-
pub fn optLString(lua: *Lua, narg: i32, default: ?[]const u8, length: ?*usize) ?[]const u8;
176-
177-
/// If the function argument narg is a string, returns this string. If this argument is absent or is nil,
178-
/// returns d. Otherwise, raises an error.
179-
///
180-
/// From: `const char *luaL_optstring(lua_State *L, int narg, const char *d);`
181-
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_optstring
182-
/// Stack Behavior: `[-0, +0, v]`
183-
pub fn optString(lua: *Lua, narg: i32, d: ?[:0]const u8) ?[:0]const u8;
184-
185169
/// Returns an address to a space of size LUAL_BUFFERSIZE where you can copy a string to be added to buffer B.
186170
/// After copying the string into this space you must call luaL_addsize with the size of the string to actually
187171
/// add it to the buffer.

src/root.zig

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,6 +2048,22 @@ pub const Lua = opaque {
20482048
}
20492049
}
20502050

2051+
/// Used by C functions to validate received arguments.
2052+
/// If the function argument `arg_n` is a string, returns this string. If this argument is absent or is nil,
2053+
/// returns d. Otherwise, raises an error.
2054+
///
2055+
/// From: `const char *luaL_optstring(lua_State *L, int narg, const char *d);`
2056+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_optstring
2057+
/// Stack Behavior: `[-0, +0, v]`
2058+
pub fn checkStringOptional(lua: *Lua, arg_n: i32, d: [*:0]const u8) [*:0]const u8 {
2059+
const string: ?[*:0]const u8 = c.luaL_optlstring(asState(lua), arg_n, d, null);
2060+
if (string) |s| {
2061+
return s;
2062+
} else {
2063+
unreachable; // If the argument is not a string or convertable to a string, the argument check should fail and the call will not return.
2064+
}
2065+
}
2066+
20512067
/// Used by C functions to validate received arguments.
20522068
/// Checks whether the function argument `arg_n` is a string and returns this string.
20532069
/// All conversions and caveats of `lua.toLString()` also apply here.
@@ -2065,6 +2081,23 @@ pub const Lua = opaque {
20652081
}
20662082
}
20672083

2084+
/// Used by C functions to validate received arguments.
2085+
/// If the function argument "arg_n" is a string, returns this string. If this argument is absent or is nil,
2086+
/// returns d. Otherwise, raises an error.
2087+
///
2088+
/// From: `const char *luaL_optlstring(lua_State *L, int narg, const char *d, size_t *l);`
2089+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_optlstring
2090+
/// Stack Behavior: `[-0, +0, v]`
2091+
pub fn checkLStringOptional(lua: *Lua, arg_n: i32, default: [:0]const u8) [:0]const u8 {
2092+
var len: usize = undefined;
2093+
const string: ?[*]const u8 = c.luaL_optlstring(asState(lua), arg_n, default, &len);
2094+
if (string) |s| {
2095+
return s[0..len :0];
2096+
} else {
2097+
unreachable; // If the argument is not a string or convertable to a string, the argument check should fail and the call will not return.
2098+
}
2099+
}
2100+
20682101
/// Used by C functions to validate received arguments.
20692102
/// Checks whether the function argument is a userdata of the specified type.
20702103
///
@@ -3622,6 +3655,38 @@ test "checkString() should validate presence of arguments and return the correct
36223655
lua.pop(1);
36233656
}
36243657

3658+
test "checkStringOptional() should validate presence of arguments and return the correct value" {
3659+
const lua = try Lua.init(std.testing.allocator);
3660+
defer lua.deinit();
3661+
3662+
const T = struct {
3663+
fn EchoString(l: *Lua) callconv(.c) i32 {
3664+
const actual = l.checkStringOptional(1, "FOO");
3665+
l.pushString(actual);
3666+
return 1;
3667+
}
3668+
};
3669+
3670+
const expected = "Who is John Galt?";
3671+
lua.pushCFunction(T.EchoString);
3672+
lua.pushString(expected);
3673+
try lua.protectedCall(1, 1, 0);
3674+
const a1 = try lua.toLString(-1);
3675+
try std.testing.expectEqualSlices(u8, expected, a1);
3676+
lua.pop(1);
3677+
3678+
lua.pushCFunction(T.EchoString);
3679+
try lua.protectedCall(0, 1, 0);
3680+
try std.testing.expectEqualSlices(u8, "FOO", (try lua.toString(-1))[0..3 :0]);
3681+
3682+
lua.pushCFunction(T.EchoString);
3683+
lua.pushInteger(42);
3684+
try lua.protectedCall(1, 1, 0);
3685+
const a3 = try lua.toLString(-1);
3686+
try std.testing.expectEqualStrings("42", a3);
3687+
lua.pop(1);
3688+
}
3689+
36253690
test "checkLString() should validate presence of arguments and return the correct value" {
36263691
const lua = try Lua.init(std.testing.allocator);
36273692
defer lua.deinit();
@@ -3655,6 +3720,38 @@ test "checkLString() should validate presence of arguments and return the correc
36553720
lua.pop(1);
36563721
}
36573722

3723+
test "checkLStringOptional() should validate presence of arguments and return the correct value" {
3724+
const lua = try Lua.init(std.testing.allocator);
3725+
defer lua.deinit();
3726+
3727+
const T = struct {
3728+
fn EchoString(l: *Lua) callconv(.c) i32 {
3729+
const actual = l.checkLStringOptional(1, "FOO");
3730+
l.pushLString(actual);
3731+
return 1;
3732+
}
3733+
};
3734+
3735+
const expected = "Who is John Galt?";
3736+
lua.pushCFunction(T.EchoString);
3737+
lua.pushLString(expected);
3738+
try lua.protectedCall(1, 1, 0);
3739+
const a1 = try lua.toLString(-1);
3740+
try std.testing.expectEqualSlices(u8, expected, a1);
3741+
lua.pop(1);
3742+
3743+
lua.pushCFunction(T.EchoString);
3744+
try lua.protectedCall(0, 1, 0);
3745+
try std.testing.expectEqualSlices(u8, "FOO", try lua.toLString(-1));
3746+
3747+
lua.pushCFunction(T.EchoString);
3748+
lua.pushInteger(42);
3749+
try lua.protectedCall(1, 1, 0);
3750+
const a3 = try lua.toLString(-1);
3751+
try std.testing.expectEqualSlices(u8, "42", a3);
3752+
lua.pop(1);
3753+
}
3754+
36583755
test "checkAny should validate presence of arguments" {
36593756
const lua = try Lua.init(std.testing.allocator);
36603757
defer lua.deinit();

0 commit comments

Comments
 (0)