aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build.zig
diff options
context:
space:
mode:
authorMaciej 'vesim' KuliƄski <vesim809@pm.me>2024-06-06 06:02:42 +0200
committerAndrew Kelley <andrew@ziglang.org>2024-06-06 12:27:29 -0400
commita4e01074b5cec7da7990188bf0163e8a1fb18483 (patch)
tree07aba91b6528dd419ee766bccb6a3c94d0bc3ca8 /lib/std/Build.zig
parent4d499359d58886ba321ef0cd524ee7f7aac0d6ae (diff)
downloadzig-a4e01074b5cec7da7990188bf0163e8a1fb18483.tar.gz
zig-a4e01074b5cec7da7990188bf0163e8a1fb18483.zip
Add support for []enum in Build.option
Diffstat (limited to 'lib/std/Build.zig')
-rw-r--r--lib/std/Build.zig52
1 files changed, 45 insertions, 7 deletions
diff --git a/lib/std/Build.zig b/lib/std/Build.zig
index 4443fa404c..79cfbea986 100644
--- a/lib/std/Build.zig
+++ b/lib/std/Build.zig
@@ -199,7 +199,7 @@ const AvailableOption = struct {
name: []const u8,
type_id: TypeId,
description: []const u8,
- /// If the `type_id` is `enum` this provides the list of enum options
+ /// If the `type_id` is `enum` or `enum_list` this provides the list of enum options
enum_options: ?[]const []const u8,
};
@@ -221,6 +221,7 @@ const TypeId = enum {
int,
float,
@"enum",
+ enum_list,
string,
list,
build_id,
@@ -1084,8 +1085,9 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
const name = b.dupe(name_raw);
const description = b.dupe(description_raw);
const type_id = comptime typeToEnum(T);
- const enum_options = if (type_id == .@"enum") blk: {
- const fields = comptime std.meta.fields(T);
+ const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: {
+ const EnumType = if (type_id == .enum_list) @typeInfo(T).Pointer.child else T;
+ const fields = comptime std.meta.fields(EnumType);
var options = ArrayList([]const u8).initCapacity(b.allocator, fields.len) catch @panic("OOM");
inline for (fields) |field| {
@@ -1229,6 +1231,38 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
},
.list => |lst| return lst.items,
},
+ .enum_list => switch (option_ptr.value) {
+ .flag, .map => {
+ log.err("Expected -D{s} to be a list, but received a {s}.", .{
+ name, @tagName(option_ptr.value),
+ });
+ b.markInvalidUserInput();
+ return null;
+ },
+ .scalar => |s| {
+ const Child = @typeInfo(T).Pointer.child;
+ const value = std.meta.stringToEnum(Child, s) orelse {
+ log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(Child) });
+ b.markInvalidUserInput();
+ return null;
+ };
+ return b.allocator.dupe(Child, &[_]Child{value}) catch @panic("OOM");
+ },
+ .list => |lst| {
+ const Child = @typeInfo(T).Pointer.child;
+ var new_list = b.allocator.alloc(Child, lst.items.len) catch @panic("OOM");
+ for (lst.items, 0..) |str, i| {
+ const value = std.meta.stringToEnum(Child, str) orelse {
+ log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(Child) });
+ b.markInvalidUserInput();
+ b.allocator.free(new_list);
+ return null;
+ };
+ new_list[i] = value;
+ }
+ return new_list;
+ },
+ },
}
}
@@ -1487,11 +1521,15 @@ fn typeToEnum(comptime T: type) TypeId {
.Float => .float,
.Bool => .bool,
.Enum => .@"enum",
- else => switch (T) {
- []const u8 => .string,
- []const []const u8 => .list,
- else => @compileError("Unsupported type: " ++ @typeName(T)),
+ .Pointer => |pointer| switch (pointer.child) {
+ u8 => .string,
+ []const u8 => .list,
+ else => switch (@typeInfo(pointer.child)) {
+ .Enum => .enum_list,
+ else => @compileError("Unsupported type: " ++ @typeName(T)),
+ },
},
+ else => @compileError("Unsupported type: " ++ @typeName(T)),
},
};
}