| ... | @@ -311,6 +311,23 @@ pub const Builder = struct { | ... | @@ -311,6 +311,23 @@ pub const Builder = struct { |
| 311 | return the_copy; | 311 | return the_copy; |
| 312 | } | 312 | } |
| 313 | | 313 | |
| | 314 | pub fn dupePkg(self: *Builder, package: Pkg) Pkg { |
| | 315 | var the_copy = Pkg{ |
| | 316 | .name = self.dupe(package.name), |
| | 317 | .path = self.dupePath(package.path), |
| | 318 | }; |
| | 319 | |
| | 320 | if (package.dependencies) |dependencies| { |
| | 321 | const new_dependencies = self.allocator.alloc(Pkg, dependencies.len) catch unreachable; |
| | 322 | the_copy.dependencies = new_dependencies; |
| | 323 | |
| | 324 | for (dependencies) |dep_package, i| { |
| | 325 | new_dependencies[i] = self.dupePkg(dep_package); |
| | 326 | } |
| | 327 | } |
| | 328 | return the_copy; |
| | 329 | } |
| | 330 | |
| 314 | pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep { | 331 | pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep { |
| 315 | const write_file_step = self.addWriteFiles(); | 332 | const write_file_step = self.addWriteFiles(); |
| 316 | write_file_step.add(file_path, data); | 333 | write_file_step.add(file_path, data); |
| ... | @@ -1826,7 +1843,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1826,7 +1843,7 @@ pub const LibExeObjStep = struct { |
| 1826 | } | 1843 | } |
| 1827 | | 1844 | |
| 1828 | pub fn addPackage(self: *LibExeObjStep, package: Pkg) void { | 1845 | pub fn addPackage(self: *LibExeObjStep, package: Pkg) void { |
| 1829 | self.packages.append(package) catch unreachable; | 1846 | self.packages.append(self.dupePkg(package)) catch unreachable; |
| 1830 | } | 1847 | } |
| 1831 | | 1848 | |
| 1832 | pub fn addPackagePath(self: *LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void { | 1849 | pub fn addPackagePath(self: *LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void { |
| ... | @@ -2691,6 +2708,47 @@ pub const InstalledFile = struct { | ... | @@ -2691,6 +2708,47 @@ pub const InstalledFile = struct { |
| 2691 | path: []const u8, | 2708 | path: []const u8, |
| 2692 | }; | 2709 | }; |
| 2693 | | 2710 | |
| | 2711 | test "Builder.dupePkg()" { |
| | 2712 | var arena = std.heap.ArenaAllocator.init(std.testing.allocator); |
| | 2713 | defer arena.deinit(); |
| | 2714 | var builder = try Builder.create( |
| | 2715 | &arena.allocator, |
| | 2716 | "test", |
| | 2717 | "test", |
| | 2718 | "test", |
| | 2719 | ); |
| | 2720 | defer builder.destroy(); |
| | 2721 | |
| | 2722 | var pkg_dep = Pkg{ |
| | 2723 | .name = "pkg_dep", |
| | 2724 | .path = "/not/a/pkg_dep.zig", |
| | 2725 | }; |
| | 2726 | var pkg_top = Pkg{ |
| | 2727 | .name = "pkg_top", |
| | 2728 | .path = "/not/a/pkg_top.zig", |
| | 2729 | .dependencies = &[_]Pkg{pkg_dep}, |
| | 2730 | }; |
| | 2731 | const dupe = builder.dupePkg(pkg_top); |
| | 2732 | |
| | 2733 | const original_deps = pkg_top.dependencies.?; |
| | 2734 | const dupe_deps = dupe.dependencies.?; |
| | 2735 | |
| | 2736 | // probably the same top level package details |
| | 2737 | std.testing.expectEqualStrings(pkg_top.name, dupe.name); |
| | 2738 | |
| | 2739 | // probably the same dependencies |
| | 2740 | std.testing.expectEqual(original_deps.len, dupe_deps.len); |
| | 2741 | std.testing.expectEqual(original_deps[0].name, pkg_dep.name); |
| | 2742 | |
| | 2743 | // could segfault otherwise if pointers in duplicated package's fields are |
| | 2744 | // the same as those in stack allocated package's fields |
| | 2745 | std.testing.expect(dupe_deps.ptr != original_deps.ptr); |
| | 2746 | std.testing.expect(dupe.name.ptr != pkg_top.name.ptr); |
| | 2747 | std.testing.expect(dupe.path.ptr != pkg_top.path.ptr); |
| | 2748 | std.testing.expect(dupe_deps[0].name.ptr != pkg_dep.name.ptr); |
| | 2749 | std.testing.expect(dupe_deps[0].path.ptr != pkg_dep.path.ptr); |
| | 2750 | } |
| | 2751 | |
| 2694 | test "" { | 2752 | test "" { |
| 2695 | // The only purpose of this test is to get all these untested functions | 2753 | // The only purpose of this test is to get all these untested functions |
| 2696 | // to be referenced to avoid regression so it is okay to skip some targets. | 2754 | // to be referenced to avoid regression so it is okay to skip some targets. |