From 7116b02210bcae7bafac9017a7e47a14b52eafc2 Mon Sep 17 00:00:00 2001 From: Krzysztof Wolicki Date: Sun, 14 Jan 2024 21:21:10 +0100 Subject: [PATCH] Allow multiple options using the same enum type --- lib/std/Build/Step/Options.zig | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 7f334a2e69..9748043a35 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -14,6 +14,7 @@ generated_file: GeneratedFile, contents: std.ArrayList(u8), args: std.ArrayList(Arg), +encountered_types: std.StringHashMap(void), pub fn create(owner: *std.Build) *Options { const self = owner.allocator.create(Options) catch @panic("OOM"); @@ -27,6 +28,7 @@ pub fn create(owner: *std.Build) *Options { .generated_file = undefined, .contents = std.ArrayList(u8).init(owner.allocator), .args = std.ArrayList(Arg).init(owner.allocator), + .encountered_types = std.StringHashMap(void).init(owner.allocator), }; self.generated_file = .{ .step = &self.step }; @@ -101,11 +103,14 @@ fn addOptionFallible(self: *Options, comptime T: type, name: []const u8, value: } switch (@typeInfo(T)) { .Enum => |enum_info| { - try out.print("pub const {} = enum {{\n", .{std.zig.fmtId(@typeName(T))}); - inline for (enum_info.fields) |field| { - try out.print(" {},\n", .{std.zig.fmtId(field.name)}); + const gop = try self.encountered_types.getOrPut(@typeName(T)); + if (!gop.found_existing) { + try out.print("pub const {} = enum {{\n", .{std.zig.fmtId(@typeName(T))}); + inline for (enum_info.fields) |field| { + try out.print(" {},\n", .{std.zig.fmtId(field.name)}); + } + try out.writeAll("};\n"); } - try out.writeAll("};\n"); try out.print("pub const {}: {s} = .{s};\n", .{ std.zig.fmtId(name), std.zig.fmtId(@typeName(T)), @@ -322,6 +327,11 @@ test Options { @"0.8.1", }; + const NormalEnum = enum { + foo, + bar, + }; + const nested_array = [2][2]u16{ [2]u16{ 300, 200 }, [2]u16{ 300, 200 }, @@ -338,6 +348,8 @@ test Options { options.addOption([]const []const u16, "nested_slice", nested_slice); options.addOption(KeywordEnum, "keyword_enum", .@"0.8.1"); options.addOption(std.SemanticVersion, "semantic_version", try std.SemanticVersion.parse("0.1.2-foo+bar")); + options.addOption(NormalEnum, "normal1", NormalEnum.foo); + options.addOption(NormalEnum, "normal2", NormalEnum.bar); try std.testing.expectEqualStrings( \\pub const option1: usize = 1; @@ -377,6 +389,12 @@ test Options { \\ .pre = "foo", \\ .build = "bar", \\}; + \\pub const @"Build.Step.Options.decltest.Options.NormalEnum" = enum { + \\ foo, + \\ bar, + \\}; + \\pub const normal1: @"Build.Step.Options.decltest.Options.NormalEnum" = .foo; + \\pub const normal2: @"Build.Step.Options.decltest.Options.NormalEnum" = .bar; \\ , options.contents.items);