Skip to content

Commit 9562dcc

Browse files
committed
std.Build.Step.ConfigHeader: add custom style
Simply replaces name with value
1 parent 2aea7a4 commit 9562dcc

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

lib/std/Build/Step/ConfigHeader.zig

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ pub const Style = union(enum) {
1313
/// The configure format supported by CMake. It uses `@FOO@`, `${}` and
1414
/// `#cmakedefine` for template substitution.
1515
cmake: std.Build.LazyPath,
16+
/// Start with input file and replace occurrences of names with their values.
17+
custom: std.Build.LazyPath,
1618
/// Instead of starting with an input file, start with nothing.
1719
blank,
1820
/// Start with nothing, like blank, and output a nasm .asm file.
1921
nasm,
2022

2123
pub fn getPath(style: Style) ?std.Build.LazyPath {
2224
switch (style) {
23-
.autoconf_undef, .autoconf_at, .cmake => |s| return s,
25+
.autoconf_undef, .autoconf_at, .cmake, .custom => |s| return s,
2426
.blank, .nasm => return null,
2527
}
2628
}
@@ -237,6 +239,16 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
237239
try bw.writeAll(asm_generated_line);
238240
try render_nasm(bw, config_header.values);
239241
},
242+
.custom => |file_source| {
243+
try bw.writeAll(asm_generated_line);
244+
const src_path = file_source.getPath2(b, step);
245+
const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| {
246+
return step.fail("unable to read custom input file '{s}': {s}", .{
247+
src_path, @errorName(err),
248+
});
249+
};
250+
try render_custom(step, contents, bw, config_header.values);
251+
},
240252
}
241253

242254
const output = aw.written();
@@ -545,6 +557,51 @@ fn render_nasm(bw: *Writer, defines: std.StringArrayHashMap(Value)) !void {
545557
for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value);
546558
}
547559

560+
fn render_custom(
561+
step: *Step,
562+
contents: []const u8,
563+
bw: *Writer,
564+
dict: std.StringArrayHashMap(Value),
565+
) !void {
566+
const build = step.owner;
567+
const allocator = build.allocator;
568+
569+
var contents_copy = try allocator.dupe(u8, contents);
570+
defer allocator.free(contents_copy);
571+
572+
var any_errors = false;
573+
const values = dict.values();
574+
for (dict.keys(), 0..) |name, x| {
575+
if (std.mem.indexOf(u8, contents, name) == null) {
576+
try step.addError("error: config header value unused: '{s}'", .{name});
577+
any_errors = true;
578+
continue;
579+
}
580+
581+
const value = values[x];
582+
const value_str: []const u8 = switch (value) {
583+
.undef => continue,
584+
.defined => try allocator.dupe(u8, ""),
585+
.boolean => |b| try allocator.dupe(u8, if (b) "1" else "0"),
586+
.int => |i| try std.fmt.allocPrint(allocator, "{d}", .{i}),
587+
.ident => |ident| try std.fmt.allocPrint(allocator, "{s}", .{ident}),
588+
// TODO: use C-specific escaping instead of zig string literals
589+
.string => |string| try std.fmt.allocPrint(allocator, "\"{f}\"", .{std.zig.fmtString(string)}),
590+
};
591+
defer allocator.free(value_str);
592+
593+
const replaced = try std.mem.replaceOwned(u8, allocator, contents_copy, name, value_str);
594+
defer allocator.free(replaced);
595+
596+
allocator.free(contents_copy);
597+
contents_copy = try allocator.dupe(u8, replaced);
598+
}
599+
600+
try bw.writeAll(contents_copy);
601+
602+
if (any_errors) return error.MakeFailed;
603+
}
604+
548605
fn renderValueC(bw: *Writer, name: []const u8, value: Value) !void {
549606
switch (value) {
550607
.undef => try bw.print("/* #undef {s} */\n", .{name}),

0 commit comments

Comments
 (0)