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;
}
}