From 371d3f12a2aacc606eb8a0cfd2779f0606975dc1 Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Sat, 23 Oct 2021 10:55:52 -0400 Subject: [PATCH 1/6] Fix std.builtin.Version build option formatting --- lib/std/build/OptionsStep.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index 781c015742..2f1c1db668 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -85,6 +85,7 @@ pub fn addOption(self: *OptionsStep, comptime T: type, name: []const u8, value: value.minor, value.patch, }) catch unreachable; + return; }, std.SemanticVersion => { out.print( @@ -239,6 +240,7 @@ test "OptionsStep" { options.addOption(?usize, "option2", null); options.addOption([]const u8, "string", "zigisthebest"); options.addOption(?[]const u8, "optional_string", null); + options.addOption(std.builtin.Version, "version", try std.builtin.Version.parse("0.1.2")); options.addOption(std.SemanticVersion, "semantic_version", try std.SemanticVersion.parse("0.1.2-foo+bar")); try std.testing.expectEqualStrings( @@ -246,6 +248,11 @@ test "OptionsStep" { \\pub const option2: ?usize = null; \\pub const string: []const u8 = "zigisthebest"; \\pub const optional_string: ?[]const u8 = null; + \\pub const version: @import("std").builtin.Version = .{ + \\ .major = 0, + \\ .minor = 1, + \\ .patch = 2, + \\}; \\pub const semantic_version: @import("std").SemanticVersion = .{ \\ .major = 0, \\ .minor = 1, From 07bb8681e97f122ad7e883cb40f28639c01b020e Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Sat, 23 Oct 2021 11:22:22 -0400 Subject: [PATCH 2/6] Ensure any custom printing here remains valid zig syntax --- lib/std/build/OptionsStep.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index 2f1c1db668..12e7950599 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -262,4 +262,6 @@ test "OptionsStep" { \\}; \\ , options.contents.items); + + _ = try std.zig.parse(&arena.allocator, try options.contents.toOwnedSliceSentinel(0)); } From f98f5e0bcd5b6e726227e3c0c72c2efae8dd21c6 Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Sat, 23 Oct 2021 12:46:22 -0400 Subject: [PATCH 3/6] Fix enums with non-ident fields --- lib/std/build/OptionsStep.zig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index 12e7950599..3524a77c88 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -119,6 +119,8 @@ pub fn addOption(self: *OptionsStep, comptime T: type, name: []const u8, value: out.print(" {},\n", .{std.zig.fmtId(field.name)}) catch unreachable; } out.writeAll("};\n") catch unreachable; + out.print("pub const {}: {s} = {s}.{s};\n", .{ std.zig.fmtId(name), @typeName(T), @typeName(T), std.zig.fmtId(@tagName(value)) }) catch unreachable; + return; }, else => {}, } @@ -236,10 +238,15 @@ test "OptionsStep" { const options = builder.addOptions(); + const KeywordEnum = enum { + @"0.8.1", + }; + options.addOption(usize, "option1", 1); options.addOption(?usize, "option2", null); options.addOption([]const u8, "string", "zigisthebest"); options.addOption(?[]const u8, "optional_string", null); + options.addOption(KeywordEnum, "keyword_enum", .@"0.8.1"); options.addOption(std.builtin.Version, "version", try std.builtin.Version.parse("0.1.2")); options.addOption(std.SemanticVersion, "semantic_version", try std.SemanticVersion.parse("0.1.2-foo+bar")); @@ -248,6 +255,10 @@ test "OptionsStep" { \\pub const option2: ?usize = null; \\pub const string: []const u8 = "zigisthebest"; \\pub const optional_string: ?[]const u8 = null; + \\pub const KeywordEnum = enum { + \\ @"0.8.1", + \\}; + \\pub const keyword_enum: KeywordEnum = KeywordEnum.@"0.8.1"; \\pub const version: @import("std").builtin.Version = .{ \\ .major = 0, \\ .minor = 1, From 72039f234921884024a9163dd222f433fc6af7c3 Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Sat, 23 Oct 2021 13:30:20 -0400 Subject: [PATCH 4/6] Allow arbitrary arrays in build options --- lib/std/build/OptionsStep.zig | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index 3524a77c88..1365f40406 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -124,7 +124,27 @@ pub fn addOption(self: *OptionsStep, comptime T: type, name: []const u8, value: }, else => {}, } - out.print("pub const {}: {s} = {};\n", .{ std.zig.fmtId(name), @typeName(T), value }) catch unreachable; + out.print("pub const {}: {s} = ", .{ std.zig.fmtId(name), @typeName(T) }) catch unreachable; + printLiteral(out, value, 0) catch unreachable; + out.writeAll(";\n") catch unreachable; +} + +fn printLiteral(out: anytype, val: anytype, indent: u8) !void { + const T = @TypeOf(val); + switch (@typeInfo(T)) { + .Array => { + // TODO: non-recursive? + try out.print("{s}{{\n", .{@typeName(T)}); + for (val) |item| { + try out.writeByteNTimes(' ', indent + 4); + try printLiteral(out, item, indent + 4); + try out.writeAll(",\n"); + } + try out.writeByteNTimes(' ', indent); + try out.writeAll("}"); + }, + else => try out.print("{any}", .{val}), + } } /// The value is the path in the cache dir. @@ -246,6 +266,7 @@ test "OptionsStep" { options.addOption(?usize, "option2", null); options.addOption([]const u8, "string", "zigisthebest"); options.addOption(?[]const u8, "optional_string", null); + options.addOption([2][2]u16, "array", [2][2]u16{ [2]u16{ 300, 200 }, [2]u16{ 300, 200 } }); options.addOption(KeywordEnum, "keyword_enum", .@"0.8.1"); options.addOption(std.builtin.Version, "version", try std.builtin.Version.parse("0.1.2")); options.addOption(std.SemanticVersion, "semantic_version", try std.SemanticVersion.parse("0.1.2-foo+bar")); @@ -255,6 +276,16 @@ test "OptionsStep" { \\pub const option2: ?usize = null; \\pub const string: []const u8 = "zigisthebest"; \\pub const optional_string: ?[]const u8 = null; + \\pub const array: [2][2]u16 = [2][2]u16{ + \\ [2]u16{ + \\ 300, + \\ 200, + \\ }, + \\ [2]u16{ + \\ 300, + \\ 200, + \\ }, + \\}; \\pub const KeywordEnum = enum { \\ @"0.8.1", \\}; From 808d1b84a8349dc62597b22c7093df61fa3585d3 Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Sat, 23 Oct 2021 14:07:40 -0400 Subject: [PATCH 5/6] Allow arbitrary slices as build options --- lib/std/build/OptionsStep.zig | 40 ++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index 1365f40406..dcb6eb5671 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -134,7 +134,20 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void { switch (@typeInfo(T)) { .Array => { // TODO: non-recursive? - try out.print("{s}{{\n", .{@typeName(T)}); + try out.print("{s} {{\n", .{@typeName(T)}); + for (val) |item| { + try out.writeByteNTimes(' ', indent + 4); + try printLiteral(out, item, indent + 4); + try out.writeAll(",\n"); + } + try out.writeByteNTimes(' ', indent); + try out.writeAll("}"); + }, + .Pointer => |p| { + if (p.size != .Slice) { + @compileError("Non-slice pointers are not yet supported in build options"); + } + try out.print("&[_]{s} {{\n", .{@typeName(p.child)}); for (val) |item| { try out.writeByteNTimes(' ', indent + 4); try printLiteral(out, item, indent + 4); @@ -262,11 +275,18 @@ test "OptionsStep" { @"0.8.1", }; + const nested_array = [2][2]u16{ + [2]u16{ 300, 200 }, + [2]u16{ 300, 200 }, + }; + const nested_slice: []const []const u16 = &[_][]const u16{ &nested_array[0], &nested_array[1] }; + options.addOption(usize, "option1", 1); options.addOption(?usize, "option2", null); options.addOption([]const u8, "string", "zigisthebest"); options.addOption(?[]const u8, "optional_string", null); - options.addOption([2][2]u16, "array", [2][2]u16{ [2]u16{ 300, 200 }, [2]u16{ 300, 200 } }); + options.addOption([2][2]u16, "nested_array", nested_array); + options.addOption([]const []const u16, "nested_slice", nested_slice); options.addOption(KeywordEnum, "keyword_enum", .@"0.8.1"); options.addOption(std.builtin.Version, "version", try std.builtin.Version.parse("0.1.2")); options.addOption(std.SemanticVersion, "semantic_version", try std.SemanticVersion.parse("0.1.2-foo+bar")); @@ -276,12 +296,22 @@ test "OptionsStep" { \\pub const option2: ?usize = null; \\pub const string: []const u8 = "zigisthebest"; \\pub const optional_string: ?[]const u8 = null; - \\pub const array: [2][2]u16 = [2][2]u16{ - \\ [2]u16{ + \\pub const nested_array: [2][2]u16 = [2][2]u16 { + \\ [2]u16 { \\ 300, \\ 200, \\ }, - \\ [2]u16{ + \\ [2]u16 { + \\ 300, + \\ 200, + \\ }, + \\}; + \\pub const nested_slice: []const []const u16 = &[_][]const u16 { + \\ &[_]u16 { + \\ 300, + \\ 200, + \\ }, + \\ &[_]u16 { \\ 300, \\ 200, \\ }, From 76d4b1b823a6fbca20e24b37c4be97a5541eebf4 Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Sat, 23 Oct 2021 14:23:58 -0400 Subject: [PATCH 6/6] Better erroring for unsupported build option types --- lib/std/build/OptionsStep.zig | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index dcb6eb5671..dfe512adec 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -129,11 +129,11 @@ pub fn addOption(self: *OptionsStep, comptime T: type, name: []const u8, value: out.writeAll(";\n") catch unreachable; } +// TODO: non-recursive? fn printLiteral(out: anytype, val: anytype, indent: u8) !void { const T = @TypeOf(val); switch (@typeInfo(T)) { .Array => { - // TODO: non-recursive? try out.print("{s} {{\n", .{@typeName(T)}); for (val) |item| { try out.writeByteNTimes(' ', indent + 4); @@ -156,7 +156,20 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void { try out.writeByteNTimes(' ', indent); try out.writeAll("}"); }, - else => try out.print("{any}", .{val}), + .Optional => { + if (val) |inner| { + return printLiteral(out, inner, indent); + } else { + return out.writeAll("null"); + } + }, + .Void, + .Bool, + .Int, + .Float, + .Null, + => try out.print("{any}", .{val}), + else => @compileError(comptime std.fmt.comptimePrint("`{s}` are not yet supported as build options", .{@tagName(@typeInfo(T))})), } } @@ -283,6 +296,7 @@ test "OptionsStep" { options.addOption(usize, "option1", 1); options.addOption(?usize, "option2", null); + options.addOption(?usize, "option3", 3); options.addOption([]const u8, "string", "zigisthebest"); options.addOption(?[]const u8, "optional_string", null); options.addOption([2][2]u16, "nested_array", nested_array); @@ -294,6 +308,7 @@ test "OptionsStep" { try std.testing.expectEqualStrings( \\pub const option1: usize = 1; \\pub const option2: ?usize = null; + \\pub const option3: ?usize = 3; \\pub const string: []const u8 = "zigisthebest"; \\pub const optional_string: ?[]const u8 = null; \\pub const nested_array: [2][2]u16 = [2][2]u16 {