authorgravatar for vesim809@pm.meMaciej 'vesim' Kuliński <vesim809@pm.me> 2024-06-06 06:02:42+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-06-06 12:27:29-04:00
loga4e01074b5cec7da7990188bf0163e8a1fb18483
tree07aba91b6528dd419ee766bccb6a3c94d0bc3ca8
parent4d499359d58886ba321ef0cd524ee7f7aac0d6ae

Add support for []enum in Build.option


1 files changed, 45 insertions(+), 7 deletions(-)

lib/std/Build.zig+45-7
......@@ -199,7 +199,7 @@ const AvailableOption = struct {
199199 name: []const u8,
200200 type_id: TypeId,
201201 description: []const u8,
202 /// If the `type_id` is `enum` this provides the list of enum options
202 /// If the `type_id` is `enum` or `enum_list` this provides the list of enum options
203203 enum_options: ?[]const []const u8,
204204};
205205
......@@ -221,6 +221,7 @@ const TypeId = enum {
221221 int,
222222 float,
223223 @"enum",
224 enum_list,
224225 string,
225226 list,
226227 build_id,
......@@ -1084,8 +1085,9 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
10841085 const name = b.dupe(name_raw);
10851086 const description = b.dupe(description_raw);
10861087 const type_id = comptime typeToEnum(T);
1087 const enum_options = if (type_id == .@"enum") blk: {
1088 const fields = comptime std.meta.fields(T);
1088 const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: {
1089 const EnumType = if (type_id == .enum_list) @typeInfo(T).Pointer.child else T;
1090 const fields = comptime std.meta.fields(EnumType);
10891091 var options = ArrayList([]const u8).initCapacity(b.allocator, fields.len) catch @panic("OOM");
10901092
10911093 inline for (fields) |field| {
......@@ -1229,6 +1231,38 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
12291231 },
12301232 .list => |lst| return lst.items,
12311233 },
1234 .enum_list => switch (option_ptr.value) {
1235 .flag, .map => {
1236 log.err("Expected -D{s} to be a list, but received a {s}.", .{
1237 name, @tagName(option_ptr.value),
1238 });
1239 b.markInvalidUserInput();
1240 return null;
1241 },
1242 .scalar => |s| {
1243 const Child = @typeInfo(T).Pointer.child;
1244 const value = std.meta.stringToEnum(Child, s) orelse {
1245 log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(Child) });
1246 b.markInvalidUserInput();
1247 return null;
1248 };
1249 return b.allocator.dupe(Child, &[_]Child{value}) catch @panic("OOM");
1250 },
1251 .list => |lst| {
1252 const Child = @typeInfo(T).Pointer.child;
1253 var new_list = b.allocator.alloc(Child, lst.items.len) catch @panic("OOM");
1254 for (lst.items, 0..) |str, i| {
1255 const value = std.meta.stringToEnum(Child, str) orelse {
1256 log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(Child) });
1257 b.markInvalidUserInput();
1258 b.allocator.free(new_list);
1259 return null;
1260 };
1261 new_list[i] = value;
1262 }
1263 return new_list;
1264 },
1265 },
12321266 }
12331267}
12341268
......@@ -1487,11 +1521,15 @@ fn typeToEnum(comptime T: type) TypeId {
14871521 .Float => .float,
14881522 .Bool => .bool,
14891523 .Enum => .@"enum",
1490 else => switch (T) {
1491 []const u8 => .string,
1492 []const []const u8 => .list,
1493 else => @compileError("Unsupported type: " ++ @typeName(T)),
1524 .Pointer => |pointer| switch (pointer.child) {
1525 u8 => .string,
1526 []const u8 => .list,
1527 else => switch (@typeInfo(pointer.child)) {
1528 .Enum => .enum_list,
1529 else => @compileError("Unsupported type: " ++ @typeName(T)),
1530 },
14941531 },
1532 else => @compileError("Unsupported type: " ++ @typeName(T)),
14951533 },
14961534 };
14971535}