feature. See also
. The project being documented here (as the example) is the Zig library itself.
ZonGen.strLitAsString
fn strLitAsString(zg: *ZonGen, str_node: Ast.Node.Index) error
File
Code
fn strLitAsString(zg: *ZonGen, str_node: Ast.Node.Index) error{ OutOfMemory, BadString }!StringLiteralResult {
if (!zg.options.parse_str_lits) return .{ .slice = .{ .start = 0, .len = 0 } };
const gpa = zg.gpa;
const string_bytes = &zg.string_bytes;
const str_index: u32 = @intCast(zg.string_bytes.items.len);
const size_hint = strLitSizeHint(zg.tree, str_node);
try string_bytes.ensureUnusedCapacity(gpa, size_hint);
const result = r: {
var aw: Writer.Allocating = .fromArrayList(gpa, &zg.string_bytes);
defer zg.string_bytes = aw.toArrayList();
break :r parseStrLit(zg.tree, str_node, &aw.writer) catch |err| switch (err) {
error.WriteFailed => return error.OutOfMemory,
};
};
switch (result) {
.success => {},
.failure => |err| {
const token = zg.tree.nodeMainToken(str_node);
const raw_string = zg.tree.tokenSlice(token);
try zg.lowerStrLitError(err, token, raw_string, 0);
return error.BadString;
},
}
const key: []const u8 = string_bytes.items[str_index..];
if (std.mem.findScalar(u8, key, 0) != null) return .{ .slice = .{
.start = str_index,
.len = @intCast(key.len),
} };
const gop = try zg.string_table.getOrPutContextAdapted(
gpa,
key,
StringIndexAdapter{ .bytes = string_bytes },
StringIndexContext{ .bytes = string_bytes },
);
if (gop.found_existing) {
string_bytes.shrinkRetainingCapacity(str_index);
return .{ .nts = @fromBackingInt(@intCast(gop.key_ptr.*)) };
}
gop.key_ptr.* = str_index;
try string_bytes.append(gpa, 0);
return .{ .nts = @fromBackingInt(@intCast(str_index)) };
}