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 {...@@ -199,7 +199,7 @@ const AvailableOption = struct {
199 name: []const u8,199 name: []const u8,
200 type_id: TypeId,200 type_id: TypeId,
201 description: []const u8,201 description: []const u8,
202 /// If the `type_id` is `enum` this provides the list of enum options202 /// If the `type_id` is `enum` or `enum_list` this provides the list of enum options
203 enum_options: ?[]const []const u8,203 enum_options: ?[]const []const u8,
204};204};
205205
...@@ -221,6 +221,7 @@ const TypeId = enum {...@@ -221,6 +221,7 @@ const TypeId = enum {
221 int,221 int,
222 float,222 float,
223 @"enum",223 @"enum",
224 enum_list,
224 string,225 string,
225 list,226 list,
226 build_id,227 build_id,
...@@ -1084,8 +1085,9 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw...@@ -1084,8 +1085,9 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
1084 const name = b.dupe(name_raw);1085 const name = b.dupe(name_raw);
1085 const description = b.dupe(description_raw);1086 const description = b.dupe(description_raw);
1086 const type_id = comptime typeToEnum(T);1087 const type_id = comptime typeToEnum(T);
1087 const enum_options = if (type_id == .@"enum") blk: {1088 const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: {
1088 const fields = comptime std.meta.fields(T);1089 const EnumType = if (type_id == .enum_list) @typeInfo(T).Pointer.child else T;
1090 const fields = comptime std.meta.fields(EnumType);
1089 var options = ArrayList([]const u8).initCapacity(b.allocator, fields.len) catch @panic("OOM");1091 var options = ArrayList([]const u8).initCapacity(b.allocator, fields.len) catch @panic("OOM");
10901092
1091 inline for (fields) |field| {1093 inline for (fields) |field| {
...@@ -1229,6 +1231,38 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw...@@ -1229,6 +1231,38 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
1229 },1231 },
1230 .list => |lst| return lst.items,1232 .list => |lst| return lst.items,
1231 },1233 },
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 },
1232 }1266 }
1233}1267}
12341268
...@@ -1487,11 +1521,15 @@ fn typeToEnum(comptime T: type) TypeId {...@@ -1487,11 +1521,15 @@ fn typeToEnum(comptime T: type) TypeId {
1487 .Float => .float,1521 .Float => .float,
1488 .Bool => .bool,1522 .Bool => .bool,
1489 .Enum => .@"enum",1523 .Enum => .@"enum",
1490 else => switch (T) {1524 .Pointer => |pointer| switch (pointer.child) {
1491 []const u8 => .string,1525 u8 => .string,
1492 []const []const u8 => .list,1526 []const u8 => .list,
1493 else => @compileError("Unsupported type: " ++ @typeName(T)),1527 else => switch (@typeInfo(pointer.child)) {
1528 .Enum => .enum_list,
1529 else => @compileError("Unsupported type: " ++ @typeName(T)),
1530 },
1494 },1531 },
1532 else => @compileError("Unsupported type: " ++ @typeName(T)),
1495 },1533 },
1496 };1534 };
1497}1535}