mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Dupe strings on all public api points for std.build
This commit is contained in:
parent
5e81b048a0
commit
1032a69321
@ -345,6 +345,14 @@ pub const Builder = struct {
|
||||
return self.allocator.dupe(u8, bytes) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn dupeStrings(self: *Builder, strings: []const []const u8) [][]u8 {
|
||||
const array = self.allocator.alloc([]u8, strings.len) catch unreachable;
|
||||
for (strings) |s, i| {
|
||||
array[i] = self.dupe(s);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
pub fn dupePath(self: *Builder, bytes: []const u8) []u8 {
|
||||
const the_copy = self.dupe(bytes);
|
||||
for (the_copy) |*byte| {
|
||||
@ -490,7 +498,9 @@ pub const Builder = struct {
|
||||
return error.InvalidStepName;
|
||||
}
|
||||
|
||||
pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
|
||||
pub fn option(self: *Builder, comptime T: type, name_raw: []const u8, description_raw: []const u8) ?T {
|
||||
const name = self.dupe(name_raw);
|
||||
const description = self.dupe(description_raw);
|
||||
const type_id = comptime typeToEnum(T);
|
||||
const available_option = AvailableOption{
|
||||
.name = name,
|
||||
@ -623,7 +633,7 @@ pub const Builder = struct {
|
||||
const step_info = self.allocator.create(TopLevelStep) catch unreachable;
|
||||
step_info.* = TopLevelStep{
|
||||
.step = Step.initNoOp(.TopLevel, name, self.allocator),
|
||||
.description = description,
|
||||
.description = self.dupe(description),
|
||||
};
|
||||
self.top_level_steps.append(step_info) catch unreachable;
|
||||
return &step_info.step;
|
||||
@ -760,7 +770,9 @@ pub const Builder = struct {
|
||||
return selected_target;
|
||||
}
|
||||
|
||||
pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {
|
||||
pub fn addUserInputOption(self: *Builder, name_raw: []const u8, value_raw: []const u8) !bool {
|
||||
const name = self.dupe(name_raw);
|
||||
const value = self.dupe(value_raw);
|
||||
const gop = try self.user_input_options.getOrPut(name);
|
||||
if (!gop.found_existing) {
|
||||
gop.entry.value = UserInputOption{
|
||||
@ -801,7 +813,8 @@ pub const Builder = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn addUserInputFlag(self: *Builder, name: []const u8) !bool {
|
||||
pub fn addUserInputFlag(self: *Builder, name_raw: []const u8) !bool {
|
||||
const name = self.dupe(name_raw);
|
||||
const gop = try self.user_input_options.getOrPut(name);
|
||||
if (!gop.found_existing) {
|
||||
gop.entry.value = UserInputOption{
|
||||
@ -993,10 +1006,11 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
pub fn pushInstalledFile(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) void {
|
||||
self.installed_files.append(InstalledFile{
|
||||
const file = InstalledFile{
|
||||
.dir = dir,
|
||||
.path = dest_rel_path,
|
||||
}) catch unreachable;
|
||||
};
|
||||
self.installed_files.append(file.dupe(self)) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
|
||||
@ -1139,7 +1153,7 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
pub fn addSearchPrefix(self: *Builder, search_prefix: []const u8) void {
|
||||
self.search_prefixes.append(search_prefix) catch unreachable;
|
||||
self.search_prefixes.append(self.dupePath(search_prefix)) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
|
||||
@ -1160,6 +1174,7 @@ pub const Builder = struct {
|
||||
fn execPkgConfigList(self: *Builder, out_code: *u8) ![]const PkgConfigPkg {
|
||||
const stdout = try self.execAllowFail(&[_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore);
|
||||
var list = ArrayList(PkgConfigPkg).init(self.allocator);
|
||||
errdefer list.deinit();
|
||||
var line_it = mem.tokenize(stdout, "\r\n");
|
||||
while (line_it.next()) |line| {
|
||||
if (mem.trim(u8, line, " \t").len == 0) continue;
|
||||
@ -1169,7 +1184,7 @@ pub const Builder = struct {
|
||||
.desc = tok_it.rest(),
|
||||
});
|
||||
}
|
||||
return list.items;
|
||||
return list.toOwnedSlice();
|
||||
}
|
||||
|
||||
fn getPkgConfigList(self: *Builder) ![]const PkgConfigPkg {
|
||||
@ -1224,9 +1239,16 @@ pub const Pkg = struct {
|
||||
dependencies: ?[]const Pkg = null,
|
||||
};
|
||||
|
||||
const CSourceFile = struct {
|
||||
pub const CSourceFile = struct {
|
||||
source: FileSource,
|
||||
args: []const []const u8,
|
||||
|
||||
fn dupe(self: CSourceFile, b: *Builder) CSourceFile {
|
||||
return .{
|
||||
.source = self.source.dupe(b),
|
||||
.args = b.dupeStrings(self.args),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const CSourceFiles = struct {
|
||||
@ -1268,6 +1290,17 @@ pub const FileSource = union(enum) {
|
||||
.translate_c => |tc| tc.getOutputPath(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn dupe(self: FileSource, b: *Builder) FileSource {
|
||||
return switch (self) {
|
||||
.path => |p| .{ .path = b.dupe(p) },
|
||||
.write_file => |wf| .{ .write_file = .{
|
||||
.step = wf.step,
|
||||
.basename = b.dupe(wf.basename),
|
||||
} },
|
||||
.translate_c => |tc| .{ .translate_c = tc },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const BuildOptionArtifactArg = struct {
|
||||
@ -1443,12 +1476,14 @@ pub const LibExeObjStep = struct {
|
||||
|
||||
fn initExtraArgs(
|
||||
builder: *Builder,
|
||||
name: []const u8,
|
||||
root_src: ?FileSource,
|
||||
name_raw: []const u8,
|
||||
root_src_raw: ?FileSource,
|
||||
kind: Kind,
|
||||
is_dynamic: bool,
|
||||
ver: ?Version,
|
||||
) LibExeObjStep {
|
||||
const name = builder.dupe(name_raw);
|
||||
const root_src: ?FileSource = if (root_src_raw) |rsrc| rsrc.dupe(builder) else null;
|
||||
if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
|
||||
panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
|
||||
}
|
||||
@ -1585,12 +1620,12 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
|
||||
pub fn setLinkerScriptPath(self: *LibExeObjStep, path: []const u8) void {
|
||||
self.linker_script = path;
|
||||
self.linker_script = self.builder.dupePath(path);
|
||||
}
|
||||
|
||||
pub fn linkFramework(self: *LibExeObjStep, framework_name: []const u8) void {
|
||||
assert(self.target.isDarwin());
|
||||
self.frameworks.put(framework_name) catch unreachable;
|
||||
self.frameworks.put(self.builder.dupe(framework_name)) catch unreachable;
|
||||
}
|
||||
|
||||
/// Returns whether the library, executable, or object depends on a particular system library.
|
||||
@ -1754,25 +1789,23 @@ pub const LibExeObjStep = struct {
|
||||
|
||||
pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void {
|
||||
assert(self.kind == Kind.Test);
|
||||
self.name_prefix = text;
|
||||
self.name_prefix = self.builder.dupe(text);
|
||||
}
|
||||
|
||||
pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void {
|
||||
assert(self.kind == Kind.Test);
|
||||
self.filter = text;
|
||||
self.filter = if (text) |t| self.builder.dupe(t) else null;
|
||||
}
|
||||
|
||||
/// Handy when you have many C/C++ source files and want them all to have the same flags.
|
||||
pub fn addCSourceFiles(self: *LibExeObjStep, files: []const []const u8, flags: []const []const u8) void {
|
||||
const c_source_files = self.builder.allocator.create(CSourceFiles) catch unreachable;
|
||||
|
||||
const flags_copy = self.builder.allocator.alloc([]u8, flags.len) catch unreachable;
|
||||
for (flags) |flag, i| {
|
||||
flags_copy[i] = self.builder.dupe(flag);
|
||||
}
|
||||
const files_copy = self.builder.dupeStrings(files);
|
||||
const flags_copy = self.builder.dupeStrings(flags);
|
||||
|
||||
c_source_files.* = .{
|
||||
.files = files,
|
||||
.files = files_copy,
|
||||
.flags = flags_copy,
|
||||
};
|
||||
self.link_objects.append(LinkObject{ .CSourceFiles = c_source_files }) catch unreachable;
|
||||
@ -1787,14 +1820,7 @@ pub const LibExeObjStep = struct {
|
||||
|
||||
pub fn addCSourceFileSource(self: *LibExeObjStep, source: CSourceFile) void {
|
||||
const c_source_file = self.builder.allocator.create(CSourceFile) catch unreachable;
|
||||
|
||||
const args_copy = self.builder.allocator.alloc([]u8, source.args.len) catch unreachable;
|
||||
for (source.args) |arg, i| {
|
||||
args_copy[i] = self.builder.dupe(arg);
|
||||
}
|
||||
|
||||
c_source_file.* = source;
|
||||
c_source_file.args = args_copy;
|
||||
c_source_file.* = source.dupe(self.builder);
|
||||
self.link_objects.append(LinkObject{ .CSourceFile = c_source_file }) catch unreachable;
|
||||
}
|
||||
|
||||
@ -1811,15 +1837,15 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
|
||||
pub fn overrideZigLibDir(self: *LibExeObjStep, dir_path: []const u8) void {
|
||||
self.override_lib_dir = self.builder.dupe(dir_path);
|
||||
self.override_lib_dir = self.builder.dupePath(dir_path);
|
||||
}
|
||||
|
||||
pub fn setMainPkgPath(self: *LibExeObjStep, dir_path: []const u8) void {
|
||||
self.main_pkg_path = dir_path;
|
||||
self.main_pkg_path = self.builder.dupePath(dir_path);
|
||||
}
|
||||
|
||||
pub fn setLibCFile(self: *LibExeObjStep, libc_file: ?[]const u8) void {
|
||||
self.libc_file = libc_file;
|
||||
self.libc_file = if (libc_file) |f| self.builder.dupe(f) else null;
|
||||
}
|
||||
|
||||
/// Unless setOutputDir was called, this function must be called only in
|
||||
@ -1879,8 +1905,9 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
|
||||
pub fn addAssemblyFileSource(self: *LibExeObjStep, source: FileSource) void {
|
||||
self.link_objects.append(LinkObject{ .AssemblyFile = source }) catch unreachable;
|
||||
source.addStepDependencies(&self.step);
|
||||
const source_duped = source.dupe(self.builder);
|
||||
self.link_objects.append(LinkObject{ .AssemblyFile = source_duped }) catch unreachable;
|
||||
source_duped.addStepDependencies(&self.step);
|
||||
}
|
||||
|
||||
pub fn addObjectFile(self: *LibExeObjStep, path: []const u8) void {
|
||||
@ -1977,7 +2004,7 @@ pub const LibExeObjStep = struct {
|
||||
/// The value is the path in the cache dir.
|
||||
/// Adds a dependency automatically.
|
||||
pub fn addBuildOptionArtifact(self: *LibExeObjStep, name: []const u8, artifact: *LibExeObjStep) void {
|
||||
self.build_options_artifact_args.append(.{ .name = name, .artifact = artifact }) catch unreachable;
|
||||
self.build_options_artifact_args.append(.{ .name = self.builder.dupe(name), .artifact = artifact }) catch unreachable;
|
||||
self.step.dependOn(&artifact.step);
|
||||
}
|
||||
|
||||
@ -2047,7 +2074,11 @@ pub const LibExeObjStep = struct {
|
||||
|
||||
pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
|
||||
assert(self.kind == Kind.Test);
|
||||
self.exec_cmd_args = args;
|
||||
const duped_args = self.builder.allocator.alloc(?[]u8, args.len) catch unreachable;
|
||||
for (args) |arg, i| {
|
||||
duped_args[i] = if (arg) |a| self.builder.dupe(a) else null;
|
||||
}
|
||||
self.exec_cmd_args = duped_args;
|
||||
}
|
||||
|
||||
fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
|
||||
@ -2665,9 +2696,9 @@ pub const InstallFileStep = struct {
|
||||
return InstallFileStep{
|
||||
.builder = builder,
|
||||
.step = Step.init(.InstallFile, builder.fmt("install {s}", .{src_path}), builder.allocator, make),
|
||||
.src_path = src_path,
|
||||
.dir = dir,
|
||||
.dest_rel_path = dest_rel_path,
|
||||
.src_path = builder.dupePath(src_path),
|
||||
.dir = dir.dupe(builder),
|
||||
.dest_rel_path = builder.dupePath(dest_rel_path),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2684,6 +2715,16 @@ pub const InstallDirectoryOptions = struct {
|
||||
install_dir: InstallDir,
|
||||
install_subdir: []const u8,
|
||||
exclude_extensions: ?[]const []const u8 = null,
|
||||
|
||||
fn dupe(self: InstallDirectoryOptions, b: *Builder) InstallDirectoryOptions {
|
||||
return .{
|
||||
.source_dir = b.dupe(self.source_dir),
|
||||
.install_dir = self.install_dir.dupe(b),
|
||||
.install_subdir = b.dupe(self.install_subdir),
|
||||
.exclude_extensions = if (self.exclude_extensions) |extensions|
|
||||
b.dupeStrings(extensions) else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const InstallDirStep = struct {
|
||||
@ -2699,7 +2740,7 @@ pub const InstallDirStep = struct {
|
||||
return InstallDirStep{
|
||||
.builder = builder,
|
||||
.step = Step.init(.InstallDir, builder.fmt("install {s}/", .{options.source_dir}), builder.allocator, make),
|
||||
.options = options,
|
||||
.options = options.dupe(builder),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2735,7 +2776,7 @@ pub const LogStep = struct {
|
||||
return LogStep{
|
||||
.builder = builder,
|
||||
.step = Step.init(.Log, builder.fmt("log {s}", .{data}), builder.allocator, make),
|
||||
.data = data,
|
||||
.data = builder.dupe(data),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2754,7 +2795,7 @@ pub const RemoveDirStep = struct {
|
||||
return RemoveDirStep{
|
||||
.builder = builder,
|
||||
.step = Step.init(.RemoveDir, builder.fmt("RemoveDir {s}", .{dir_path}), builder.allocator, make),
|
||||
.dir_path = dir_path,
|
||||
.dir_path = builder.dupePath(dir_path),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2798,7 +2839,7 @@ pub const Step = struct {
|
||||
pub fn init(id: Id, name: []const u8, allocator: *Allocator, makeFn: fn (*Step) anyerror!void) Step {
|
||||
return Step{
|
||||
.id = id,
|
||||
.name = name,
|
||||
.name = allocator.dupe(u8, name) catch unreachable,
|
||||
.makeFn = makeFn,
|
||||
.dependencies = ArrayList(*Step).init(allocator),
|
||||
.loop_flag = false,
|
||||
@ -2905,11 +2946,28 @@ pub const InstallDir = union(enum) {
|
||||
Header: void,
|
||||
/// A path relative to the prefix
|
||||
Custom: []const u8,
|
||||
|
||||
fn dupe(self: InstallDir, builder: *Builder) InstallDir {
|
||||
if (self == .Custom) {
|
||||
// Written with this temporary to avoid RLS problems
|
||||
const duped_path = builder.dupe(self.Custom);
|
||||
return .{ .Custom = duped_path };
|
||||
} else {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const InstalledFile = struct {
|
||||
dir: InstallDir,
|
||||
path: []const u8,
|
||||
|
||||
pub fn dupe(self: InstalledFile, builder: *Builder) InstalledFile {
|
||||
return .{
|
||||
.dir = self.dir.dupe(builder),
|
||||
.path = builder.dupe(self.path),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
test "Builder.dupePkg()" {
|
||||
|
||||
@ -27,8 +27,8 @@ pub const CheckFileStep = struct {
|
||||
self.* = CheckFileStep{
|
||||
.builder = builder,
|
||||
.step = Step.init(.CheckFile, "CheckFile", builder.allocator, make),
|
||||
.source = source,
|
||||
.expected_matches = expected_matches,
|
||||
.source = source.dupe(builder),
|
||||
.expected_matches = builder.dupeStrings(expected_matches),
|
||||
};
|
||||
self.source.addStepDependencies(&self.step);
|
||||
return self;
|
||||
|
||||
@ -76,7 +76,7 @@ pub const RunStep = struct {
|
||||
self.argv.append(Arg{
|
||||
.WriteFile = .{
|
||||
.step = write_file,
|
||||
.file_name = file_name,
|
||||
.file_name = self.builder.dupePath(file_name),
|
||||
},
|
||||
}) catch unreachable;
|
||||
self.step.dependOn(&write_file.step);
|
||||
@ -119,7 +119,7 @@ pub const RunStep = struct {
|
||||
const new_path = self.builder.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path });
|
||||
env_map.set(key, new_path) catch unreachable;
|
||||
} else {
|
||||
env_map.set(key, search_path) catch unreachable;
|
||||
env_map.set(key, self.builder.dupePath(search_path)) catch unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,15 +134,18 @@ pub const RunStep = struct {
|
||||
|
||||
pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8) void {
|
||||
const env_map = self.getEnvMap();
|
||||
env_map.set(key, value) catch unreachable;
|
||||
env_map.set(
|
||||
self.builder.dupe(key),
|
||||
self.builder.dupe(value),
|
||||
) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn expectStdErrEqual(self: *RunStep, bytes: []const u8) void {
|
||||
self.stderr_action = .{ .expect_exact = bytes };
|
||||
self.stderr_action = .{ .expect_exact = self.builder.dupe(bytes) };
|
||||
}
|
||||
|
||||
pub fn expectStdOutEqual(self: *RunStep, bytes: []const u8) void {
|
||||
self.stdout_action = .{ .expect_exact = bytes };
|
||||
self.stdout_action = .{ .expect_exact = self.builder.dupe(bytes) };
|
||||
}
|
||||
|
||||
fn stdIoActionToBehavior(action: StdIoAction) std.ChildProcess.StdIo {
|
||||
|
||||
@ -57,11 +57,11 @@ pub const TranslateCStep = struct {
|
||||
}
|
||||
|
||||
pub fn addIncludeDir(self: *TranslateCStep, include_dir: []const u8) void {
|
||||
self.include_dirs.append(include_dir) catch unreachable;
|
||||
self.include_dirs.append(self.builder.dupePath(include_dir)) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn addCheckFile(self: *TranslateCStep, expected_matches: []const []const u8) *CheckFileStep {
|
||||
return CheckFileStep.create(self.builder, .{ .translate_c = self }, expected_matches);
|
||||
return CheckFileStep.create(self.builder, .{ .translate_c = self }, self.builder.dupeStrings(expected_matches));
|
||||
}
|
||||
|
||||
fn make(step: *Step) !void {
|
||||
|
||||
@ -32,7 +32,10 @@ pub const WriteFileStep = struct {
|
||||
}
|
||||
|
||||
pub fn add(self: *WriteFileStep, basename: []const u8, bytes: []const u8) void {
|
||||
self.files.append(.{ .basename = basename, .bytes = bytes }) catch unreachable;
|
||||
self.files.append(.{
|
||||
.basename = self.builder.dupePath(basename),
|
||||
.bytes = self.builder.dupe(bytes),
|
||||
}) catch unreachable;
|
||||
}
|
||||
|
||||
/// Unless setOutputDir was called, this function must be called only in
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user