Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many changes to String and Bytes functions #72

Merged
merged 7 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 43 additions & 68 deletions src/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1497,12 +1497,14 @@ pub const Lua = struct {

/// Push a formatted string onto the stack and return a pointer to the string
/// See https://www.lua.org/manual/5.4/manual.html#lua_pushfstring
pub fn pushFString(lua: *Lua, fmt: [:0]const u8, args: anytype) [*:0]const u8 {
return @call(
pub fn pushFString(lua: *Lua, fmt: [:0]const u8, args: anytype) [:0]const u8 {
const ptr = @call(
.auto,
if (lang == .luau) c.lua_pushfstringL else c.lua_pushfstring,
.{ lua.state, fmt.ptr } ++ args,
);
const l = lua.rawLen(-1);
return ptr[0..l :0];
}

/// Pushes the global environment onto the stack
Expand All @@ -1526,19 +1528,17 @@ pub const Lua = struct {
c.lua_pushlightuserdata(lua.state, ptr);
}

const BytesResult = switch (lang) {
/// Pushes the string onto the stack. Returns a slice pointing to Lua's internal copy of the string
/// See https://www.lua.org/manual/5.4/manual.html#lua_pushlstring
pub fn pushString(lua: *Lua, str: []const u8) switch (lang) {
.lua51, .luajit, .luau => void,
else => []const u8,
};

/// Pushes the bytes onto the stack. Returns a slice pointing to Lua's internal copy of the string
/// See https://www.lua.org/manual/5.4/manual.html#lua_pushlstring
pub fn pushBytes(lua: *Lua, bytes: []const u8) BytesResult {
} {
switch (lang) {
.lua51, .luajit, .luau => {
c.lua_pushlstring(lua.state, bytes.ptr, bytes.len);
c.lua_pushlstring(lua.state, str.ptr, str.len);
},
else => return c.lua_pushlstring(lua.state, bytes.ptr, bytes.len)[0..bytes.len],
else => return c.lua_pushlstring(lua.state, str.ptr, str.len)[0..str.len],
}
}

Expand All @@ -1554,16 +1554,14 @@ pub const Lua = struct {
c.lua_pushnumber(lua.state, n);
}

const StringResult = switch (lang) {
.lua51, .luajit, .luau => void,
else => [:0]const u8,
};

/// Pushes a zero-terminated string onto the stack
/// Lua makes a copy of the string so `str` may be freed immediately after return
/// Returns a pointer to the internal Lua string
/// See https://www.lua.org/manual/5.4/manual.html#lua_pushstring
pub fn pushString(lua: *Lua, str: [:0]const u8) StringResult {
pub fn pushStringZ(lua: *Lua, str: [:0]const u8) switch (lang) {
.lua51, .luajit, .luau => void,
else => [:0]const u8,
} {
switch (lang) {
.lua51, .luajit, .luau => {
c.lua_pushstring(lua.state, str.ptr);
Expand Down Expand Up @@ -1931,16 +1929,6 @@ pub const Lua = struct {
else => toInteger52,
};

/// Returns a slice of bytes at the given index
/// If the value is not a string or number, returns an error
/// If the value was a number the actual value in the stack will be changed to a string
/// See https://www.lua.org/manual/5.4/manual.html#lua_tolstring
pub fn toBytes(lua: *Lua, index: i32) ![:0]const u8 {
var length: usize = undefined;
if (c.lua_tolstring(lua.state, index, &length)) |ptr| return ptr[0..length :0];
return error.Fail;
}

fn toNumber51(lua: *Lua, index: i32) Number {
return c.lua_tonumber(lua.state, index);
}
Expand Down Expand Up @@ -1972,9 +1960,9 @@ pub const Lua = struct {
/// Returns an error if the conversion failed
/// If the value was a number the actual value in the stack will be changed to a string
/// See https://www.lua.org/manual/5.4/manual.html#lua_tostring
pub fn toString(lua: *Lua, index: i32) ![*:0]const u8 {
pub fn toString(lua: *Lua, index: i32) ![:0]const u8 {
var length: usize = undefined;
if (c.lua_tolstring(lua.state, index, &length)) |str| return str;
if (c.lua_tolstring(lua.state, index, &length)) |ptr| return ptr[0..length :0];
return error.Fail;
}

Expand Down Expand Up @@ -2389,8 +2377,8 @@ pub const Lua = struct {

/// Raises an error reporting a problem with argument `arg` of the C function that called it
/// See https://www.lua.org/manual/5.4/manual.html#luaL_argerror
pub fn argError(lua: *Lua, arg: i32, extra_msg: [*:0]const u8) noreturn {
_ = c.luaL_argerror(lua.state, arg, extra_msg);
pub fn argError(lua: *Lua, arg: i32, extra_msg: [:0]const u8) noreturn {
_ = c.luaL_argerror(lua.state, arg, extra_msg.ptr);
unreachable;
}

Expand Down Expand Up @@ -2427,15 +2415,6 @@ pub const Lua = struct {
return c.luaL_checkinteger(lua.state, arg);
}

/// Checks whether the function argument `arg` is a slice of bytes and returns the slice
/// See https://www.lua.org/manual/5.4/manual.html#luaL_checklstring
pub fn checkBytes(lua: *Lua, arg: i32) [:0]const u8 {
var length: usize = 0;
const str = c.luaL_checklstring(lua.state, arg, &length);
// luaL_checklstring never returns null (throws lua error)
return str[0..length :0];
}

/// Checks whether the function argument `arg` is a number and returns the number
/// See https://www.lua.org/manual/5.4/manual.html#luaL_checknumber
pub fn checkNumber(lua: *Lua, arg: i32) Number {
Expand All @@ -2450,9 +2429,9 @@ pub const Lua = struct {
pub fn checkOption(lua: *Lua, comptime T: type, arg: i32, default: ?T) T {
const name = blk: {
if (default) |defaultName| {
break :blk lua.optBytes(arg, @tagName(defaultName));
break :blk lua.optString(arg, @tagName(defaultName));
} else {
break :blk lua.checkBytes(arg);
break :blk lua.checkString(arg);
}
};

Expand All @@ -2468,14 +2447,17 @@ pub const Lua = struct {
/// Grows the stack size to top + `size` elements, raising an error if the stack cannot grow to that size
/// `msg` is an additional text to go into the error message
/// See https://www.lua.org/manual/5.4/manual.html#luaL_checkstack
pub fn checkStackErr(lua: *Lua, size: i32, msg: ?[*:0]const u8) void {
c.luaL_checkstack(lua.state, size, msg);
pub fn checkStackErr(lua: *Lua, size: i32, msg: ?[:0]const u8) void {
c.luaL_checkstack(lua.state, size, if (msg) |m| m.ptr else null);
}

/// Checks whether the function argument `arg` is a string and returns the string
/// See https://www.lua.org/manual/5.4/manual.html#luaL_checkstring
pub fn checkString(lua: *Lua, arg: i32) [*:0]const u8 {
return c.luaL_checklstring(lua.state, arg, null);
pub fn checkString(lua: *Lua, arg: i32) [:0]const u8 {
var length: usize = 0;
const str = c.luaL_checklstring(lua.state, arg, &length);
// luaL_checklstring never returns null (throws lua error)
return str[0..length :0];
}

/// Checks whether the function argument `arg` has type `t`
Expand Down Expand Up @@ -2770,17 +2752,6 @@ pub const Lua = struct {
return c.luaL_optinteger(lua.state, arg, default);
}

/// If the function argument `arg` is a slice of bytes, returns the slice
/// If the argument is absent or nil returns `default`
/// See https://www.lua.org/manual/5.4/manual.html#luaL_optlstring
pub fn optBytes(lua: *Lua, arg: i32, default: [:0]const u8) [:0]const u8 {
var length: usize = 0;
// will never return null because default cannot be null
const ret: [*]const u8 = c.luaL_optlstring(lua.state, arg, default.ptr, &length);
if (ret == default.ptr) return default;
return ret[0..length :0];
}

/// If the function argument `arg` is a number, returns the number
/// If the argument is absent or nil returns `default`
/// See https://www.lua.org/manual/5.4/manual.html#luaL_optnumber
Expand All @@ -2791,9 +2762,12 @@ pub const Lua = struct {
/// If the function argument `arg` is a string, returns the string
/// If the argment is absent or nil returns `default`
/// See https://www.lua.org/manual/5.4/manual.html#luaL_optstring
pub fn optString(lua: *Lua, arg: i32, default: [:0]const u8) [*:0]const u8 {
// translate-c error
return c.luaL_optlstring(lua.state, arg, default.ptr, null);
pub fn optString(lua: *Lua, arg: i32, default: [:0]const u8) [:0]const u8 {
var length: usize = 0;
// will never return null because default cannot be null
const ret: [*]const u8 = c.luaL_optlstring(lua.state, arg, default.ptr, &length);
if (ret == default.ptr) return default;
return ret[0..length :0];
}

/// If the function argument is a number, returns this number as an unsigned
Expand Down Expand Up @@ -2853,7 +2827,7 @@ pub const Lua = struct {
switch (lang) {
.lua51, .luajit, .luau => {
lua.pushFunction(open_fn);
_ = lua.pushString(mod_name);
_ = lua.pushStringZ(mod_name);
lua.call(1, 0);
},
else => c.luaL_requiref(lua.state, mod_name.ptr, open_fn, @intFromBool(global)),
Expand Down Expand Up @@ -2902,8 +2876,9 @@ pub const Lua = struct {
}

/// Converts any Lua value at the given index into a string in a reasonable format
/// Uses the __tostring metamethod if available
/// See https://www.lua.org/manual/5.4/manual.html#luaL_tolstring
pub fn toBytesFmt(lua: *Lua, index: i32) [:0]const u8 {
pub fn toStringEx(lua: *Lua, index: i32) [:0]const u8 {
var length: usize = undefined;
const ptr = c.luaL_tolstring(lua.state, index, &length);
return ptr[0..length :0];
Expand Down Expand Up @@ -3034,7 +3009,7 @@ pub const Lua = struct {
if (casted.* != 0) {
@compileError("Sentinel of slice must be a null terminator");
}
_ = lua.pushString(value);
_ = lua.pushStringZ(value);
},
.C, .Many, .Slice => {
std.debug.assert(info.child == u8);
Expand All @@ -3043,11 +3018,11 @@ pub const Lua = struct {
if (casted.* != 0) {
@compileError("Sentinel of slice must be a null terminator");
}
_ = lua.pushString(value);
_ = lua.pushStringZ(value);
} else {
const null_terminated = try lua.allocator().dupeZ(u8, value);
defer lua.allocator().free(null_terminated);
_ = lua.pushString(null_terminated);
_ = lua.pushStringZ(null_terminated);
}
},
}
Expand Down Expand Up @@ -3101,7 +3076,7 @@ pub const Lua = struct {
lua.pushBoolean(value);
},
.Enum => {
_ = lua.pushString(@tagName(value));
_ = lua.pushStringZ(@tagName(value));
},
.Optional, .Null => {
if (value == null) {
Expand Down Expand Up @@ -3345,7 +3320,7 @@ pub const Lua = struct {

inline for (@typeInfo(T).Struct.fields) |field| {
const field_name = comptime field.name ++ "";
_ = lua.pushString(field_name);
_ = lua.pushStringZ(field_name);

const lua_field_type = lua.getTable(index);
defer lua.pop(1);
Expand Down Expand Up @@ -3520,7 +3495,7 @@ pub const Buffer = struct {

/// Adds the string to the buffer
/// See https://www.lua.org/manual/5.4/manual.html#luaL_addlstring
pub fn addBytes(buf: *Buffer, str: []const u8) void {
pub fn addString(buf: *Buffer, str: []const u8) void {
c.luaL_addlstring(&buf.b, str.ptr, str.len);
}

Expand All @@ -3539,7 +3514,7 @@ pub const Buffer = struct {

/// Adds the zero-terminated string pointed to by `str` to the buffer
/// See https://www.lua.org/manual/5.4/manual.html#luaL_addstring
pub fn addString(buf: *Buffer, str: [:0]const u8) void {
pub fn addStringZ(buf: *Buffer, str: [:0]const u8) void {
switch (lang) {
.luau => c.luaL_addlstring(&buf.b, str.ptr, str.len),
else => c.luaL_addstring(&buf.b, str.ptr),
Expand Down
Loading
Loading