fix memory leak on string arguments
This commit is contained in:
parent
b195577dee
commit
d7d4385242
2 changed files with 20 additions and 5 deletions
19
src/lang.zig
19
src/lang.zig
|
@ -479,6 +479,21 @@ pub const CommandList = struct {
|
|||
pub fn deinit(self: *Self) void {
|
||||
for (self.list.items) |cmd_ptr| {
|
||||
self.list.allocator.destroy(cmd_ptr);
|
||||
inline for (@typeInfo(Command.Tag).Enum.fields) |field| {
|
||||
if (cmd_ptr.tag == @field(Command.Tag, field.name)) {
|
||||
const actual_tag =
|
||||
@field(Command.Tag, field.name);
|
||||
// if we find a match on the tag, we can get the type
|
||||
const typ = Command.tagToType(actual_tag);
|
||||
|
||||
inline for (@typeInfo(typ).Struct.fields) |cmd_field| {
|
||||
switch (cmd_field.field_type) {
|
||||
[]u8, []const u8 => self.list.allocator.destroy(@field(typ, cmd_field.name)),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.list.deinit();
|
||||
}
|
||||
|
@ -561,7 +576,7 @@ pub const Lang = struct {
|
|||
f32 => try std.fmt.parseFloat(f32, arg),
|
||||
u64 => try std.fmt.parseInt(u64, arg, 10),
|
||||
usize => try std.fmt.parseInt(usize, arg, 10),
|
||||
[]const u8 => arg,
|
||||
[]const u8 => @as([]const u8, try self.allocator.dupe(u8, arg)),
|
||||
else => @compileError("parameter struct has unsupported type " ++ @typeName(cmd_field.field_type)),
|
||||
};
|
||||
|
||||
|
@ -586,7 +601,7 @@ pub const Lang = struct {
|
|||
usize => try std.fmt.parseInt(usize, arg, 10),
|
||||
i32 => try std.fmt.parseInt(i32, arg, 10),
|
||||
f32 => try std.fmt.parseFloat(f32, arg),
|
||||
[]const u8 => arg,
|
||||
[]const u8 => @as([]const u8, try self.allocator.dupe(u8, arg)),
|
||||
else => @compileError("Invalid parameter type (" ++ @typeName(cmd_field.field_type) ++ ") left on command struct " ++ @typeName(command_struct) ++ "."),
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: anytype) !void {
|
|||
var stdout_file = std.io.getStdOut();
|
||||
const stdout = &stdout_file.writer();
|
||||
const scri_path = try (args_it.next(allocator) orelse @panic("expected scri path"));
|
||||
errdefer allocator.free(scri_path);
|
||||
defer allocator.free(scri_path);
|
||||
|
||||
var file_read_opt: ?std.fs.File = std.fs.cwd().openFile(scri_path, .{}) catch |err| blk: {
|
||||
if (err == error.FileNotFound) break :blk null;
|
||||
|
@ -54,11 +56,9 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: anytype) !void {
|
|||
defer lang.deinit();
|
||||
|
||||
if (total_bytes > 0) {
|
||||
// this MUST BE long lived (a reference to it is kept inside
|
||||
// existing_cmds, and then passed along to cmds),
|
||||
// we can't defer them here
|
||||
var scri_existing = try allocator.alloc(u8, total_bytes);
|
||||
_ = try file_read_opt.?.read(scri_existing);
|
||||
defer allocator.free(scri_existing);
|
||||
|
||||
// we can't defer this directly because we copy the
|
||||
// Command pointers to the cmds list. running deinit() directly
|
||||
|
|
Loading…
Reference in a new issue