From 137edcd527e66104a311b2c7243aeb5491e95d03 Mon Sep 17 00:00:00 2001 From: Lee Cannon Date: Mon, 26 Sep 2022 22:01:00 +0100 Subject: [PATCH] use `StringArrayHashMap` to remove duplicate include paths --- src/DocumentStore.zig | 27 +++++++-------------------- src/special/build_runner.zig | 35 +++++++++++++++-------------------- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index 6d685ee..6dce261 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -32,7 +32,7 @@ const BuildFile = struct { pub const BuildFileConfig = struct { packages: []Pkg, - include_dirs: []IncludeDir, + include_dirs: []const []const u8, pub fn deinit(self: BuildFileConfig, allocator: std.mem.Allocator) void { for (self.packages) |pkg| { @@ -42,7 +42,7 @@ pub const BuildFileConfig = struct { allocator.free(self.packages); for (self.include_dirs) |dir| { - allocator.free(dir.path); + allocator.free(dir); } allocator.free(self.include_dirs); } @@ -51,8 +51,6 @@ pub const BuildFileConfig = struct { name: []const u8, uri: []const u8, }; - - pub const IncludeDir = BuildConfig.IncludeDir; }; pub const Handle = struct { @@ -223,10 +221,10 @@ fn loadBuildConfiguration(context: LoadBuildConfigContext) !void { packages.deinit(allocator); } - var include_dirs = try std.ArrayListUnmanaged(BuildFileConfig.IncludeDir).initCapacity(allocator, config.include_dirs.len); + var include_dirs = try std.ArrayListUnmanaged([]const u8).initCapacity(allocator, config.include_dirs.len); errdefer { for (include_dirs.items) |dir| { - allocator.free(dir.path); + allocator.free(dir); } include_dirs.deinit(allocator); } @@ -245,10 +243,10 @@ fn loadBuildConfiguration(context: LoadBuildConfigContext) !void { } for (config.include_dirs) |dir| { - const path = try allocator.dupe(u8, dir.path); + const path = try allocator.dupe(u8, dir); errdefer allocator.free(path); - include_dirs.appendAssumeCapacity(.{ .path = path, .system = dir.system }); + include_dirs.appendAssumeCapacity(path); } build_file.config = .{ @@ -655,18 +653,7 @@ fn collectCIncludes(self: *DocumentStore, handle: *Handle) ![]CImportHandle { } fn translate(self: *DocumentStore, handle: *Handle, source: []const u8) error{OutOfMemory}!?translate_c.Result { - const dirs: []BuildConfig.IncludeDir = if (handle.associated_build_file) |build_file| build_file.config.include_dirs else &.{}; - const include_dirs = blk: { - var result = try self.allocator.alloc([]const u8, dirs.len); - errdefer self.allocator.free(result); - - for (dirs) |dir, i| { - result[i] = dir.path; - } - - break :blk result; - }; - defer self.allocator.free(include_dirs); + const include_dirs: []const []const u8 = if (handle.associated_build_file) |build_file| build_file.config.include_dirs else &.{}; const maybe_result = try translate_c.translate( self.allocator, diff --git a/src/special/build_runner.zig b/src/special/build_runner.zig index 1389746..baa69ee 100644 --- a/src/special/build_runner.zig +++ b/src/special/build_runner.zig @@ -8,17 +8,12 @@ const LibExeObjStep = std.build.LibExeObjStep; pub const BuildConfig = struct { packages: []Pkg, - include_dirs: []IncludeDir, + include_dirs: []const []const u8, pub const Pkg = struct { name: []const u8, path: []const u8, }; - - pub const IncludeDir = struct { - path: []const u8, - system: bool, - }; }; ///! This is a modified build runner to extract information out of build.zig @@ -68,7 +63,7 @@ pub fn main() !void { var packages = std.ArrayListUnmanaged(BuildConfig.Pkg){}; defer packages.deinit(allocator); - var include_dirs = std.ArrayListUnmanaged(BuildConfig.IncludeDir){}; + var include_dirs: std.StringArrayHashMapUnmanaged(void) = .{}; defer include_dirs.deinit(allocator); // TODO: We currently add packages from every LibExeObj step that the install step depends on. @@ -83,7 +78,7 @@ pub fn main() !void { try std.json.stringify( BuildConfig{ .packages = packages.items, - .include_dirs = include_dirs.items, + .include_dirs = include_dirs.keys(), }, .{ .whitespace = .{} }, std.io.getStdOut().writer(), @@ -93,7 +88,7 @@ pub fn main() !void { fn processStep( allocator: std.mem.Allocator, packages: *std.ArrayListUnmanaged(BuildConfig.Pkg), - include_dirs: *std.ArrayListUnmanaged(BuildConfig.IncludeDir), + include_dirs: *std.StringArrayHashMapUnmanaged(void), step: *std.build.Step, ) anyerror!void { if (step.cast(InstallArtifactStep)) |install_exe| { @@ -143,29 +138,27 @@ fn processPackage( fn processIncludeDirs( allocator: std.mem.Allocator, - include_dirs: *std.ArrayListUnmanaged(BuildConfig.IncludeDir), + include_dirs: *std.StringArrayHashMapUnmanaged(void), dirs: []std.build.LibExeObjStep.IncludeDir, ) !void { try include_dirs.ensureUnusedCapacity(allocator, dirs.len); - outer: for (dirs) |dir| { - const candidate: BuildConfig.IncludeDir = switch (dir) { - .raw_path => |path| .{ .path = path, .system = false }, - .raw_path_system => |path| .{ .path = path, .system = true }, + for (dirs) |dir| { + const candidate: []const u8 = switch (dir) { + .raw_path => |path| path, + .raw_path_system => |path| path, else => continue, }; - for (include_dirs.items) |include_dir| { - if (std.mem.eql(u8, candidate.path, include_dir.path)) continue :outer; - } + if (include_dirs.contains(candidate)) continue; - include_dirs.appendAssumeCapacity(candidate); + include_dirs.putAssumeCapacityNoClobber(candidate, {}); } } fn processPkgConfig( allocator: std.mem.Allocator, - include_dirs: *std.ArrayListUnmanaged(BuildConfig.IncludeDir), + include_dirs: *std.StringArrayHashMapUnmanaged(void), exe: *std.build.LibExeObjStep, ) !void { for (exe.link_objects.items) |link_object| { @@ -177,7 +170,9 @@ fn processPkgConfig( if (exe.runPkgConfig(system_lib.name)) |args| { for (args) |arg| { if (std.mem.startsWith(u8, arg, "-I")) { - try include_dirs.append(allocator, .{ .path = arg[2..], .system = true }); + const candidate = arg[2..]; + if (include_dirs.contains(candidate)) continue; + try include_dirs.putNoClobber(allocator, candidate, {}); } } } else |err| switch (err) {