| ... | ... | @@ -894,34 +894,32 @@ pub const errno = struct { |
| 894 | 894 | return null; |
| 895 | 895 | } |
| 896 | 896 | |
| 897 | | const map = blk: { |
| 898 | | const KV = struct { []const u8, Error }; |
| 899 | | var kvs: []const KV = &.{}; |
| 900 | | for (std.meta.fields(Enum)) |field| { |
| 901 | | kvs = kvs ++ &[1]KV{.{ field.name, @field(Error, field.name) }}; |
| 897 | comptime { |
| 898 | // assert Enum is sequential |
| 899 | var value: c_ushort = 0; // SUCCESS |
| 900 | for (std.enums.values(Enum)) |val| { |
| 901 | std.debug.assert(@intFromEnum(val) > value); |
| 902 | value = @intFromEnum(val); |
| 902 | 903 | } |
| 903 | | break :blk std.StaticStringMap(Error).initComptime(kvs); |
| 904 | } |
| 905 | comptime { |
| 906 | // sanity test |
| 907 | std.debug.assert(@intFromEnum(Enum.EPERM) == 1); |
| 908 | } |
| 909 | const list = blk: { |
| 910 | const values = std.enums.values(Enum); |
| 911 | const len = @intFromEnum(values[values.len - 1]) + 1; |
| 912 | var errors: [len]Error = @splat(error.Unexpected); |
| 913 | for (values) |f| errors[@intFromEnum(f)] = @field(Error, @tagName(f)); |
| 914 | const final = errors; |
| 915 | break :blk final; |
| 904 | 916 | }; |
| 905 | 917 | |
| 906 | 918 | pub fn fromInt(code: c_int) Error { |
| 907 | | const errors_are_seqential = comptime blk: { |
| 908 | | if (@intFromEnum(Enum.EPERM) != 1) break :blk false; |
| 909 | | var prev: u16 = @intFromError(Error.EPERM); |
| 910 | | for (std.meta.fields(Error)[1..]) |field| { |
| 911 | | const int = @intFromError(@field(anyerror, field.name)); |
| 912 | | if (int != prev + 1) break :blk false; |
| 913 | | prev = int; |
| 914 | | } |
| 915 | | break :blk true; |
| 916 | | }; |
| 917 | | if (errors_are_seqential) { |
| 918 | | // avoid an inline for and N comparisons |
| 919 | | if (code < 1) return error.Unexpected; |
| 920 | | if (code > std.meta.fields(Enum).len) return error.Unexpected; |
| 921 | | const ucode: c_ushort = @intCast(code); |
| 922 | | return @errorCast(@errorFromInt(@intFromError(Error.EPERM) + ucode - @intFromEnum(Enum.EPERM))); |
| 923 | | } |
| 924 | | return map.get(std.enums.tagName(Enum, @enumFromInt(code)) orelse return error.Unexpected).?; |
| 919 | @setRuntimeSafety(false); |
| 920 | if (code >= list.len) return error.Unexpected; |
| 921 | if (code <= 0) return error.Unexpected; |
| 922 | return list[@intCast(code)]; |
| 925 | 923 | } |
| 926 | 924 | |
| 927 | 925 | pub fn fromLibC() c_int { |