fix: memory leaks on error handling
This commit is contained in:
parent
3ac2f0202c
commit
a371b10180
@ -67,6 +67,7 @@ fn prefixed(
|
|||||||
if (end_position >= cap or !validator(input[end_position])) {
|
if (end_position >= cap or !validator(input[end_position])) {
|
||||||
// populate error information
|
// populate error information
|
||||||
try err.init("Incomplete number", start, end_position, alloc);
|
try err.init("Incomplete number", start, end_position, alloc);
|
||||||
|
try err.add_label("Expected a valid digit after the '" ++ [_]u8{prefix} ++ "'", start, end_position);
|
||||||
|
|
||||||
// throw error
|
// throw error
|
||||||
return LexError.Incomplete;
|
return LexError.Incomplete;
|
||||||
@ -303,6 +304,7 @@ test "shouldnt parse incomplete hex number" {
|
|||||||
defer std.testing.allocator.destroy(errdata);
|
defer std.testing.allocator.destroy(errdata);
|
||||||
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
||||||
try std.testing.expect(err == token.LexError.Incomplete);
|
try std.testing.expect(err == token.LexError.Incomplete);
|
||||||
|
defer errdata.deinit();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -322,6 +324,7 @@ test "shouldnt parse incomplete hex number 2" {
|
|||||||
defer std.testing.allocator.destroy(errdata);
|
defer std.testing.allocator.destroy(errdata);
|
||||||
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
||||||
try std.testing.expect(err == token.LexError.Incomplete);
|
try std.testing.expect(err == token.LexError.Incomplete);
|
||||||
|
defer errdata.deinit();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -365,6 +368,7 @@ test "shouldnt parse incomplete octal number" {
|
|||||||
defer std.testing.allocator.destroy(errdata);
|
defer std.testing.allocator.destroy(errdata);
|
||||||
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
||||||
try std.testing.expect(err == token.LexError.Incomplete);
|
try std.testing.expect(err == token.LexError.Incomplete);
|
||||||
|
defer errdata.deinit();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -396,6 +400,7 @@ test "shouldnt parse incomplete binary number" {
|
|||||||
defer std.testing.allocator.destroy(errdata);
|
defer std.testing.allocator.destroy(errdata);
|
||||||
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
const result = lex(input, input.len, 0, errdata, std.testing.allocator) catch |err| {
|
||||||
try std.testing.expect(err == token.LexError.Incomplete);
|
try std.testing.expect(err == token.LexError.Incomplete);
|
||||||
|
defer errdata.deinit();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,6 +214,7 @@ test "should handle recoverable errors" {
|
|||||||
const input = "322 0b 644";
|
const input = "322 0b 644";
|
||||||
var error_list = std.ArrayList(errors.ErrorData).init(std.testing.allocator);
|
var error_list = std.ArrayList(errors.ErrorData).init(std.testing.allocator);
|
||||||
defer error_list.deinit();
|
defer error_list.deinit();
|
||||||
|
defer for (error_list.items) |*err| err.deinit();
|
||||||
const arrl = try tokenize(input, std.testing.allocator, &error_list);
|
const arrl = try tokenize(input, std.testing.allocator, &error_list);
|
||||||
defer arrl.deinit();
|
defer arrl.deinit();
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ pub const LexError = error{
|
|||||||
IncompleteScientificNumber,
|
IncompleteScientificNumber,
|
||||||
IncompleteString,
|
IncompleteString,
|
||||||
CRLF,
|
CRLF,
|
||||||
|
OutOfMemory,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Contains the lexed token and the next position
|
/// Contains the lexed token and the next position
|
||||||
|
@ -10,6 +10,7 @@ pub const ErrorLabel = struct {
|
|||||||
/// and pretty prints them.
|
/// and pretty prints them.
|
||||||
pub const ErrorData = struct {
|
pub const ErrorData = struct {
|
||||||
reason: []const u8,
|
reason: []const u8,
|
||||||
|
help: ?[]const u8,
|
||||||
start_position: usize,
|
start_position: usize,
|
||||||
end_position: usize,
|
end_position: usize,
|
||||||
labels: std.ArrayList(ErrorLabel),
|
labels: std.ArrayList(ErrorLabel),
|
||||||
@ -27,6 +28,7 @@ pub const ErrorData = struct {
|
|||||||
.start_position = start_position,
|
.start_position = start_position,
|
||||||
.end_position = end_position,
|
.end_position = end_position,
|
||||||
.labels = std.ArrayList(ErrorLabel).init(alloc),
|
.labels = std.ArrayList(ErrorLabel).init(alloc),
|
||||||
|
.help = null,
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -39,6 +41,11 @@ pub const ErrorData = struct {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the help message of this error.
|
||||||
|
pub fn set_help(self: *@This(), help: []const u8) void {
|
||||||
|
self.help = help;
|
||||||
|
}
|
||||||
|
|
||||||
/// Generates an error string. `alloc` is used to create the string,
|
/// Generates an error string. `alloc` is used to create the string,
|
||||||
/// the caller should call `free` on the returning slice.
|
/// the caller should call `free` on the returning slice.
|
||||||
pub fn get_error_str(self: *@This(), source_code: []const u8, filename: []const u8, alloc: std.mem.Allocator) ![]u8 {
|
pub fn get_error_str(self: *@This(), source_code: []const u8, filename: []const u8, alloc: std.mem.Allocator) ![]u8 {
|
||||||
@ -238,6 +245,7 @@ test "should gen error message" {
|
|||||||
const source = "print(ehh)";
|
const source = "print(ehh)";
|
||||||
var err = ErrorData{
|
var err = ErrorData{
|
||||||
.reason = "Invalid identifier",
|
.reason = "Invalid identifier",
|
||||||
|
.help = null,
|
||||||
.start_position = 6,
|
.start_position = 6,
|
||||||
.end_position = 9,
|
.end_position = 9,
|
||||||
.labels = std.ArrayList(ErrorLabel).init(std.testing.allocator),
|
.labels = std.ArrayList(ErrorLabel).init(std.testing.allocator),
|
||||||
@ -256,6 +264,7 @@ test "should gen error message with label (1)" {
|
|||||||
const source = "print(ehh)";
|
const source = "print(ehh)";
|
||||||
var err = ErrorData{
|
var err = ErrorData{
|
||||||
.reason = "Invalid identifier",
|
.reason = "Invalid identifier",
|
||||||
|
.help = null,
|
||||||
.start_position = 6,
|
.start_position = 6,
|
||||||
.end_position = 9,
|
.end_position = 9,
|
||||||
.labels = std.ArrayList(ErrorLabel).init(std.testing.allocator),
|
.labels = std.ArrayList(ErrorLabel).init(std.testing.allocator),
|
||||||
|
Loading…
Reference in New Issue
Block a user