parser: ostensibly fix sentinel handling
I guess arrays don't need special handling because their memory is explicitly accounted for, but it would probably be good to check that a sentinel-terminated array initialized as `undefined` does get the correct sentinel value.
This commit is contained in:
parent
f371f16e2f
commit
ce65dee71f
@ -9,7 +9,7 @@ const Example = struct {
|
|||||||
useful: bool,
|
useful: bool,
|
||||||
number: i32,
|
number: i32,
|
||||||
string: []const u8,
|
string: []const u8,
|
||||||
longstring: []const u8,
|
longstring: [:0]const u8,
|
||||||
tuple: struct { bool, i8 },
|
tuple: struct { bool, i8 },
|
||||||
enume: enum { first, second, third },
|
enume: enum { first, second, third },
|
||||||
taggart: union(enum) { first: []const u8, second: i32 },
|
taggart: union(enum) { first: []const u8, second: i32 },
|
||||||
|
@ -118,16 +118,30 @@ pub const Value = union(enum) {
|
|||||||
// type to use for this? the problem is that it becomes
|
// type to use for this? the problem is that it becomes
|
||||||
// invasive into downstream code. Ultimately this should
|
// invasive into downstream code. Ultimately this should
|
||||||
// probably be solved in the zig stdlib or similar.
|
// probably be solved in the zig stdlib or similar.
|
||||||
// TODO: This also doesn't handle sentinels properly.
|
|
||||||
switch (self) {
|
switch (self) {
|
||||||
.scalar, .string => |str| return if (ptr.child == u8) str else error.BadValue,
|
.scalar, .string => |str| {
|
||||||
|
if (ptr.child == u8) {
|
||||||
|
if (ptr.sentinel) |sent| {
|
||||||
|
var copy = try allocator.allocSentinel(u8, str.len, @as(*const u8, @ptrCast(sent)).*);
|
||||||
|
@memcpy(copy, str);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
return error.BadValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
.list, .inline_list => |lst| {
|
.list, .inline_list => |lst| {
|
||||||
var result = try std.ArrayList(ptr.child).initCapacity(allocator, lst.items.len);
|
var result = try std.ArrayList(ptr.child).initCapacity(allocator, lst.items.len);
|
||||||
errdefer result.deinit();
|
errdefer result.deinit();
|
||||||
for (lst.items) |item| {
|
for (lst.items) |item| {
|
||||||
result.appendAssumeCapacity(try item.convertTo(ptr.child, allocator, options));
|
result.appendAssumeCapacity(try item.convertTo(ptr.child, allocator, options));
|
||||||
}
|
}
|
||||||
return result.toOwnedSlice();
|
if (ptr.sentinel) |sent| {
|
||||||
|
return try result.toOwnedSliceSentinel(@as(*align(1) const ptr.child, @ptrCast(sent)).*);
|
||||||
|
} else {
|
||||||
|
return try result.toOwnedSlice();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
else => return error.BadValue,
|
else => return error.BadValue,
|
||||||
}
|
}
|
||||||
@ -146,7 +160,6 @@ pub const Value = union(enum) {
|
|||||||
// type to use for this? the problem is that it becomes
|
// type to use for this? the problem is that it becomes
|
||||||
// invasive into downstream code. Ultimately this should
|
// invasive into downstream code. Ultimately this should
|
||||||
// probably be solved in the zig stdlib or similar.
|
// probably be solved in the zig stdlib or similar.
|
||||||
// TODO: This also doesn't handle sentinels properly.
|
|
||||||
switch (self) {
|
switch (self) {
|
||||||
.scalar, .string => |str| {
|
.scalar, .string => |str| {
|
||||||
if (arr.child == u8 and str.len == arr.len) {
|
if (arr.child == u8 and str.len == arr.len) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user