authorgravatar for spexguy070@gmail.comMartin Wickham <spexguy070@gmail.com> 2021-01-31 13:02:19-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-01 12:31:24-08:00
log1032a693211dd96abe349bfa76b43bb1f226cfda
tree2333516713e6e708d4a4a83f0c5a1ee4230d82e3
parent5e81b048a0966815cc1911e33144ed6ffad37ba1

Dupe strings on all public api points for std.build


5 files changed, 116 insertions(+), 52 deletions(-)

lib/std/build.zig+100-42
......@@ -345,6 +345,14 @@ pub const Builder = struct {
345345 return self.allocator.dupe(u8, bytes) catch unreachable;
346346 }
347347
348 pub fn dupeStrings(self: *Builder, strings: []const []const u8) [][]u8 {
349 const array = self.allocator.alloc([]u8, strings.len) catch unreachable;
350 for (strings) |s, i| {
351 array[i] = self.dupe(s);
352 }
353 return array;
354 }
355
348356 pub fn dupePath(self: *Builder, bytes: []const u8) []u8 {
349357 const the_copy = self.dupe(bytes);
350358 for (the_copy) |*byte| {
......@@ -490,7 +498,9 @@ pub const Builder = struct {
490498 return error.InvalidStepName;
491499 }
492500
493 pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
501 pub fn option(self: *Builder, comptime T: type, name_raw: []const u8, description_raw: []const u8) ?T {
502 const name = self.dupe(name_raw);
503 const description = self.dupe(description_raw);
494504 const type_id = comptime typeToEnum(T);
495505 const available_option = AvailableOption{
496506 .name = name,
......@@ -623,7 +633,7 @@ pub const Builder = struct {
623633 const step_info = self.allocator.create(TopLevelStep) catch unreachable;
624634 step_info.* = TopLevelStep{
625635 .step = Step.initNoOp(.TopLevel, name, self.allocator),
626 .description = description,
636 .description = self.dupe(description),
627637 };
628638 self.top_level_steps.append(step_info) catch unreachable;
629639 return &step_info.step;
......@@ -760,7 +770,9 @@ pub const Builder = struct {
760770 return selected_target;
761771 }
762772
763 pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool {
773 pub fn addUserInputOption(self: *Builder, name_raw: []const u8, value_raw: []const u8) !bool {
774 const name = self.dupe(name_raw);
775 const value = self.dupe(value_raw);
764776 const gop = try self.user_input_options.getOrPut(name);
765777 if (!gop.found_existing) {
766778 gop.entry.value = UserInputOption{
......@@ -801,7 +813,8 @@ pub const Builder = struct {
801813 return false;
802814 }
803815
804 pub fn addUserInputFlag(self: *Builder, name: []const u8) !bool {
816 pub fn addUserInputFlag(self: *Builder, name_raw: []const u8) !bool {
817 const name = self.dupe(name_raw);
805818 const gop = try self.user_input_options.getOrPut(name);
806819 if (!gop.found_existing) {
807820 gop.entry.value = UserInputOption{
......@@ -993,10 +1006,11 @@ pub const Builder = struct {
9931006 }
9941007
9951008 pub fn pushInstalledFile(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) void {
996 self.installed_files.append(InstalledFile{
1009 const file = InstalledFile{
9971010 .dir = dir,
9981011 .path = dest_rel_path,
999 }) catch unreachable;
1012 };
1013 self.installed_files.append(file.dupe(self)) catch unreachable;
10001014 }
10011015
10021016 pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
......@@ -1139,7 +1153,7 @@ pub const Builder = struct {
11391153 }
11401154
11411155 pub fn addSearchPrefix(self: *Builder, search_prefix: []const u8) void {
1142 self.search_prefixes.append(search_prefix) catch unreachable;
1156 self.search_prefixes.append(self.dupePath(search_prefix)) catch unreachable;
11431157 }
11441158
11451159 pub fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
......@@ -1160,6 +1174,7 @@ pub const Builder = struct {
11601174 fn execPkgConfigList(self: *Builder, out_code: *u8) ![]const PkgConfigPkg {
11611175 const stdout = try self.execAllowFail(&[_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore);
11621176 var list = ArrayList(PkgConfigPkg).init(self.allocator);
1177 errdefer list.deinit();
11631178 var line_it = mem.tokenize(stdout, "\r\n");
11641179 while (line_it.next()) |line| {
11651180 if (mem.trim(u8, line, " \t").len == 0) continue;
......@@ -1169,7 +1184,7 @@ pub const Builder = struct {
11691184 .desc = tok_it.rest(),
11701185 });
11711186 }
1172 return list.items;
1187 return list.toOwnedSlice();
11731188 }
11741189
11751190 fn getPkgConfigList(self: *Builder) ![]const PkgConfigPkg {
......@@ -1224,9 +1239,16 @@ pub const Pkg = struct {
12241239 dependencies: ?[]const Pkg = null,
12251240};
12261241
1227const CSourceFile = struct {
1242pub const CSourceFile = struct {
12281243 source: FileSource,
12291244 args: []const []const u8,
1245
1246 fn dupe(self: CSourceFile, b: *Builder) CSourceFile {
1247 return .{
1248 .source = self.source.dupe(b),
1249 .args = b.dupeStrings(self.args),
1250 };
1251 }
12301252};
12311253
12321254const CSourceFiles = struct {
......@@ -1268,6 +1290,17 @@ pub const FileSource = union(enum) {
12681290 .translate_c => |tc| tc.getOutputPath(),
12691291 };
12701292 }
1293
1294 pub fn dupe(self: FileSource, b: *Builder) FileSource {
1295 return switch (self) {
1296 .path => |p| .{ .path = b.dupe(p) },
1297 .write_file => |wf| .{ .write_file = .{
1298 .step = wf.step,
1299 .basename = b.dupe(wf.basename),
1300 } },
1301 .translate_c => |tc| .{ .translate_c = tc },
1302 };
1303 }
12711304};
12721305
12731306const BuildOptionArtifactArg = struct {
......@@ -1443,12 +1476,14 @@ pub const LibExeObjStep = struct {
14431476
14441477 fn initExtraArgs(
14451478 builder: *Builder,
1446 name: []const u8,
1447 root_src: ?FileSource,
1479 name_raw: []const u8,
1480 root_src_raw: ?FileSource,
14481481 kind: Kind,
14491482 is_dynamic: bool,
14501483 ver: ?Version,
14511484 ) LibExeObjStep {
1485 const name = builder.dupe(name_raw);
1486 const root_src: ?FileSource = if (root_src_raw) |rsrc| rsrc.dupe(builder) else null;
14521487 if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
14531488 panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
14541489 }
......@@ -1585,12 +1620,12 @@ pub const LibExeObjStep = struct {
15851620 }
15861621
15871622 pub fn setLinkerScriptPath(self: *LibExeObjStep, path: []const u8) void {
1588 self.linker_script = path;
1623 self.linker_script = self.builder.dupePath(path);
15891624 }
15901625
15911626 pub fn linkFramework(self: *LibExeObjStep, framework_name: []const u8) void {
15921627 assert(self.target.isDarwin());
1593 self.frameworks.put(framework_name) catch unreachable;
1628 self.frameworks.put(self.builder.dupe(framework_name)) catch unreachable;
15941629 }
15951630
15961631 /// Returns whether the library, executable, or object depends on a particular system library.
......@@ -1754,25 +1789,23 @@ pub const LibExeObjStep = struct {
17541789
17551790 pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void {
17561791 assert(self.kind == Kind.Test);
1757 self.name_prefix = text;
1792 self.name_prefix = self.builder.dupe(text);
17581793 }
17591794
17601795 pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void {
17611796 assert(self.kind == Kind.Test);
1762 self.filter = text;
1797 self.filter = if (text) |t| self.builder.dupe(t) else null;
17631798 }
17641799
17651800 /// Handy when you have many C/C++ source files and want them all to have the same flags.
17661801 pub fn addCSourceFiles(self: *LibExeObjStep, files: []const []const u8, flags: []const []const u8) void {
17671802 const c_source_files = self.builder.allocator.create(CSourceFiles) catch unreachable;
17681803
1769 const flags_copy = self.builder.allocator.alloc([]u8, flags.len) catch unreachable;
1770 for (flags) |flag, i| {
1771 flags_copy[i] = self.builder.dupe(flag);
1772 }
1804 const files_copy = self.builder.dupeStrings(files);
1805 const flags_copy = self.builder.dupeStrings(flags);
17731806
17741807 c_source_files.* = .{
1775 .files = files,
1808 .files = files_copy,
17761809 .flags = flags_copy,
17771810 };
17781811 self.link_objects.append(LinkObject{ .CSourceFiles = c_source_files }) catch unreachable;
......@@ -1787,14 +1820,7 @@ pub const LibExeObjStep = struct {
17871820
17881821 pub fn addCSourceFileSource(self: *LibExeObjStep, source: CSourceFile) void {
17891822 const c_source_file = self.builder.allocator.create(CSourceFile) catch unreachable;
1790
1791 const args_copy = self.builder.allocator.alloc([]u8, source.args.len) catch unreachable;
1792 for (source.args) |arg, i| {
1793 args_copy[i] = self.builder.dupe(arg);
1794 }
1795
1796 c_source_file.* = source;
1797 c_source_file.args = args_copy;
1823 c_source_file.* = source.dupe(self.builder);
17981824 self.link_objects.append(LinkObject{ .CSourceFile = c_source_file }) catch unreachable;
17991825 }
18001826
......@@ -1811,15 +1837,15 @@ pub const LibExeObjStep = struct {
18111837 }
18121838
18131839 pub fn overrideZigLibDir(self: *LibExeObjStep, dir_path: []const u8) void {
1814 self.override_lib_dir = self.builder.dupe(dir_path);
1840 self.override_lib_dir = self.builder.dupePath(dir_path);
18151841 }
18161842
18171843 pub fn setMainPkgPath(self: *LibExeObjStep, dir_path: []const u8) void {
1818 self.main_pkg_path = dir_path;
1844 self.main_pkg_path = self.builder.dupePath(dir_path);
18191845 }
18201846
18211847 pub fn setLibCFile(self: *LibExeObjStep, libc_file: ?[]const u8) void {
1822 self.libc_file = libc_file;
1848 self.libc_file = if (libc_file) |f| self.builder.dupe(f) else null;
18231849 }
18241850
18251851 /// Unless setOutputDir was called, this function must be called only in
......@@ -1879,8 +1905,9 @@ pub const LibExeObjStep = struct {
18791905 }
18801906
18811907 pub fn addAssemblyFileSource(self: *LibExeObjStep, source: FileSource) void {
1882 self.link_objects.append(LinkObject{ .AssemblyFile = source }) catch unreachable;
1883 source.addStepDependencies(&self.step);
1908 const source_duped = source.dupe(self.builder);
1909 self.link_objects.append(LinkObject{ .AssemblyFile = source_duped }) catch unreachable;
1910 source_duped.addStepDependencies(&self.step);
18841911 }
18851912
18861913 pub fn addObjectFile(self: *LibExeObjStep, path: []const u8) void {
......@@ -1977,7 +2004,7 @@ pub const LibExeObjStep = struct {
19772004 /// The value is the path in the cache dir.
19782005 /// Adds a dependency automatically.
19792006 pub fn addBuildOptionArtifact(self: *LibExeObjStep, name: []const u8, artifact: *LibExeObjStep) void {
1980 self.build_options_artifact_args.append(.{ .name = name, .artifact = artifact }) catch unreachable;
2007 self.build_options_artifact_args.append(.{ .name = self.builder.dupe(name), .artifact = artifact }) catch unreachable;
19812008 self.step.dependOn(&artifact.step);
19822009 }
19832010
......@@ -2047,7 +2074,11 @@ pub const LibExeObjStep = struct {
20472074
20482075 pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
20492076 assert(self.kind == Kind.Test);
2050 self.exec_cmd_args = args;
2077 const duped_args = self.builder.allocator.alloc(?[]u8, args.len) catch unreachable;
2078 for (args) |arg, i| {
2079 duped_args[i] = if (arg) |a| self.builder.dupe(a) else null;
2080 }
2081 self.exec_cmd_args = duped_args;
20512082 }
20522083
20532084 fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void {
......@@ -2665,9 +2696,9 @@ pub const InstallFileStep = struct {
26652696 return InstallFileStep{
26662697 .builder = builder,
26672698 .step = Step.init(.InstallFile, builder.fmt("install {s}", .{src_path}), builder.allocator, make),
2668 .src_path = src_path,
2669 .dir = dir,
2670 .dest_rel_path = dest_rel_path,
2699 .src_path = builder.dupePath(src_path),
2700 .dir = dir.dupe(builder),
2701 .dest_rel_path = builder.dupePath(dest_rel_path),
26712702 };
26722703 }
26732704
......@@ -2684,6 +2715,16 @@ pub const InstallDirectoryOptions = struct {
26842715 install_dir: InstallDir,
26852716 install_subdir: []const u8,
26862717 exclude_extensions: ?[]const []const u8 = null,
2718
2719 fn dupe(self: InstallDirectoryOptions, b: *Builder) InstallDirectoryOptions {
2720 return .{
2721 .source_dir = b.dupe(self.source_dir),
2722 .install_dir = self.install_dir.dupe(b),
2723 .install_subdir = b.dupe(self.install_subdir),
2724 .exclude_extensions = if (self.exclude_extensions) |extensions|
2725 b.dupeStrings(extensions) else null,
2726 };
2727 }
26872728};
26882729
26892730pub const InstallDirStep = struct {
......@@ -2699,7 +2740,7 @@ pub const InstallDirStep = struct {
26992740 return InstallDirStep{
27002741 .builder = builder,
27012742 .step = Step.init(.InstallDir, builder.fmt("install {s}/", .{options.source_dir}), builder.allocator, make),
2702 .options = options,
2743 .options = options.dupe(builder),
27032744 };
27042745 }
27052746
......@@ -2735,7 +2776,7 @@ pub const LogStep = struct {
27352776 return LogStep{
27362777 .builder = builder,
27372778 .step = Step.init(.Log, builder.fmt("log {s}", .{data}), builder.allocator, make),
2738 .data = data,
2779 .data = builder.dupe(data),
27392780 };
27402781 }
27412782
......@@ -2754,7 +2795,7 @@ pub const RemoveDirStep = struct {
27542795 return RemoveDirStep{
27552796 .builder = builder,
27562797 .step = Step.init(.RemoveDir, builder.fmt("RemoveDir {s}", .{dir_path}), builder.allocator, make),
2757 .dir_path = dir_path,
2798 .dir_path = builder.dupePath(dir_path),
27582799 };
27592800 }
27602801
......@@ -2798,7 +2839,7 @@ pub const Step = struct {
27982839 pub fn init(id: Id, name: []const u8, allocator: *Allocator, makeFn: fn (*Step) anyerror!void) Step {
27992840 return Step{
28002841 .id = id,
2801 .name = name,
2842 .name = allocator.dupe(u8, name) catch unreachable,
28022843 .makeFn = makeFn,
28032844 .dependencies = ArrayList(*Step).init(allocator),
28042845 .loop_flag = false,
......@@ -2905,11 +2946,28 @@ pub const InstallDir = union(enum) {
29052946 Header: void,
29062947 /// A path relative to the prefix
29072948 Custom: []const u8,
2949
2950 fn dupe(self: InstallDir, builder: *Builder) InstallDir {
2951 if (self == .Custom) {
2952 // Written with this temporary to avoid RLS problems
2953 const duped_path = builder.dupe(self.Custom);
2954 return .{ .Custom = duped_path };
2955 } else {
2956 return self;
2957 }
2958 }
29082959};
29092960
29102961pub const InstalledFile = struct {
29112962 dir: InstallDir,
29122963 path: []const u8,
2964
2965 pub fn dupe(self: InstalledFile, builder: *Builder) InstalledFile {
2966 return .{
2967 .dir = self.dir.dupe(builder),
2968 .path = builder.dupe(self.path),
2969 };
2970 }
29132971};
29142972
29152973test "Builder.dupePkg()" {
lib/std/build/check_file.zig+2-2
......@@ -27,8 +27,8 @@ pub const CheckFileStep = struct {
2727 self.* = CheckFileStep{
2828 .builder = builder,
2929 .step = Step.init(.CheckFile, "CheckFile", builder.allocator, make),
30 .source = source,
31 .expected_matches = expected_matches,
30 .source = source.dupe(builder),
31 .expected_matches = builder.dupeStrings(expected_matches),
3232 };
3333 self.source.addStepDependencies(&self.step);
3434 return self;
lib/std/build/run.zig+8-5
......@@ -76,7 +76,7 @@ pub const RunStep = struct {
7676 self.argv.append(Arg{
7777 .WriteFile = .{
7878 .step = write_file,
79 .file_name = file_name,
79 .file_name = self.builder.dupePath(file_name),
8080 },
8181 }) catch unreachable;
8282 self.step.dependOn(&write_file.step);
......@@ -119,7 +119,7 @@ pub const RunStep = struct {
119119 const new_path = self.builder.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path });
120120 env_map.set(key, new_path) catch unreachable;
121121 } else {
122 env_map.set(key, search_path) catch unreachable;
122 env_map.set(key, self.builder.dupePath(search_path)) catch unreachable;
123123 }
124124 }
125125
......@@ -134,15 +134,18 @@ pub const RunStep = struct {
134134
135135 pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8) void {
136136 const env_map = self.getEnvMap();
137 env_map.set(key, value) catch unreachable;
137 env_map.set(
138 self.builder.dupe(key),
139 self.builder.dupe(value),
140 ) catch unreachable;
138141 }
139142
140143 pub fn expectStdErrEqual(self: *RunStep, bytes: []const u8) void {
141 self.stderr_action = .{ .expect_exact = bytes };
144 self.stderr_action = .{ .expect_exact = self.builder.dupe(bytes) };
142145 }
143146
144147 pub fn expectStdOutEqual(self: *RunStep, bytes: []const u8) void {
145 self.stdout_action = .{ .expect_exact = bytes };
148 self.stdout_action = .{ .expect_exact = self.builder.dupe(bytes) };
146149 }
147150
148151 fn stdIoActionToBehavior(action: StdIoAction) std.ChildProcess.StdIo {
lib/std/build/translate_c.zig+2-2
......@@ -57,11 +57,11 @@ pub const TranslateCStep = struct {
5757 }
5858
5959 pub fn addIncludeDir(self: *TranslateCStep, include_dir: []const u8) void {
60 self.include_dirs.append(include_dir) catch unreachable;
60 self.include_dirs.append(self.builder.dupePath(include_dir)) catch unreachable;
6161 }
6262
6363 pub fn addCheckFile(self: *TranslateCStep, expected_matches: []const []const u8) *CheckFileStep {
64 return CheckFileStep.create(self.builder, .{ .translate_c = self }, expected_matches);
64 return CheckFileStep.create(self.builder, .{ .translate_c = self }, self.builder.dupeStrings(expected_matches));
6565 }
6666
6767 fn make(step: *Step) !void {
lib/std/build/write_file.zig+4-1
......@@ -32,7 +32,10 @@ pub const WriteFileStep = struct {
3232 }
3333
3434 pub fn add(self: *WriteFileStep, basename: []const u8, bytes: []const u8) void {
35 self.files.append(.{ .basename = basename, .bytes = bytes }) catch unreachable;
35 self.files.append(.{
36 .basename = self.builder.dupePath(basename),
37 .bytes = self.builder.dupe(bytes),
38 }) catch unreachable;
3639 }
3740
3841 /// Unless setOutputDir was called, this function must be called only in