feature. See also
. The project being documented here (as the example) is the Zig library itself.
ConfigHeader.renderCmake
fn renderCmake(
arena: Allocator,
maker: *Maker,
step: *Step,
contents: []const u8,
w: *Writer,
value_pairs: []const Value.Pair,
value_map: *ValueMap,
src_path: Path,
) !void
File
Code
fn renderCmake(
arena: Allocator,
maker: *Maker,
step: *Step,
contents: []const u8,
w: *Writer,
value_pairs: []const Value.Pair,
value_map: *ValueMap,
src_path: Path,
) !void {
const conf = &maker.scanned_config.configuration;
const newline = detectNewline(contents);
try w.writeAll(c_generated_line);
try w.writeAll(newline);
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 stripped_line = std.mem.trimEnd(u8, raw_line, "\r");
const line = expandVariablesCmake(arena, stripped_line, conf, value_pairs, value_map) catch |err| switch (err) {
error.InvalidCharacter => {
try step.addError(maker, "{f}:{d}: invalid character in a variable name", .{
src_path, line_index + 1,
});
any_errors = true;
continue;
},
else => {
try step.addError(maker, "{f}:{d}: failed substituting variable: {t}", .{
src_path, line_index + 1, err,
});
any_errors = true;
continue;
},
};
const line_start = std.mem.findNone(u8, line, " \t\r") orelse {
try w.writeAll(line);
if (!last_line) try w.writeAll(newline);
continue;
};
const whitespace_prefix = line[0..line_start];
const trimmed_line = line[line_start..];
if (!std.mem.startsWith(u8, trimmed_line, "#")) {
try w.writeAll(line);
if (!last_line) try w.writeAll(newline);
continue;
}
var it = std.mem.tokenizeAny(u8, trimmed_line[1..], " \t\r");
const cmakedefine = it.next().?;
const booldefine = if (std.mem.eql(u8, cmakedefine, "cmakedefine01"))
true
else if (std.mem.eql(u8, cmakedefine, "cmakedefine"))
false
else {
try w.writeAll(line);
if (!last_line) try w.writeAll(newline);
continue;
};
const name = it.next() orelse {
try step.addError(maker, "{f}:{d}: error: missing define name", .{ src_path, line_index + 1 });
any_errors = true;
continue;
};
const orig_value: Value.Index = v: {
const index = value_map.getIndex(name) orelse break :v if (booldefine) .int_0 else .undef;
value_map.values()[index] = true;
break :v value_pairs[index].index;
};
const value = switch (orig_value.unpack(conf)) {
.bool => |b| if (!b) .undef else orig_value,
inline .i64, .u64 => |i| if (i == 0) .undef else orig_value,
.string => |s| if (s.len == 0) .undef else orig_value,
else => orig_value,
};
try w.writeAll(whitespace_prefix);
if (booldefine) {
try renderValueCBool(w, newline, name, switch (value.unpack(conf)) {
.undef, .defined => false,
.bool => |b| b,
inline .u64, .i64 => |i| i != 0,
.string => |s| s.len != 0,
.ident => false,
});
} else if (value != .undef) {
try renderValueCIdent(w, newline, name, it.rest());
} else {
try renderValueC(conf, w, newline, name, value);
}
}
try ensureAllValuesUsed(maker, step, value_map, src_path);
if (any_errors) return error.MakeFailed;
}