DoxigAlpha

render_cmake

Function parameters

Parameters

#
step:*Step
contents:[]const u8
bw:*Writer
values:std.StringArrayHashMap(Value)
src_path:[]const u8

Type definitions in this namespace

Types

#

Functions in this namespace

Functions

#
getOutput
Deprecated; use `getOutputFile`.

= .config_header

Values

#
base_id
= .config_header

Source

Implementation

#
fn render_cmake(
    step: *Step,
    contents: []const u8,
    bw: *Writer,
    values: std.StringArrayHashMap(Value),
    src_path: []const u8,
) !void {
    const build = step.owner;
    const allocator = build.allocator;

    var values_copy = try values.clone();
    defer values_copy.deinit();

    var any_errors = false;
    var line_index: u32 = 0;
    var line_it = std.mem.splitScalar(u8, contents, '\n');
    while (line_it.next()) |raw_line| : (line_index += 1) {
        const last_line = line_it.index == line_it.buffer.len;

        const line = expand_variables_cmake(allocator, raw_line, values) catch |err| switch (err) {
            error.InvalidCharacter => {
                try step.addError("{s}:{d}: error: invalid character in a variable name", .{
                    src_path, line_index + 1,
                });
                any_errors = true;
                continue;
            },
            else => {
                try step.addError("{s}:{d}: unable to substitute variable: error: {s}", .{
                    src_path, line_index + 1, @errorName(err),
                });
                any_errors = true;
                continue;
            },
        };
        defer allocator.free(line);

        if (!std.mem.startsWith(u8, line, "#")) {
            try bw.writeAll(line);
            if (!last_line) try bw.writeByte('\n');
            continue;
        }
        var it = std.mem.tokenizeAny(u8, line[1..], " \t\r");
        const cmakedefine = it.next().?;
        if (!std.mem.eql(u8, cmakedefine, "cmakedefine") and
            !std.mem.eql(u8, cmakedefine, "cmakedefine01"))
        {
            try bw.writeAll(line);
            if (!last_line) try bw.writeByte('\n');
            continue;
        }

        const booldefine = std.mem.eql(u8, cmakedefine, "cmakedefine01");

        const name = it.next() orelse {
            try step.addError("{s}:{d}: error: missing define name", .{
                src_path, line_index + 1,
            });
            any_errors = true;
            continue;
        };
        var value = values_copy.get(name) orelse blk: {
            if (booldefine) {
                break :blk Value{ .int = 0 };
            }
            break :blk Value.undef;
        };

        value = blk: {
            switch (value) {
                .boolean => |b| {
                    if (!b) {
                        break :blk Value.undef;
                    }
                },
                .int => |i| {
                    if (i == 0) {
                        break :blk Value.undef;
                    }
                },
                .string => |string| {
                    if (string.len == 0) {
                        break :blk Value.undef;
                    }
                },

                else => {},
            }
            break :blk value;
        };

        if (booldefine) {
            value = blk: {
                switch (value) {
                    .undef => {
                        break :blk Value{ .boolean = false };
                    },
                    .defined => {
                        break :blk Value{ .boolean = false };
                    },
                    .boolean => |b| {
                        break :blk Value{ .boolean = b };
                    },
                    .int => |i| {
                        break :blk Value{ .boolean = i != 0 };
                    },
                    .string => |string| {
                        break :blk Value{ .boolean = string.len != 0 };
                    },

                    else => {
                        break :blk Value{ .boolean = false };
                    },
                }
            };
        } else if (value != Value.undef) {
            value = Value{ .ident = it.rest() };
        }

        try renderValueC(bw, name, value);
    }

    if (any_errors) {
        return error.HeaderConfigFailed;
    }
}