Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

parseQuotedString

literals.parseQuotedString
pub fn parseQuotedString(
    comptime literal_type: StringType,
    allocator: std.mem.Allocator,
    bytes: SourceBytes,
    options: StringParseOptions,
) !(switch (literal_type)

File

lib/compiler/resinator/literals.zig:460

Code

pub fn parseQuotedString(
    comptime literal_type: StringType,
    allocator: std.mem.Allocator,
    bytes: SourceBytes,
    options: StringParseOptions,
) !(switch (literal_type) {
    .ascii => []u8,
    .wide => [:0]u16,
}) {
    const T = if (literal_type == .ascii) u8 else u16;
    std.debug.assert(bytes.slice.len >= 2); // must at least have 2 double quote chars

    var buf = try std.ArrayList(T).initCapacity(allocator, bytes.slice.len);
    errdefer buf.deinit(allocator);

    var iterative_parser = IterativeStringParser.init(bytes, options);

    while (try iterative_parser.next()) |parsed| {
        const c = parsed.codepoint;
        switch (literal_type) {
            .ascii => switch (options.output_code_page) {
                .windows1252 => {
                    if (parsed.from_escaped_integer) {
                        try buf.append(allocator, @truncate(c));
                    } else if (windows1252.bestFitFromCodepoint(c)) |best_fit| {
                        try buf.append(allocator, best_fit);
                    } else if (c < 0x10000 or c == code_pages.Codepoint.invalid) {
                        try buf.append(allocator, '?');
                    } else {
                        try buf.appendSlice(allocator, "??");
                    }
                },
                .utf8 => {
                    var codepoint_to_encode = c;
                    if (parsed.from_escaped_integer) {
                        codepoint_to_encode = @as(T, @truncate(c));
                    }
                    const escaped_integer_outside_ascii_range = parsed.from_escaped_integer and codepoint_to_encode > 0x7F;
                    if (escaped_integer_outside_ascii_range or c == code_pages.Codepoint.invalid) {
                        codepoint_to_encode = '�';
                    }
                    var utf8_buf: [4]u8 = undefined;
                    const utf8_len = std.unicode.utf8Encode(codepoint_to_encode, &utf8_buf) catch unreachable;
                    try buf.appendSlice(allocator, utf8_buf[0..utf8_len]);
                },
            },
            .wide => {
                // Parsing any string type as a wide string is handled separately, see parseQuotedStringAsWideString
                std.debug.assert(iterative_parser.declared_string_type == .wide);
                if (parsed.from_escaped_integer) {
                    try buf.append(allocator, std.mem.nativeToLittle(u16, @truncate(c)));
                } else if (c == code_pages.Codepoint.invalid) {
                    try buf.append(allocator, std.mem.nativeToLittle(u16, '�'));
                } else if (c < 0x10000) {
                    const short: u16 = @intCast(c);
                    try buf.append(allocator, std.mem.nativeToLittle(u16, short));
                } else {
                    if (!parsed.escaped_surrogate_pair) {
                        const high = @as(u16, @intCast((c - 0x10000) >> 10)) + 0xD800;
                        try buf.append(allocator, std.mem.nativeToLittle(u16, high));
                    }
                    const low = @as(u16, @intCast(c & 0x3FF)) + 0xDC00;
                    try buf.append(allocator, std.mem.nativeToLittle(u16, low));
                }
            },
        }
    }

    if (literal_type == .wide) {
        return buf.toOwnedSliceSentinel(allocator, 0);
    } else {
        return buf.toOwnedSlice(allocator);
    }
}