| author | |
| committer | |
| log | ba2f2e139306618b8beaa8e833b1f9845309df73 |
| tree | a0d0d184a7a3070bca4161d2760e66a57a4256b1 |
| parent | ccdb81fb31f3fa1384b44b74ecdae345457bd0b5 |
| parent | fa09c3a5e7ab855026ae10f9e1f61b05611a2275 |
| signature |
stage2: free Package resources, print package path on --pkg-begin failure 2 files changed, 61 insertions(+), 57 deletions(-)
src/Package.zig+34-22| ... | ... | @@ -1,3 +1,12 @@ |
| 1 | const Package = @This(); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | const fs = std.fs; | |
| 5 | const mem = std.mem; | |
| 6 | const Allocator = mem.Allocator; | |
| 7 | ||
| 8 | const Compilation = @import("Compilation.zig"); | |
| 9 | ||
| 1 | 10 | pub const Table = std.StringHashMapUnmanaged(*Package); |
| 2 | 11 | |
| 3 | 12 | root_src_directory: Compilation.Directory, |
| ... | ... | @@ -6,57 +15,60 @@ root_src_path: []const u8, |
| 6 | 15 | table: Table = .{}, |
| 7 | 16 | parent: ?*Package = null, |
| 8 | 17 | |
| 9 | const std = @import("std"); | |
| 10 | const mem = std.mem; | |
| 11 | const Allocator = std.mem.Allocator; | |
| 12 | const assert = std.debug.assert; | |
| 13 | const Package = @This(); | |
| 14 | const Compilation = @import("Compilation.zig"); | |
| 15 | ||
| 16 | /// No references to `root_src_dir` and `root_src_path` are kept. | |
| 18 | /// Allocate a Package. No references to the slices passed are kept. | |
| 17 | 19 | pub fn create( |
| 18 | 20 | gpa: *Allocator, |
| 19 | base_directory: Compilation.Directory, | |
| 20 | /// Relative to `base_directory`. | |
| 21 | root_src_dir: []const u8, | |
| 22 | /// Relative to `root_src_dir`. | |
| 21 | /// Null indicates the current working directory | |
| 22 | root_src_dir_path: ?[]const u8, | |
| 23 | /// Relative to root_src_dir_path | |
| 23 | 24 | root_src_path: []const u8, |
| 24 | 25 | ) !*Package { |
| 25 | 26 | const ptr = try gpa.create(Package); |
| 26 | 27 | errdefer gpa.destroy(ptr); |
| 27 | 28 | |
| 28 | const root_src_dir_path = try base_directory.join(gpa, &[_][]const u8{root_src_dir}); | |
| 29 | errdefer gpa.free(root_src_dir_path); | |
| 29 | const owned_dir_path = if (root_src_dir_path) |p| try gpa.dupe(u8, p) else null; | |
| 30 | errdefer if (owned_dir_path) |p| gpa.free(p); | |
| 30 | 31 | |
| 31 | const root_src_path_dupe = try mem.dupe(gpa, u8, root_src_path); | |
| 32 | errdefer gpa.free(root_src_path_dupe); | |
| 32 | const owned_src_path = try gpa.dupe(u8, root_src_path); | |
| 33 | errdefer gpa.free(owned_src_path); | |
| 33 | 34 | |
| 34 | 35 | ptr.* = .{ |
| 35 | 36 | .root_src_directory = .{ |
| 36 | .path = root_src_dir_path, | |
| 37 | .handle = try base_directory.handle.openDir(root_src_dir, .{}), | |
| 37 | .path = owned_dir_path, | |
| 38 | .handle = if (owned_dir_path) |p| try fs.cwd().openDir(p, .{}) else fs.cwd(), | |
| 38 | 39 | }, |
| 39 | .root_src_path = root_src_path_dupe, | |
| 40 | .root_src_path = owned_src_path, | |
| 40 | 41 | }; |
| 42 | ||
| 41 | 43 | return ptr; |
| 42 | 44 | } |
| 43 | 45 | |
| 46 | /// Free all memory associated with this package and recursively call destroy | |
| 47 | /// on all packages in its table | |
| 44 | 48 | pub fn destroy(pkg: *Package, gpa: *Allocator) void { |
| 45 | pkg.root_src_directory.handle.close(); | |
| 46 | 49 | gpa.free(pkg.root_src_path); |
| 47 | if (pkg.root_src_directory.path) |p| gpa.free(p); | |
| 50 | ||
| 51 | // If root_src_directory.path is null then the handle is the cwd() | |
| 52 | // which shouldn't be closed. | |
| 53 | if (pkg.root_src_directory.path) |p| { | |
| 54 | gpa.free(p); | |
| 55 | pkg.root_src_directory.handle.close(); | |
| 56 | } | |
| 57 | ||
| 48 | 58 | { |
| 49 | 59 | var it = pkg.table.iterator(); |
| 50 | 60 | while (it.next()) |kv| { |
| 61 | kv.value.destroy(gpa); | |
| 51 | 62 | gpa.free(kv.key); |
| 52 | 63 | } |
| 53 | 64 | } |
| 65 | ||
| 54 | 66 | pkg.table.deinit(gpa); |
| 55 | 67 | gpa.destroy(pkg); |
| 56 | 68 | } |
| 57 | 69 | |
| 58 | 70 | pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void { |
| 59 | try pkg.table.ensureCapacity(gpa, pkg.table.items().len + 1); | |
| 71 | try pkg.table.ensureCapacity(gpa, pkg.table.count() + 1); | |
| 60 | 72 | const name_dupe = try mem.dupe(gpa, u8, name); |
| 61 | 73 | pkg.table.putAssumeCapacityNoClobber(name_dupe, package); |
| 62 | 74 | } |
src/main.zig+27-35| ... | ... | @@ -568,12 +568,15 @@ fn buildOutputType( |
| 568 | 568 | var test_exec_args = std.ArrayList(?[]const u8).init(gpa); |
| 569 | 569 | defer test_exec_args.deinit(); |
| 570 | 570 | |
| 571 | var root_pkg_memory: Package = .{ | |
| 572 | .root_src_directory = undefined, | |
| 573 | .root_src_path = undefined, | |
| 571 | const pkg_tree_root = try gpa.create(Package); | |
| 572 | // This package only exists to clean up the code parsing --pkg-begin and | |
| 573 | // --pkg-end flags. Use dummy values that are safe for the destroy call. | |
| 574 | pkg_tree_root.* = .{ | |
| 575 | .root_src_directory = .{ .path = null, .handle = fs.cwd() }, | |
| 576 | .root_src_path = &[0]u8{}, | |
| 574 | 577 | }; |
| 575 | defer root_pkg_memory.table.deinit(gpa); | |
| 576 | var cur_pkg: *Package = &root_pkg_memory; | |
| 578 | defer pkg_tree_root.destroy(gpa); | |
| 579 | var cur_pkg: *Package = pkg_tree_root; | |
| 577 | 580 | |
| 578 | 581 | switch (arg_mode) { |
| 579 | 582 | .build, .translate_c, .zig_test, .run => { |
| ... | ... | @@ -627,22 +630,15 @@ fn buildOutputType( |
| 627 | 630 | i += 1; |
| 628 | 631 | const pkg_path = args[i]; |
| 629 | 632 | |
| 630 | const new_cur_pkg = try arena.create(Package); | |
| 631 | new_cur_pkg.* = .{ | |
| 632 | .root_src_directory = if (fs.path.dirname(pkg_path)) |dirname| | |
| 633 | .{ | |
| 634 | .path = dirname, | |
| 635 | .handle = try fs.cwd().openDir(dirname, .{}), // TODO close this fd | |
| 636 | } | |
| 637 | else | |
| 638 | .{ | |
| 639 | .path = null, | |
| 640 | .handle = fs.cwd(), | |
| 641 | }, | |
| 642 | .root_src_path = fs.path.basename(pkg_path), | |
| 643 | .parent = cur_pkg, | |
| 633 | const new_cur_pkg = Package.create( | |
| 634 | gpa, | |
| 635 | fs.path.dirname(pkg_path), | |
| 636 | fs.path.basename(pkg_path), | |
| 637 | ) catch |err| { | |
| 638 | fatal("Failed to add package at path {}: {}", .{ pkg_path, @errorName(err) }); | |
| 644 | 639 | }; |
| 645 | try cur_pkg.table.put(gpa, pkg_name, new_cur_pkg); | |
| 640 | new_cur_pkg.parent = cur_pkg; | |
| 641 | try cur_pkg.add(gpa, pkg_name, new_cur_pkg); | |
| 646 | 642 | cur_pkg = new_cur_pkg; |
| 647 | 643 | } else if (mem.eql(u8, arg, "--pkg-end")) { |
| 648 | 644 | cur_pkg = cur_pkg.parent orelse |
| ... | ... | @@ -1600,26 +1596,22 @@ fn buildOutputType( |
| 1600 | 1596 | .yes => |p| p, |
| 1601 | 1597 | }; |
| 1602 | 1598 | |
| 1603 | var cleanup_root_dir: ?fs.Dir = null; | |
| 1604 | defer if (cleanup_root_dir) |*dir| dir.close(); | |
| 1605 | ||
| 1606 | 1599 | const root_pkg: ?*Package = if (root_src_file) |src_path| blk: { |
| 1607 | 1600 | if (main_pkg_path) |p| { |
| 1608 | const dir = try fs.cwd().openDir(p, .{}); | |
| 1609 | cleanup_root_dir = dir; | |
| 1610 | root_pkg_memory.root_src_directory = .{ .path = p, .handle = dir }; | |
| 1611 | root_pkg_memory.root_src_path = try fs.path.relative(arena, p, src_path); | |
| 1612 | } else if (fs.path.dirname(src_path)) |p| { | |
| 1613 | const dir = try fs.cwd().openDir(p, .{}); | |
| 1614 | cleanup_root_dir = dir; | |
| 1615 | root_pkg_memory.root_src_directory = .{ .path = p, .handle = dir }; | |
| 1616 | root_pkg_memory.root_src_path = fs.path.basename(src_path); | |
| 1601 | const rel_src_path = try fs.path.relative(gpa, p, src_path); | |
| 1602 | defer gpa.free(rel_src_path); | |
| 1603 | break :blk try Package.create(gpa, p, rel_src_path); | |
| 1617 | 1604 | } else { |
| 1618 | root_pkg_memory.root_src_directory = .{ .path = null, .handle = fs.cwd() }; | |
| 1619 | root_pkg_memory.root_src_path = src_path; | |
| 1605 | break :blk try Package.create(gpa, fs.path.dirname(src_path), fs.path.basename(src_path)); | |
| 1620 | 1606 | } |
| 1621 | break :blk &root_pkg_memory; | |
| 1622 | 1607 | } else null; |
| 1608 | defer if (root_pkg) |p| p.destroy(gpa); | |
| 1609 | ||
| 1610 | // Transfer packages added with --pkg-begin/--pkg-end to the root package | |
| 1611 | if (root_pkg) |pkg| { | |
| 1612 | pkg.table = pkg_tree_root.table; | |
| 1613 | pkg_tree_root.table = .{}; | |
| 1614 | } | |
| 1623 | 1615 | |
| 1624 | 1616 | const self_exe_path = try fs.selfExePathAlloc(arena); |
| 1625 | 1617 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| |