| ... | @@ -584,9 +584,6 @@ pub const Step = extern struct { | ... | @@ -584,9 +584,6 @@ pub const Step = extern struct { |
| 584 | }; | 584 | }; |
| 585 | }; | 585 | }; |
| 586 | | 586 | |
| 587 | /// Trailing: | | |
| 588 | /// * exact_match: String, // if expect_errors is contains, starts_with, or stderr_contains | | |
| 589 | /// * test_runner: LazyPath, // if test_runner_mode is not default | | |
| 590 | pub const Compile = struct { | 587 | pub const Compile = struct { |
| 591 | flags: @This().Flags, | 588 | flags: @This().Flags, |
| 592 | flags2: Flags2, | 589 | flags2: Flags2, |
| ... | @@ -600,7 +597,7 @@ pub const Step = extern struct { | ... | @@ -600,7 +597,7 @@ pub const Step = extern struct { |
| 600 | exec_cmd_args: Storage.FlagLengthPrefixedList(.flags, .exec_cmd_args_len, OptionalString), | 597 | exec_cmd_args: Storage.FlagLengthPrefixedList(.flags, .exec_cmd_args_len, OptionalString), |
| 601 | installed_headers: Storage.FlagLengthPrefixedList(.flags, .installed_headers_len, Storage.Extended(InstalledHeader.Flags, InstalledHeader)), | 598 | installed_headers: Storage.FlagLengthPrefixedList(.flags, .installed_headers_len, Storage.Extended(InstalledHeader.Flags, InstalledHeader)), |
| 602 | force_undefined_symbols: Storage.FlagLengthPrefixedList(.flags, .force_undefined_symbols_len, String), | 599 | force_undefined_symbols: Storage.FlagLengthPrefixedList(.flags, .force_undefined_symbols_len, String), |
| 603 | //exacts: EnumConditionalPrefixedList(.flags4, .expect_errors, .exact, String), | 600 | expect_errors: Storage.FlagUnion(.flags4, .expect_errors, ExpectErrors), |
| 604 | linker_script: Storage.FlagOptional(.flags4, .linker_script, LazyPath), | 601 | linker_script: Storage.FlagOptional(.flags4, .linker_script, LazyPath), |
| 605 | version_script: Storage.FlagOptional(.flags4, .version_script, LazyPath), | 602 | version_script: Storage.FlagOptional(.flags4, .version_script, LazyPath), |
| 606 | zig_lib_dir: Storage.FlagOptional(.flags3, .zig_lib_dir, LazyPath), | 603 | zig_lib_dir: Storage.FlagOptional(.flags3, .zig_lib_dir, LazyPath), |
| ... | @@ -622,6 +619,7 @@ pub const Step = extern struct { | ... | @@ -622,6 +619,7 @@ pub const Step = extern struct { |
| 622 | headerpad_size: Storage.FlagOptional(.flags4, .headerpad_size, u32), | 619 | headerpad_size: Storage.FlagOptional(.flags4, .headerpad_size, u32), |
| 623 | error_limit: Storage.FlagOptional(.flags4, .error_limit, u32), | 620 | error_limit: Storage.FlagOptional(.flags4, .error_limit, u32), |
| 624 | build_id: Storage.EnumOptional(.flags3, .build_id, .hexstring, String), | 621 | build_id: Storage.EnumOptional(.flags3, .build_id, .hexstring, String), |
| | 622 | test_runner: Storage.FlagUnion(.flags3, .test_runner, TestRunner), |
| 625 | | 623 | |
| 626 | pub const InstalledHeader = union(@This().Tag) { | 624 | pub const InstalledHeader = union(@This().Tag) { |
| 627 | file: File, | 625 | file: File, |
| ... | @@ -663,8 +661,22 @@ pub const Step = extern struct { | ... | @@ -663,8 +661,22 @@ pub const Step = extern struct { |
| 663 | }; | 661 | }; |
| 664 | }; | 662 | }; |
| 665 | }; | 663 | }; |
| 666 | pub const ExpectErrors = enum(u3) { contains, exact, starts_with, stderr_contains, none }; | 664 | pub const ExpectErrors = union(@This().Tag) { |
| 667 | pub const TestRunnerMode = enum(u2) { default, simple, server }; | 665 | pub const Tag = enum(u3) { contains, exact, starts_with, stderr_contains, none }; |
| | 666 | |
| | 667 | contains: String, |
| | 668 | exact: Storage.LengthPrefixedList(String), |
| | 669 | starts_with: String, |
| | 670 | stderr_contains: String, |
| | 671 | none: void, |
| | 672 | }; |
| | 673 | pub const TestRunner = union(@This().Tag) { |
| | 674 | pub const Tag = enum(u2) { default, simple, server }; |
| | 675 | |
| | 676 | default: void, |
| | 677 | simple: LazyPath, |
| | 678 | server: LazyPath, |
| | 679 | }; |
| 668 | pub const Entry = enum(u2) { default, disabled, enabled, symbol_name }; | 680 | pub const Entry = enum(u2) { default, disabled, enabled, symbol_name }; |
| 669 | | 681 | |
| 670 | pub const Lto = enum(u2) { | 682 | pub const Lto = enum(u2) { |
| ... | @@ -826,7 +838,7 @@ pub const Step = extern struct { | ... | @@ -826,7 +838,7 @@ pub const Step = extern struct { |
| 826 | kind: Kind, | 838 | kind: Kind, |
| 827 | compress_debug_sections: std.zig.CompressDebugSections, | 839 | compress_debug_sections: std.zig.CompressDebugSections, |
| 828 | global_base: bool, | 840 | global_base: bool, |
| 829 | test_runner_mode: TestRunnerMode, | 841 | test_runner: TestRunner.Tag, |
| 830 | wasi_exec_model: WasiExecModel, | 842 | wasi_exec_model: WasiExecModel, |
| 831 | win32_manifest: bool, | 843 | win32_manifest: bool, |
| 832 | win32_module_definition: bool, | 844 | win32_module_definition: bool, |
| ... | @@ -849,7 +861,7 @@ pub const Step = extern struct { | ... | @@ -849,7 +861,7 @@ pub const Step = extern struct { |
| 849 | error_limit: bool, | 861 | error_limit: bool, |
| 850 | install_name: bool, | 862 | install_name: bool, |
| 851 | entitlements: bool, | 863 | entitlements: bool, |
| 852 | expect_errors: ExpectErrors, | 864 | expect_errors: ExpectErrors.Tag, |
| 853 | linker_script: bool, | 865 | linker_script: bool, |
| 854 | version_script: bool, | 866 | version_script: bool, |
| 855 | _: u18 = 0, | 867 | _: u18 = 0, |
| ... | @@ -1756,8 +1768,10 @@ pub const Storage = enum { | ... | @@ -1756,8 +1768,10 @@ pub const Storage = enum { |
| 1756 | flag_optional, | 1768 | flag_optional, |
| 1757 | enum_optional, | 1769 | enum_optional, |
| 1758 | extended, | 1770 | extended, |
| | 1771 | length_prefixed_list, |
| 1759 | flag_length_prefixed_list, | 1772 | flag_length_prefixed_list, |
| 1760 | union_list, | 1773 | union_list, |
| | 1774 | flag_union, |
| 1761 | | 1775 | |
| 1762 | /// The presence of the field is determined by a boolean within a packed | 1776 | /// The presence of the field is determined by a boolean within a packed |
| 1763 | /// struct. | 1777 | /// struct. |
| ... | @@ -1776,6 +1790,24 @@ pub const Storage = enum { | ... | @@ -1776,6 +1790,24 @@ pub const Storage = enum { |
| 1776 | }; | 1790 | }; |
| 1777 | } | 1791 | } |
| 1778 | | 1792 | |
| | 1793 | /// The type of the field is determined by an enum within a packed struct. |
| | 1794 | pub fn FlagUnion( |
| | 1795 | comptime flags_arg: @EnumLiteral(), |
| | 1796 | comptime flag_arg: @EnumLiteral(), |
| | 1797 | comptime UnionArg: type, |
| | 1798 | ) type { |
| | 1799 | return struct { |
| | 1800 | u: Union, |
| | 1801 | |
| | 1802 | pub const storage: Storage = .flag_union; |
| | 1803 | pub const flags = flags_arg; |
| | 1804 | pub const flag = flag_arg; |
| | 1805 | pub const Union = UnionArg; |
| | 1806 | |
| | 1807 | pub const Tag = @typeInfo(Union).@"union".tag_type.?; |
| | 1808 | }; |
| | 1809 | } |
| | 1810 | |
| 1779 | /// The field is present if an enum tag from flags matches a specific value. | 1811 | /// The field is present if an enum tag from flags matches a specific value. |
| 1780 | pub fn EnumOptional( | 1812 | pub fn EnumOptional( |
| 1781 | comptime flags_arg: @EnumLiteral(), | 1813 | comptime flags_arg: @EnumLiteral(), |
| ... | @@ -1814,21 +1846,32 @@ pub const Storage = enum { | ... | @@ -1814,21 +1846,32 @@ pub const Storage = enum { |
| 1814 | | 1846 | |
| 1815 | /// A field in flags determines whether the length is zero or nonzero. If the length is | 1847 | /// A field in flags determines whether the length is zero or nonzero. If the length is |
| 1816 | /// nonzero, then there is a length field followed by the list. | 1848 | /// nonzero, then there is a length field followed by the list. |
| 1817 | /// | | |
| 1818 | /// When deserializing, the slice field is set. When serializing, the index | | |
| 1819 | /// field must be set. | | |
| 1820 | pub fn FlagLengthPrefixedList( | 1849 | pub fn FlagLengthPrefixedList( |
| 1821 | comptime flags_arg: @EnumLiteral(), | 1850 | comptime flags_arg: @EnumLiteral(), |
| 1822 | comptime flag_arg: @EnumLiteral(), | 1851 | comptime flag_arg: @EnumLiteral(), |
| 1823 | comptime ValueArg: type, | 1852 | comptime ElemArg: type, |
| 1824 | ) type { | 1853 | ) type { |
| 1825 | return struct { | 1854 | return struct { |
| 1826 | slice: []const Value, | 1855 | slice: []const Elem, |
| 1827 | | 1856 | |
| 1828 | pub const storage: Storage = .flag_length_prefixed_list; | 1857 | pub const storage: Storage = .flag_length_prefixed_list; |
| 1829 | pub const flags = flags_arg; | 1858 | pub const flags = flags_arg; |
| 1830 | pub const flag = flag_arg; | 1859 | pub const flag = flag_arg; |
| 1831 | pub const Value = ValueArg; | 1860 | pub const Elem = ElemArg; |
| | 1861 | |
| | 1862 | pub fn initErased(s: []const u32) @This() { |
| | 1863 | return .{ .slice = @ptrCast(s) }; |
| | 1864 | } |
| | 1865 | }; |
| | 1866 | } |
| | 1867 | |
| | 1868 | /// The field contains a u32 length followed by that many items. |
| | 1869 | pub fn LengthPrefixedList(comptime ElemArg: type) type { |
| | 1870 | return struct { |
| | 1871 | slice: []const Elem, |
| | 1872 | |
| | 1873 | pub const storage: Storage = .length_prefixed_list; |
| | 1874 | pub const Elem = ElemArg; |
| 1832 | | 1875 | |
| 1833 | pub fn initErased(s: []const u32) @This() { | 1876 | pub fn initErased(s: []const u32) @This() { |
| 1834 | return .{ .slice = @ptrCast(s) }; | 1877 | return .{ .slice = @ptrCast(s) }; |
| ... | @@ -1910,6 +1953,7 @@ pub const Storage = enum { | ... | @@ -1910,6 +1953,7 @@ pub const Storage = enum { |
| 1910 | | 1953 | |
| 1911 | fn dataField(buffer: []const u32, i: *usize, container: anytype, comptime Field: type) Field { | 1954 | fn dataField(buffer: []const u32, i: *usize, container: anytype, comptime Field: type) Field { |
| 1912 | switch (@typeInfo(Field)) { | 1955 | switch (@typeInfo(Field)) { |
| | 1956 | .void => return {}, |
| 1913 | .int => |info| switch (info.bits) { | 1957 | .int => |info| switch (info.bits) { |
| 1914 | 32 => { | 1958 | 32 => { |
| 1915 | defer i.* += 1; | 1959 | defer i.* += 1; |
| ... | @@ -1954,6 +1998,24 @@ pub const Storage = enum { | ... | @@ -1954,6 +1998,24 @@ pub const Storage = enum { |
| 1954 | .value = if (flag) dataField(buffer, i, container, Field.Value) else null, | 1998 | .value = if (flag) dataField(buffer, i, container, Field.Value) else null, |
| 1955 | }; | 1999 | }; |
| 1956 | }, | 2000 | }, |
| | 2001 | .flag_union => { |
| | 2002 | const flags = @field(container, @tagName(Field.flags)); |
| | 2003 | const tag: Field.Tag = @field(flags, @tagName(Field.flag)); |
| | 2004 | return .{ |
| | 2005 | .u = switch (tag) { |
| | 2006 | inline else => |comptime_tag| @unionInit( |
| | 2007 | Field.Union, |
| | 2008 | @tagName(comptime_tag), |
| | 2009 | dataField( |
| | 2010 | buffer, |
| | 2011 | i, |
| | 2012 | container, |
| | 2013 | @typeInfo(Field.Union).@"union".fields[@intFromEnum(comptime_tag)].type, |
| | 2014 | ), |
| | 2015 | ), |
| | 2016 | }, |
| | 2017 | }; |
| | 2018 | }, |
| 1957 | .enum_optional => { | 2019 | .enum_optional => { |
| 1958 | const flags = @field(container, @tagName(Field.flags)); | 2020 | const flags = @field(container, @tagName(Field.flags)); |
| 1959 | const tag = @field(flags, @tagName(Field.flag)); | 2021 | const tag = @field(flags, @tagName(Field.flag)); |
| ... | @@ -1963,6 +2025,12 @@ pub const Storage = enum { | ... | @@ -1963,6 +2025,12 @@ pub const Storage = enum { |
| 1963 | }; | 2025 | }; |
| 1964 | }, | 2026 | }, |
| 1965 | .extended => @compileError("TODO"), | 2027 | .extended => @compileError("TODO"), |
| | 2028 | .length_prefixed_list => { |
| | 2029 | const data_start = i.* + 1; |
| | 2030 | const len = buffer[data_start - 1]; |
| | 2031 | defer i.* = data_start + len; |
| | 2032 | return .{ .slice = @ptrCast(buffer[data_start..][0..len]) }; |
| | 2033 | }, |
| 1966 | .flag_length_prefixed_list => { | 2034 | .flag_length_prefixed_list => { |
| 1967 | const flags = @field(container, @tagName(Field.flags)); | 2035 | const flags = @field(container, @tagName(Field.flags)); |
| 1968 | const flag = @field(flags, @tagName(Field.flag)); | 2036 | const flag = @field(flags, @tagName(Field.flag)); |
| ... | @@ -2010,6 +2078,7 @@ pub const Storage = enum { | ... | @@ -2010,6 +2078,7 @@ pub const Storage = enum { |
| 2010 | fn extraFieldLen(field: anytype) usize { | 2078 | fn extraFieldLen(field: anytype) usize { |
| 2011 | const Field = @TypeOf(field); | 2079 | const Field = @TypeOf(field); |
| 2012 | return switch (@typeInfo(Field)) { | 2080 | return switch (@typeInfo(Field)) { |
| | 2081 | .void => 0, |
| 2013 | .int => |info| switch (info.bits) { | 2082 | .int => |info| switch (info.bits) { |
| 2014 | 32 => 1, | 2083 | 32 => 1, |
| 2015 | 64 => 2, | 2084 | 64 => 2, |
| ... | @@ -2024,8 +2093,11 @@ pub const Storage = enum { | ... | @@ -2024,8 +2093,11 @@ pub const Storage = enum { |
| 2024 | }, | 2093 | }, |
| 2025 | .auto => switch (Field.storage) { | 2094 | .auto => switch (Field.storage) { |
| 2026 | .flag_optional, .enum_optional, .extended => 1, | 2095 | .flag_optional, .enum_optional, .extended => 1, |
| 2027 | .flag_length_prefixed_list => field.slice.len + 1, | 2096 | .length_prefixed_list, .flag_length_prefixed_list => field.slice.len + 1, |
| 2028 | .union_list => Field.extraLen(field.len), | 2097 | .union_list => Field.extraLen(field.len), |
| | 2098 | .flag_union => switch (field.u) { |
| | 2099 | inline else => |v| extraFieldLen(v), |
| | 2100 | }, |
| 2029 | }, | 2101 | }, |
| 2030 | .@"extern" => comptime unreachable, | 2102 | .@"extern" => comptime unreachable, |
| 2031 | }, | 2103 | }, |
| ... | @@ -2044,6 +2116,7 @@ pub const Storage = enum { | ... | @@ -2044,6 +2116,7 @@ pub const Storage = enum { |
| 2044 | | 2116 | |
| 2045 | inline fn setExtraField(buffer: []u32, i: usize, comptime Field: type, value: anytype) usize { | 2117 | inline fn setExtraField(buffer: []u32, i: usize, comptime Field: type, value: anytype) usize { |
| 2046 | switch (@typeInfo(Field)) { | 2118 | switch (@typeInfo(Field)) { |
| | 2119 | .void => return 0, |
| 2047 | .int => |info| switch (info.bits) { | 2120 | .int => |info| switch (info.bits) { |
| 2048 | 32 => { | 2121 | 32 => { |
| 2049 | buffer[i] = value; | 2122 | buffer[i] = value; |
| ... | @@ -2081,8 +2154,11 @@ pub const Storage = enum { | ... | @@ -2081,8 +2154,11 @@ pub const Storage = enum { |
| 2081 | .flag_optional, .enum_optional => { | 2154 | .flag_optional, .enum_optional => { |
| 2082 | return if (value.value) |v| setExtraField(buffer, i, Field.Value, v) else 0; | 2155 | return if (value.value) |v| setExtraField(buffer, i, Field.Value, v) else 0; |
| 2083 | }, | 2156 | }, |
| | 2157 | .flag_union => return switch (value.u) { |
| | 2158 | inline else => |x| setExtraField(buffer, i, @TypeOf(x), x), |
| | 2159 | }, |
| 2084 | .extended => @compileError("TODO"), | 2160 | .extended => @compileError("TODO"), |
| 2085 | .flag_length_prefixed_list => { | 2161 | .flag_length_prefixed_list, .length_prefixed_list => { |
| 2086 | const len: u32 = @intCast(value.slice.len); | 2162 | const len: u32 = @intCast(value.slice.len); |
| 2087 | if (len == 0) return 0; | 2163 | if (len == 0) return 0; |
| 2088 | buffer[i] = len; | 2164 | buffer[i] = len; |