diff options
| author | Maciej 'vesim' KuliĆski <vesim809@pm.me> | 2024-06-06 06:02:42 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-06-06 12:27:29 -0400 |
| commit | a4e01074b5cec7da7990188bf0163e8a1fb18483 (patch) | |
| tree | 07aba91b6528dd419ee766bccb6a3c94d0bc3ca8 /lib/std/Build.zig | |
| parent | 4d499359d58886ba321ef0cd524ee7f7aac0d6ae (diff) | |
| download | zig-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.zig | 52 |
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)), }, }; } |
