authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-24 02:25:22-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-10-24 02:25:22-04:00
log345042ecbc7fb645fd17b69df4e57ffefa5be5a5
tree457ea0157f0f42dccf905593426154be8682812b
parentef62452363de75240b21299e9f80b4851433faaa
parent60cd11bd4b48e4dfdf11d1f25cb1ee842a49ee1d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3519 from ziglang/move-builtin-types

move types from builtin to std

39 files changed, 1385 insertions(+), 1117 deletions(-)

lib/std/build.zig+9-428
...@@ -971,433 +971,14 @@ test "builder.findProgram compiles" {...@@ -971,433 +971,14 @@ test "builder.findProgram compiles" {
971 _ = builder.findProgram([_][]const u8{}, [_][]const u8{}) catch null;971 _ = builder.findProgram([_][]const u8{}, [_][]const u8{}) catch null;
972}972}
973973
974pub const Version = struct {974/// Deprecated. Use `builtin.Version`.
975 major: u32,975pub const Version = builtin.Version;
976 minor: u32,
977 patch: u32,
978};
979
980pub const CrossTarget = struct {
981 arch: builtin.Arch,
982 os: builtin.Os,
983 abi: builtin.Abi,
984};
985
986pub const Target = union(enum) {
987 Native: void,
988 Cross: CrossTarget,
989
990 pub fn zigTriple(self: Target, allocator: *Allocator) ![]u8 {
991 return std.fmt.allocPrint(
992 allocator,
993 "{}{}-{}-{}",
994 @tagName(self.getArch()),
995 Target.archSubArchName(self.getArch()),
996 @tagName(self.getOs()),
997 @tagName(self.getAbi()),
998 );
999 }
1000
1001 pub fn allocDescription(self: Target, allocator: *Allocator) ![]u8 {
1002 // TODO is there anything else worthy of the description that is not
1003 // already captured in the triple?
1004 return self.zigTriple(allocator);
1005 }
1006
1007 pub fn zigTripleNoSubArch(self: Target, allocator: *Allocator) ![]u8 {
1008 return std.fmt.allocPrint(
1009 allocator,
1010 "{}-{}-{}",
1011 @tagName(self.getArch()),
1012 @tagName(self.getOs()),
1013 @tagName(self.getAbi()),
1014 );
1015 }
1016
1017 pub fn linuxTriple(self: Target, allocator: *Allocator) ![]u8 {
1018 return std.fmt.allocPrint(
1019 allocator,
1020 "{}-{}-{}",
1021 @tagName(self.getArch()),
1022 @tagName(self.getOs()),
1023 @tagName(self.getAbi()),
1024 );
1025 }
1026
1027 pub fn parse(text: []const u8) !Target {
1028 var it = mem.separate(text, "-");
1029 const arch_name = it.next() orelse return error.MissingArchitecture;
1030 const os_name = it.next() orelse return error.MissingOperatingSystem;
1031 const abi_name = it.next();
1032
1033 var cross = CrossTarget{
1034 .arch = try parseArchSub(arch_name),
1035 .os = try parseOs(os_name),
1036 .abi = undefined,
1037 };
1038 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
1039 return Target{ .Cross = cross };
1040 }
1041
1042 pub fn defaultAbi(arch: builtin.Arch, target_os: builtin.Os) builtin.Abi {
1043 switch (arch) {
1044 .wasm32, .wasm64 => return .musl,
1045 else => {},
1046 }
1047 switch (target_os) {
1048 .freestanding,
1049 .ananas,
1050 .cloudabi,
1051 .dragonfly,
1052 .lv2,
1053 .solaris,
1054 .haiku,
1055 .minix,
1056 .rtems,
1057 .nacl,
1058 .cnk,
1059 .aix,
1060 .cuda,
1061 .nvcl,
1062 .amdhsa,
1063 .ps4,
1064 .elfiamcu,
1065 .mesa3d,
1066 .contiki,
1067 .amdpal,
1068 .zen,
1069 .hermit,
1070 => return .eabi,
1071 .openbsd,
1072 .macosx,
1073 .freebsd,
1074 .ios,
1075 .tvos,
1076 .watchos,
1077 .fuchsia,
1078 .kfreebsd,
1079 .netbsd,
1080 .hurd,
1081 => return .gnu,
1082 .windows,
1083 .uefi,
1084 => return .msvc,
1085 .linux,
1086 .wasi,
1087 .emscripten,
1088 => return .musl,
1089 }
1090 }
1091
1092 pub const ParseArchSubError = error{
1093 UnknownArchitecture,
1094 UnknownSubArchitecture,
1095 };
1096
1097 pub fn parseArchSub(text: []const u8) ParseArchSubError!builtin.Arch {
1098 const info = @typeInfo(builtin.Arch);
1099 inline for (info.Union.fields) |field| {
1100 if (mem.eql(u8, text, field.name)) {
1101 if (field.field_type == void) {
1102 return (builtin.Arch)(@field(builtin.Arch, field.name));
1103 } else {
1104 const sub_info = @typeInfo(field.field_type);
1105 inline for (sub_info.Enum.fields) |sub_field| {
1106 const combined = field.name ++ sub_field.name;
1107 if (mem.eql(u8, text, combined)) {
1108 return @unionInit(builtin.Arch, field.name, @field(field.field_type, sub_field.name));
1109 }
1110 }
1111 return error.UnknownSubArchitecture;
1112 }
1113 }
1114 }
1115 return error.UnknownArchitecture;
1116 }
1117
1118 pub fn parseOs(text: []const u8) !builtin.Os {
1119 const info = @typeInfo(builtin.Os);
1120 inline for (info.Enum.fields) |field| {
1121 if (mem.eql(u8, text, field.name)) {
1122 return @field(builtin.Os, field.name);
1123 }
1124 }
1125 return error.UnknownOperatingSystem;
1126 }
1127
1128 pub fn parseAbi(text: []const u8) !builtin.Abi {
1129 const info = @typeInfo(builtin.Abi);
1130 inline for (info.Enum.fields) |field| {
1131 if (mem.eql(u8, text, field.name)) {
1132 return @field(builtin.Abi, field.name);
1133 }
1134 }
1135 return error.UnknownApplicationBinaryInterface;
1136 }
1137
1138 fn archSubArchName(arch: builtin.Arch) []const u8 {
1139 return switch (arch) {
1140 .arm => |sub| @tagName(sub),
1141 .armeb => |sub| @tagName(sub),
1142 .thumb => |sub| @tagName(sub),
1143 .thumbeb => |sub| @tagName(sub),
1144 .aarch64 => |sub| @tagName(sub),
1145 .aarch64_be => |sub| @tagName(sub),
1146 .kalimba => |sub| @tagName(sub),
1147 else => "",
1148 };
1149 }
1150
1151 pub fn subArchName(self: Target) []const u8 {
1152 switch (self) {
1153 .Native => return archSubArchName(builtin.arch),
1154 .Cross => |cross| return archSubArchName(cross.arch),
1155 }
1156 }
1157
1158 pub fn oFileExt(self: Target) []const u8 {
1159 return switch (self.getAbi()) {
1160 builtin.Abi.msvc => ".obj",
1161 else => ".o",
1162 };
1163 }
1164
1165 pub fn exeFileExt(self: Target) []const u8 {
1166 if (self.isWindows()) {
1167 return ".exe";
1168 } else if (self.isUefi()) {
1169 return ".efi";
1170 } else if (self.isWasm()) {
1171 return ".wasm";
1172 } else {
1173 return "";
1174 }
1175 }
1176976
1177 pub fn staticLibSuffix(self: Target) []const u8 {977/// Deprecated. Use `std.Target.Cross`.
1178 if (self.isWasm()) {978pub const CrossTarget = std.Target.Cross;
1179 return ".wasm";
1180 }
1181 switch (self.getAbi()) {
1182 .msvc => return ".lib",
1183 else => return ".a",
1184 }
1185 }
1186
1187 pub fn dynamicLibSuffix(self: Target) []const u8 {
1188 if (self.isDarwin()) {
1189 return ".dylib";
1190 }
1191 switch (self.getOs()) {
1192 .windows => return ".dll",
1193 else => return ".so",
1194 }
1195 }
1196
1197 pub fn libPrefix(self: Target) []const u8 {
1198 if (self.isWasm()) {
1199 return "";
1200 }
1201 switch (self.getAbi()) {
1202 .msvc => return "",
1203 else => return "lib",
1204 }
1205 }
1206979
1207 pub fn getOs(self: Target) builtin.Os {980/// Deprecated. Use `std.Target`.
1208 return switch (self) {981pub const Target = std.Target;
1209 .Native => builtin.os,
1210 .Cross => |t| t.os,
1211 };
1212 }
1213
1214 pub fn getArch(self: Target) builtin.Arch {
1215 switch (self) {
1216 .Native => return builtin.arch,
1217 .Cross => |t| return t.arch,
1218 }
1219 }
1220
1221 pub fn getAbi(self: Target) builtin.Abi {
1222 switch (self) {
1223 .Native => return builtin.abi,
1224 .Cross => |t| return t.abi,
1225 }
1226 }
1227
1228 pub fn isMinGW(self: Target) bool {
1229 return self.isWindows() and self.isGnu();
1230 }
1231
1232 pub fn isGnu(self: Target) bool {
1233 return switch (self.getAbi()) {
1234 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
1235 else => false,
1236 };
1237 }
1238
1239 pub fn isDarwin(self: Target) bool {
1240 return switch (self.getOs()) {
1241 .ios, .macosx, .watchos, .tvos => true,
1242 else => false,
1243 };
1244 }
1245
1246 pub fn isWindows(self: Target) bool {
1247 return switch (self.getOs()) {
1248 .windows => true,
1249 else => false,
1250 };
1251 }
1252
1253 pub fn isLinux(self: Target) bool {
1254 return switch (self.getOs()) {
1255 .linux => true,
1256 else => false,
1257 };
1258 }
1259
1260 pub fn isUefi(self: Target) bool {
1261 return switch (self.getOs()) {
1262 .uefi => true,
1263 else => false,
1264 };
1265 }
1266
1267 pub fn isWasm(self: Target) bool {
1268 return switch (self.getArch()) {
1269 .wasm32, .wasm64 => true,
1270 else => false,
1271 };
1272 }
1273
1274 pub fn isFreeBSD(self: Target) bool {
1275 return switch (self.getOs()) {
1276 .freebsd => true,
1277 else => false,
1278 };
1279 }
1280
1281 pub fn isNetBSD(self: Target) bool {
1282 return switch (self.getOs()) {
1283 .netbsd => true,
1284 else => false,
1285 };
1286 }
1287
1288 pub fn wantSharedLibSymLinks(self: Target) bool {
1289 return !self.isWindows();
1290 }
1291
1292 pub fn osRequiresLibC(self: Target) bool {
1293 return self.isDarwin() or self.isFreeBSD() or self.isNetBSD();
1294 }
1295
1296 pub fn getArchPtrBitWidth(self: Target) u32 {
1297 switch (self.getArch()) {
1298 .avr,
1299 .msp430,
1300 => return 16,
1301
1302 .arc,
1303 .arm,
1304 .armeb,
1305 .hexagon,
1306 .le32,
1307 .mips,
1308 .mipsel,
1309 .powerpc,
1310 .r600,
1311 .riscv32,
1312 .sparc,
1313 .sparcel,
1314 .tce,
1315 .tcele,
1316 .thumb,
1317 .thumbeb,
1318 .i386,
1319 .xcore,
1320 .nvptx,
1321 .amdil,
1322 .hsail,
1323 .spir,
1324 .kalimba,
1325 .shave,
1326 .lanai,
1327 .wasm32,
1328 .renderscript32,
1329 .aarch64_32,
1330 => return 32,
1331
1332 .aarch64,
1333 .aarch64_be,
1334 .mips64,
1335 .mips64el,
1336 .powerpc64,
1337 .powerpc64le,
1338 .riscv64,
1339 .x86_64,
1340 .nvptx64,
1341 .le64,
1342 .amdil64,
1343 .hsail64,
1344 .spir64,
1345 .wasm64,
1346 .renderscript64,
1347 .amdgcn,
1348 .bpfel,
1349 .bpfeb,
1350 .sparcv9,
1351 .s390x,
1352 => return 64,
1353 }
1354 }
1355
1356 pub const Executor = union(enum) {
1357 native,
1358 qemu: []const u8,
1359 wine: []const u8,
1360 unavailable,
1361 };
1362
1363 pub fn getExternalExecutor(self: Target) Executor {
1364 if (@TagType(Target)(self) == .Native) return .native;
1365
1366 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
1367 if (self.getOs() == builtin.os) {
1368 return switch (self.getArch()) {
1369 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
1370 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
1371 .arm => Executor{ .qemu = "qemu-arm" },
1372 .armeb => Executor{ .qemu = "qemu-armeb" },
1373 .i386 => Executor{ .qemu = "qemu-i386" },
1374 .mips => Executor{ .qemu = "qemu-mips" },
1375 .mipsel => Executor{ .qemu = "qemu-mipsel" },
1376 .mips64 => Executor{ .qemu = "qemu-mips64" },
1377 .mips64el => Executor{ .qemu = "qemu-mips64el" },
1378 .powerpc => Executor{ .qemu = "qemu-ppc" },
1379 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
1380 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
1381 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
1382 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
1383 .s390x => Executor{ .qemu = "qemu-s390x" },
1384 .sparc => Executor{ .qemu = "qemu-sparc" },
1385 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
1386 else => return .unavailable,
1387 };
1388 }
1389
1390 if (self.isWindows()) {
1391 switch (self.getArchPtrBitWidth()) {
1392 32 => return Executor{ .wine = "wine" },
1393 64 => return Executor{ .wine = "wine64" },
1394 else => return .unavailable,
1395 }
1396 }
1397
1398 return .unavailable;
1399 }
1400};
1401982
1402const Pkg = struct {983const Pkg = struct {
1403 name: []const u8,984 name: []const u8,
...@@ -2168,8 +1749,8 @@ pub const LibExeObjStep = struct {...@@ -2168,8 +1749,8 @@ pub const LibExeObjStep = struct {
2168 }1749 }
21691750
2170 switch (self.target) {1751 switch (self.target) {
2171 Target.Native => {},1752 .Native => {},
2172 Target.Cross => {1753 .Cross => {
2173 try zig_args.append("-target");1754 try zig_args.append("-target");
2174 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);1755 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
2175 },1756 },
...@@ -2419,7 +2000,7 @@ pub const RunStep = struct {...@@ -2419,7 +2000,7 @@ pub const RunStep = struct {
2419 }2000 }
24202001
2421 pub fn addPathDir(self: *RunStep, search_path: []const u8) void {2002 pub fn addPathDir(self: *RunStep, search_path: []const u8) void {
2422 const PATH = if (std.os.windows.is_the_target) "Path" else "PATH";2003 const PATH = if (builtin.os == .windows) "Path" else "PATH";
2423 const env_map = self.getEnvMap();2004 const env_map = self.getEnvMap();
2424 const prev_path = env_map.get(PATH) orelse {2005 const prev_path = env_map.get(PATH) orelse {
2425 env_map.set(PATH, search_path) catch unreachable;2006 env_map.set(PATH, search_path) catch unreachable;
lib/std/builtin.zig created+413
...@@ -0,0 +1,413 @@
1pub usingnamespace @import("builtin");
2
3/// Deprecated: use `std.Target.Os`.
4pub const Os = std.Target.Os;
5
6/// Deprecated: use `std.Target.Arch`.
7pub const Arch = std.Target.Arch;
8
9/// Deprecated: use `std.Target.Abi`.
10pub const Abi = std.Target.Abi;
11
12/// Deprecated: use `std.Target.ObjectFormat`.
13pub const ObjectFormat = std.Target.ObjectFormat;
14
15/// Deprecated: use `std.Target.SubSystem`.
16pub const SubSystem = std.Target.SubSystem;
17
18/// `explicit_subsystem` is missing when the subsystem is automatically detected,
19/// so Zig standard library has the subsystem detection logic here. This should generally be
20/// used rather than `explicit_subsystem`.
21/// On non-Windows targets, this is `null`.
22pub const subsystem: ?SubSystem = blk: {
23 if (@hasDecl(@This(), "explicit_subsystem")) break :blk explicit_subsystem;
24 switch (os) {
25 .windows => {
26 if (is_test) {
27 break :blk SubSystem.Console;
28 }
29 if (@hasDecl(root, "WinMain") or
30 @hasDecl(root, "wWinMain") or
31 @hasDecl(root, "WinMainCRTStartup") or
32 @hasDecl(root, "wWinMainCRTStartup"))
33 {
34 break :blk SubSystem.Windows;
35 } else {
36 break :blk SubSystem.Console;
37 }
38 },
39 else => break :blk null,
40 }
41};
42
43/// This data structure is used by the Zig language code generation and
44/// therefore must be kept in sync with the compiler implementation.
45pub const StackTrace = struct {
46 index: usize,
47 instruction_addresses: []usize,
48};
49
50/// This data structure is used by the Zig language code generation and
51/// therefore must be kept in sync with the compiler implementation.
52pub const GlobalLinkage = enum {
53 Internal,
54 Strong,
55 Weak,
56 LinkOnce,
57};
58
59/// This data structure is used by the Zig language code generation and
60/// therefore must be kept in sync with the compiler implementation.
61pub const AtomicOrder = enum {
62 Unordered,
63 Monotonic,
64 Acquire,
65 Release,
66 AcqRel,
67 SeqCst,
68};
69
70/// This data structure is used by the Zig language code generation and
71/// therefore must be kept in sync with the compiler implementation.
72pub const AtomicRmwOp = enum {
73 Xchg,
74 Add,
75 Sub,
76 And,
77 Nand,
78 Or,
79 Xor,
80 Max,
81 Min,
82};
83
84/// This data structure is used by the Zig language code generation and
85/// therefore must be kept in sync with the compiler implementation.
86pub const Mode = enum {
87 Debug,
88 ReleaseSafe,
89 ReleaseFast,
90 ReleaseSmall,
91};
92
93/// This data structure is used by the Zig language code generation and
94/// therefore must be kept in sync with the compiler implementation.
95pub const TypeId = enum {
96 Type,
97 Void,
98 Bool,
99 NoReturn,
100 Int,
101 Float,
102 Pointer,
103 Array,
104 Struct,
105 ComptimeFloat,
106 ComptimeInt,
107 Undefined,
108 Null,
109 Optional,
110 ErrorUnion,
111 ErrorSet,
112 Enum,
113 Union,
114 Fn,
115 BoundFn,
116 ArgTuple,
117 Opaque,
118 Frame,
119 AnyFrame,
120 Vector,
121 EnumLiteral,
122};
123
124/// This data structure is used by the Zig language code generation and
125/// therefore must be kept in sync with the compiler implementation.
126pub const TypeInfo = union(TypeId) {
127 Type: void,
128 Void: void,
129 Bool: void,
130 NoReturn: void,
131 Int: Int,
132 Float: Float,
133 Pointer: Pointer,
134 Array: Array,
135 Struct: Struct,
136 ComptimeFloat: void,
137 ComptimeInt: void,
138 Undefined: void,
139 Null: void,
140 Optional: Optional,
141 ErrorUnion: ErrorUnion,
142 ErrorSet: ErrorSet,
143 Enum: Enum,
144 Union: Union,
145 Fn: Fn,
146 BoundFn: Fn,
147 ArgTuple: void,
148 Opaque: void,
149 Frame: void,
150 AnyFrame: AnyFrame,
151 Vector: Vector,
152 EnumLiteral: void,
153
154 /// This data structure is used by the Zig language code generation and
155 /// therefore must be kept in sync with the compiler implementation.
156 pub const Int = struct {
157 is_signed: bool,
158 bits: comptime_int,
159 };
160
161 /// This data structure is used by the Zig language code generation and
162 /// therefore must be kept in sync with the compiler implementation.
163 pub const Float = struct {
164 bits: comptime_int,
165 };
166
167 /// This data structure is used by the Zig language code generation and
168 /// therefore must be kept in sync with the compiler implementation.
169 pub const Pointer = struct {
170 size: Size,
171 is_const: bool,
172 is_volatile: bool,
173 alignment: comptime_int,
174 child: type,
175 is_allowzero: bool,
176
177 /// This data structure is used by the Zig language code generation and
178 /// therefore must be kept in sync with the compiler implementation.
179 pub const Size = enum {
180 One,
181 Many,
182 Slice,
183 C,
184 };
185 };
186
187 /// This data structure is used by the Zig language code generation and
188 /// therefore must be kept in sync with the compiler implementation.
189 pub const Array = struct {
190 len: comptime_int,
191 child: type,
192 };
193
194 /// This data structure is used by the Zig language code generation and
195 /// therefore must be kept in sync with the compiler implementation.
196 pub const ContainerLayout = enum {
197 Auto,
198 Extern,
199 Packed,
200 };
201
202 /// This data structure is used by the Zig language code generation and
203 /// therefore must be kept in sync with the compiler implementation.
204 pub const StructField = struct {
205 name: []const u8,
206 offset: ?comptime_int,
207 field_type: type,
208 };
209
210 /// This data structure is used by the Zig language code generation and
211 /// therefore must be kept in sync with the compiler implementation.
212 pub const Struct = struct {
213 layout: ContainerLayout,
214 fields: []StructField,
215 decls: []Declaration,
216 };
217
218 /// This data structure is used by the Zig language code generation and
219 /// therefore must be kept in sync with the compiler implementation.
220 pub const Optional = struct {
221 child: type,
222 };
223
224 /// This data structure is used by the Zig language code generation and
225 /// therefore must be kept in sync with the compiler implementation.
226 pub const ErrorUnion = struct {
227 error_set: type,
228 payload: type,
229 };
230
231 /// This data structure is used by the Zig language code generation and
232 /// therefore must be kept in sync with the compiler implementation.
233 pub const Error = struct {
234 name: []const u8,
235 value: comptime_int,
236 };
237
238 /// This data structure is used by the Zig language code generation and
239 /// therefore must be kept in sync with the compiler implementation.
240 pub const ErrorSet = ?[]Error;
241
242 /// This data structure is used by the Zig language code generation and
243 /// therefore must be kept in sync with the compiler implementation.
244 pub const EnumField = struct {
245 name: []const u8,
246 value: comptime_int,
247 };
248
249 /// This data structure is used by the Zig language code generation and
250 /// therefore must be kept in sync with the compiler implementation.
251 pub const Enum = struct {
252 layout: ContainerLayout,
253 tag_type: type,
254 fields: []EnumField,
255 decls: []Declaration,
256 };
257
258 /// This data structure is used by the Zig language code generation and
259 /// therefore must be kept in sync with the compiler implementation.
260 pub const UnionField = struct {
261 name: []const u8,
262 enum_field: ?EnumField,
263 field_type: type,
264 };
265
266 /// This data structure is used by the Zig language code generation and
267 /// therefore must be kept in sync with the compiler implementation.
268 pub const Union = struct {
269 layout: ContainerLayout,
270 tag_type: ?type,
271 fields: []UnionField,
272 decls: []Declaration,
273 };
274
275 /// This data structure is used by the Zig language code generation and
276 /// therefore must be kept in sync with the compiler implementation.
277 pub const CallingConvention = enum {
278 Unspecified,
279 C,
280 Cold,
281 Naked,
282 Stdcall,
283 Async,
284 };
285
286 /// This data structure is used by the Zig language code generation and
287 /// therefore must be kept in sync with the compiler implementation.
288 pub const FnArg = struct {
289 is_generic: bool,
290 is_noalias: bool,
291 arg_type: ?type,
292 };
293
294 /// This data structure is used by the Zig language code generation and
295 /// therefore must be kept in sync with the compiler implementation.
296 pub const Fn = struct {
297 calling_convention: CallingConvention,
298 is_generic: bool,
299 is_var_args: bool,
300 return_type: ?type,
301 args: []FnArg,
302 };
303
304 /// This data structure is used by the Zig language code generation and
305 /// therefore must be kept in sync with the compiler implementation.
306 pub const AnyFrame = struct {
307 child: ?type,
308 };
309
310 /// This data structure is used by the Zig language code generation and
311 /// therefore must be kept in sync with the compiler implementation.
312 pub const Vector = struct {
313 len: comptime_int,
314 child: type,
315 };
316
317 /// This data structure is used by the Zig language code generation and
318 /// therefore must be kept in sync with the compiler implementation.
319 pub const Declaration = struct {
320 name: []const u8,
321 is_pub: bool,
322 data: Data,
323
324 /// This data structure is used by the Zig language code generation and
325 /// therefore must be kept in sync with the compiler implementation.
326 pub const Data = union(enum) {
327 Type: type,
328 Var: type,
329 Fn: FnDecl,
330
331 /// This data structure is used by the Zig language code generation and
332 /// therefore must be kept in sync with the compiler implementation.
333 pub const FnDecl = struct {
334 fn_type: type,
335 inline_type: Inline,
336 calling_convention: CallingConvention,
337 is_var_args: bool,
338 is_extern: bool,
339 is_export: bool,
340 lib_name: ?[]const u8,
341 return_type: type,
342 arg_names: [][]const u8,
343
344 /// This data structure is used by the Zig language code generation and
345 /// therefore must be kept in sync with the compiler implementation.
346 pub const Inline = enum {
347 Auto,
348 Always,
349 Never,
350 };
351 };
352 };
353 };
354};
355
356/// This data structure is used by the Zig language code generation and
357/// therefore must be kept in sync with the compiler implementation.
358pub const FloatMode = enum {
359 Strict,
360 Optimized,
361};
362
363/// This data structure is used by the Zig language code generation and
364/// therefore must be kept in sync with the compiler implementation.
365pub const Endian = enum {
366 Big,
367 Little,
368};
369
370/// This data structure is used by the Zig language code generation and
371/// therefore must be kept in sync with the compiler implementation.
372pub const Version = struct {
373 major: u32,
374 minor: u32,
375 patch: u32,
376};
377
378/// This function type is used by the Zig language code generation and
379/// therefore must be kept in sync with the compiler implementation.
380pub const PanicFn = fn ([]const u8, ?*StackTrace) noreturn;
381
382/// This function is used by the Zig language code generation and
383/// therefore must be kept in sync with the compiler implementation.
384pub const panic: PanicFn = if (@hasDecl(root, "panic")) root.panic else default_panic;
385
386/// This function is used by the Zig language code generation and
387/// therefore must be kept in sync with the compiler implementation.
388pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn {
389 @setCold(true);
390 switch (os) {
391 .freestanding => {
392 while (true) {
393 @breakpoint();
394 }
395 },
396 .wasi => {
397 std.debug.warn("{}", msg);
398 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
399 unreachable;
400 },
401 .uefi => {
402 // TODO look into using the debug info and logging helpful messages
403 std.os.abort();
404 },
405 else => {
406 const first_trace_addr = @returnAddress();
407 std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
408 },
409 }
410}
411
412const std = @import("std.zig");
413const root = @import("root");
lib/std/c/darwin.zig+1-1
...@@ -36,7 +36,7 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;...@@ -36,7 +36,7 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;
36/// export a weak symbol here, to be overridden by the real one.36/// export a weak symbol here, to be overridden by the real one.
37pub extern "c" var _mh_execute_header: mach_hdr = undefined;37pub extern "c" var _mh_execute_header: mach_hdr = undefined;
38comptime {38comptime {
39 if (std.os.darwin.is_the_target) {39 if (std.Target.current.isDarwin()) {
40 @export("_mh_execute_header", _mh_execute_header, .Weak);40 @export("_mh_execute_header", _mh_execute_header, .Weak);
41 }41 }
42}42}
lib/std/child_process.zig+12-12
...@@ -17,9 +17,9 @@ const TailQueue = std.TailQueue;...@@ -17,9 +17,9 @@ const TailQueue = std.TailQueue;
17const maxInt = std.math.maxInt;17const maxInt = std.math.maxInt;
1818
19pub const ChildProcess = struct {19pub const ChildProcess = struct {
20 pid: if (os.windows.is_the_target) void else i32,20 pid: if (builtin.os == .windows) void else i32,
21 handle: if (os.windows.is_the_target) windows.HANDLE else void,21 handle: if (builtin.os == .windows) windows.HANDLE else void,
22 thread_handle: if (os.windows.is_the_target) windows.HANDLE else void,22 thread_handle: if (builtin.os == .windows) windows.HANDLE else void,
2323
24 allocator: *mem.Allocator,24 allocator: *mem.Allocator,
2525
...@@ -39,16 +39,16 @@ pub const ChildProcess = struct {...@@ -39,16 +39,16 @@ pub const ChildProcess = struct {
39 stderr_behavior: StdIo,39 stderr_behavior: StdIo,
4040
41 /// Set to change the user id when spawning the child process.41 /// Set to change the user id when spawning the child process.
42 uid: if (os.windows.is_the_target) void else ?u32,42 uid: if (builtin.os == .windows) void else ?u32,
4343
44 /// Set to change the group id when spawning the child process.44 /// Set to change the group id when spawning the child process.
45 gid: if (os.windows.is_the_target) void else ?u32,45 gid: if (builtin.os == .windows) void else ?u32,
4646
47 /// Set to change the current working directory when spawning the child process.47 /// Set to change the current working directory when spawning the child process.
48 cwd: ?[]const u8,48 cwd: ?[]const u8,
4949
50 err_pipe: if (os.windows.is_the_target) void else [2]os.fd_t,50 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,
51 llnode: if (os.windows.is_the_target) void else TailQueue(*ChildProcess).Node,51 llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,
5252
53 pub const SpawnError = error{OutOfMemory} || os.ExecveError || os.SetIdError ||53 pub const SpawnError = error{OutOfMemory} || os.ExecveError || os.SetIdError ||
54 os.ChangeCurDirError || windows.CreateProcessError;54 os.ChangeCurDirError || windows.CreateProcessError;
...@@ -82,8 +82,8 @@ pub const ChildProcess = struct {...@@ -82,8 +82,8 @@ pub const ChildProcess = struct {
82 .term = null,82 .term = null,
83 .env_map = null,83 .env_map = null,
84 .cwd = null,84 .cwd = null,
85 .uid = if (os.windows.is_the_target) {} else null,85 .uid = if (builtin.os == .windows) {} else null,
86 .gid = if (os.windows.is_the_target) {} else null,86 .gid = if (builtin.os == .windows) {} else null,
87 .stdin = null,87 .stdin = null,
88 .stdout = null,88 .stdout = null,
89 .stderr = null,89 .stderr = null,
...@@ -103,7 +103,7 @@ pub const ChildProcess = struct {...@@ -103,7 +103,7 @@ pub const ChildProcess = struct {
103103
104 /// On success must call `kill` or `wait`.104 /// On success must call `kill` or `wait`.
105 pub fn spawn(self: *ChildProcess) !void {105 pub fn spawn(self: *ChildProcess) !void {
106 if (os.windows.is_the_target) {106 if (builtin.os == .windows) {
107 return self.spawnWindows();107 return self.spawnWindows();
108 } else {108 } else {
109 return self.spawnPosix();109 return self.spawnPosix();
...@@ -117,7 +117,7 @@ pub const ChildProcess = struct {...@@ -117,7 +117,7 @@ pub const ChildProcess = struct {
117117
118 /// Forcibly terminates child process and then cleans up all resources.118 /// Forcibly terminates child process and then cleans up all resources.
119 pub fn kill(self: *ChildProcess) !Term {119 pub fn kill(self: *ChildProcess) !Term {
120 if (os.windows.is_the_target) {120 if (builtin.os == .windows) {
121 return self.killWindows(1);121 return self.killWindows(1);
122 } else {122 } else {
123 return self.killPosix();123 return self.killPosix();
...@@ -147,7 +147,7 @@ pub const ChildProcess = struct {...@@ -147,7 +147,7 @@ pub const ChildProcess = struct {
147147
148 /// Blocks until child process terminates and then cleans up all resources.148 /// Blocks until child process terminates and then cleans up all resources.
149 pub fn wait(self: *ChildProcess) !Term {149 pub fn wait(self: *ChildProcess) !Term {
150 if (os.windows.is_the_target) {150 if (builtin.os == .windows) {
151 return self.waitWindows();151 return self.waitWindows();
152 } else {152 } else {
153 return self.waitPosix();153 return self.waitPosix();
lib/std/debug.zig+8-8
...@@ -133,7 +133,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {...@@ -133,7 +133,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
133/// chopping off the irrelevant frames and shifting so that the returned addresses pointer133/// chopping off the irrelevant frames and shifting so that the returned addresses pointer
134/// equals the passed in addresses pointer.134/// equals the passed in addresses pointer.
135pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace) void {135pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace) void {
136 if (windows.is_the_target) {136 if (builtin.os == .windows) {
137 const addrs = stack_trace.instruction_addresses;137 const addrs = stack_trace.instruction_addresses;
138 const u32_addrs_len = @intCast(u32, addrs.len);138 const u32_addrs_len = @intCast(u32, addrs.len);
139 const first_addr = first_address orelse {139 const first_addr = first_address orelse {
...@@ -310,7 +310,7 @@ pub const StackIterator = struct {...@@ -310,7 +310,7 @@ pub const StackIterator = struct {
310};310};
311311
312pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {312pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
313 if (windows.is_the_target) {313 if (builtin.os == .windows) {
314 return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr);314 return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr);
315 }315 }
316 var it = StackIterator.init(start_addr);316 var it = StackIterator.init(start_addr);
...@@ -342,10 +342,10 @@ pub fn writeCurrentStackTraceWindows(...@@ -342,10 +342,10 @@ pub fn writeCurrentStackTraceWindows(
342/// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented,342/// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented,
343/// make this `noasync fn` and remove the individual noasync calls.343/// make this `noasync fn` and remove the individual noasync calls.
344pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {344pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
345 if (windows.is_the_target) {345 if (builtin.os == .windows) {
346 return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_color);346 return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_color);
347 }347 }
348 if (os.darwin.is_the_target) {348 if (comptime std.Target.current.isDarwin()) {
349 return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color);349 return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color);
350 }350 }
351 return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_color);351 return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_color);
...@@ -832,10 +832,10 @@ pub const OpenSelfDebugInfoError = error{...@@ -832,10 +832,10 @@ pub const OpenSelfDebugInfoError = error{
832pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {832pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
833 if (builtin.strip_debug_info)833 if (builtin.strip_debug_info)
834 return error.MissingDebugInfo;834 return error.MissingDebugInfo;
835 if (windows.is_the_target) {835 if (builtin.os == .windows) {
836 return noasync openSelfDebugInfoWindows(allocator);836 return noasync openSelfDebugInfoWindows(allocator);
837 }837 }
838 if (os.darwin.is_the_target) {838 if (comptime std.Target.current.isDarwin()) {
839 return noasync openSelfDebugInfoMacOs(allocator);839 return noasync openSelfDebugInfoMacOs(allocator);
840 }840 }
841 return noasync openSelfDebugInfoPosix(allocator);841 return noasync openSelfDebugInfoPosix(allocator);
...@@ -2364,7 +2364,7 @@ pub fn attachSegfaultHandler() void {...@@ -2364,7 +2364,7 @@ pub fn attachSegfaultHandler() void {
2364 if (!have_segfault_handling_support) {2364 if (!have_segfault_handling_support) {
2365 @compileError("segfault handler not supported for this target");2365 @compileError("segfault handler not supported for this target");
2366 }2366 }
2367 if (windows.is_the_target) {2367 if (builtin.os == .windows) {
2368 windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);2368 windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
2369 return;2369 return;
2370 }2370 }
...@@ -2378,7 +2378,7 @@ pub fn attachSegfaultHandler() void {...@@ -2378,7 +2378,7 @@ pub fn attachSegfaultHandler() void {
2378}2378}
23792379
2380fn resetSegfaultHandler() void {2380fn resetSegfaultHandler() void {
2381 if (windows.is_the_target) {2381 if (builtin.os == .windows) {
2382 if (windows_segfault_handle) |handle| {2382 if (windows_segfault_handle) |handle| {
2383 assert(windows.kernel32.RemoveVectoredExceptionHandler(handle) != 0);2383 assert(windows.kernel32.RemoveVectoredExceptionHandler(handle) != 0);
2384 windows_segfault_handle = null;2384 windows_segfault_handle = null;
lib/std/event/channel.zig+1-1
...@@ -307,7 +307,7 @@ test "std.event.Channel" {...@@ -307,7 +307,7 @@ test "std.event.Channel" {
307 // https://github.com/ziglang/zig/issues/1908307 // https://github.com/ziglang/zig/issues/1908
308 if (builtin.single_threaded) return error.SkipZigTest;308 if (builtin.single_threaded) return error.SkipZigTest;
309 // https://github.com/ziglang/zig/issues/3251309 // https://github.com/ziglang/zig/issues/3251
310 if (std.os.freebsd.is_the_target) return error.SkipZigTest;310 if (builtin.os == .freebsd) return error.SkipZigTest;
311311
312 var loop: Loop = undefined;312 var loop: Loop = undefined;
313 // TODO make a multi threaded test313 // TODO make a multi threaded test
lib/std/event/fs.zig+1-1
...@@ -909,7 +909,7 @@ fn hashString(s: []const u16) u32 {...@@ -909,7 +909,7 @@ fn hashString(s: []const u16) u32 {
909// var close_op_consumed = false;909// var close_op_consumed = false;
910// defer if (!close_op_consumed) close_op.finish();910// defer if (!close_op_consumed) close_op.finish();
911//911//
912// const flags = if (os.darwin.is_the_target) os.O_SYMLINK | os.O_EVTONLY else 0;912// const flags = if (comptime std.Target.current.isDarwin()) os.O_SYMLINK | os.O_EVTONLY else 0;
913// const mode = 0;913// const mode = 0;
914// const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);914// const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);
915// close_op.setHandle(fd);915// close_op.setHandle(fd);
lib/std/event/future.zig+1-1
...@@ -86,7 +86,7 @@ test "std.event.Future" {...@@ -86,7 +86,7 @@ test "std.event.Future" {
86 // https://github.com/ziglang/zig/issues/190886 // https://github.com/ziglang/zig/issues/1908
87 if (builtin.single_threaded) return error.SkipZigTest;87 if (builtin.single_threaded) return error.SkipZigTest;
88 // https://github.com/ziglang/zig/issues/325188 // https://github.com/ziglang/zig/issues/3251
89 if (std.os.freebsd.is_the_target) return error.SkipZigTest;89 if (builtin.os == .freebsd) return error.SkipZigTest;
9090
91 const allocator = std.heap.direct_allocator;91 const allocator = std.heap.direct_allocator;
9292
lib/std/event/lock.zig+1-1
...@@ -119,7 +119,7 @@ test "std.event.Lock" {...@@ -119,7 +119,7 @@ test "std.event.Lock" {
119 // TODO https://github.com/ziglang/zig/issues/1908119 // TODO https://github.com/ziglang/zig/issues/1908
120 if (builtin.single_threaded) return error.SkipZigTest;120 if (builtin.single_threaded) return error.SkipZigTest;
121 // TODO https://github.com/ziglang/zig/issues/3251121 // TODO https://github.com/ziglang/zig/issues/3251
122 if (std.os.freebsd.is_the_target) return error.SkipZigTest;122 if (builtin.os == .freebsd) return error.SkipZigTest;
123123
124 const allocator = std.heap.direct_allocator;124 const allocator = std.heap.direct_allocator;
125125
lib/std/fs.zig+9-9
...@@ -255,7 +255,7 @@ pub const AtomicFile = struct {...@@ -255,7 +255,7 @@ pub const AtomicFile = struct {
255 assert(!self.finished);255 assert(!self.finished);
256 self.file.close();256 self.file.close();
257 self.finished = true;257 self.finished = true;
258 if (os.windows.is_the_target) {258 if (builtin.os == .windows) {
259 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path);259 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path);
260 const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf);260 const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf);
261 return os.renameW(&tmp_path_w, &dest_path_w);261 return os.renameW(&tmp_path_w, &dest_path_w);
...@@ -659,7 +659,7 @@ pub const Dir = struct {...@@ -659,7 +659,7 @@ pub const Dir = struct {
659 /// Closing the returned `Dir` is checked illegal behavior.659 /// Closing the returned `Dir` is checked illegal behavior.
660 /// On POSIX targets, this function is comptime-callable.660 /// On POSIX targets, this function is comptime-callable.
661 pub fn cwd() Dir {661 pub fn cwd() Dir {
662 if (os.windows.is_the_target) {662 if (builtin.os == .windows) {
663 return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle };663 return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle };
664 } else {664 } else {
665 return Dir{ .fd = os.AT_FDCWD };665 return Dir{ .fd = os.AT_FDCWD };
...@@ -711,7 +711,7 @@ pub const Dir = struct {...@@ -711,7 +711,7 @@ pub const Dir = struct {
711711
712 /// Call `close` on the result when done.712 /// Call `close` on the result when done.
713 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {713 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {
714 if (os.windows.is_the_target) {714 if (builtin.os == .windows) {
715 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);715 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
716 return self.openDirW(&sub_path_w);716 return self.openDirW(&sub_path_w);
717 }717 }
...@@ -722,7 +722,7 @@ pub const Dir = struct {...@@ -722,7 +722,7 @@ pub const Dir = struct {
722722
723 /// Same as `openDir` except the parameter is null-terminated.723 /// Same as `openDir` except the parameter is null-terminated.
724 pub fn openDirC(self: Dir, sub_path_c: [*]const u8) OpenError!Dir {724 pub fn openDirC(self: Dir, sub_path_c: [*]const u8) OpenError!Dir {
725 if (os.windows.is_the_target) {725 if (builtin.os == .windows) {
726 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);726 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
727 return self.openDirW(&sub_path_w);727 return self.openDirW(&sub_path_w);
728 }728 }
...@@ -829,7 +829,7 @@ pub const Dir = struct {...@@ -829,7 +829,7 @@ pub const Dir = struct {
829 /// Returns `error.DirNotEmpty` if the directory is not empty.829 /// Returns `error.DirNotEmpty` if the directory is not empty.
830 /// To delete a directory recursively, see `deleteTree`.830 /// To delete a directory recursively, see `deleteTree`.
831 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {831 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {
832 if (os.windows.is_the_target) {832 if (builtin.os == .windows) {
833 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);833 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
834 return self.deleteDirW(&sub_path_w);834 return self.deleteDirW(&sub_path_w);
835 }835 }
...@@ -1146,10 +1146,10 @@ pub fn readLinkC(pathname_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {...@@ -1146,10 +1146,10 @@ pub fn readLinkC(pathname_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
1146pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError;1146pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError;
11471147
1148pub fn openSelfExe() OpenSelfExeError!File {1148pub fn openSelfExe() OpenSelfExeError!File {
1149 if (os.linux.is_the_target) {1149 if (builtin.os == .linux) {
1150 return File.openReadC(c"/proc/self/exe");1150 return File.openReadC(c"/proc/self/exe");
1151 }1151 }
1152 if (os.windows.is_the_target) {1152 if (builtin.os == .windows) {
1153 var buf: [os.windows.PATH_MAX_WIDE]u16 = undefined;1153 var buf: [os.windows.PATH_MAX_WIDE]u16 = undefined;
1154 const wide_slice = try selfExePathW(&buf);1154 const wide_slice = try selfExePathW(&buf);
1155 return File.openReadW(wide_slice.ptr);1155 return File.openReadW(wide_slice.ptr);
...@@ -1180,7 +1180,7 @@ pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;...@@ -1180,7 +1180,7 @@ pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;
1180/// been deleted, the file path looks something like `/a/b/c/exe (deleted)`.1180/// been deleted, the file path looks something like `/a/b/c/exe (deleted)`.
1181/// TODO make the return type of this a null terminated pointer1181/// TODO make the return type of this a null terminated pointer
1182pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {1182pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
1183 if (os.darwin.is_the_target) {1183 if (comptime std.Target.current.isDarwin()) {
1184 var u32_len: u32 = out_buffer.len;1184 var u32_len: u32 = out_buffer.len;
1185 const rc = std.c._NSGetExecutablePath(out_buffer, &u32_len);1185 const rc = std.c._NSGetExecutablePath(out_buffer, &u32_len);
1186 if (rc != 0) return error.NameTooLong;1186 if (rc != 0) return error.NameTooLong;
...@@ -1228,7 +1228,7 @@ pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 {...@@ -1228,7 +1228,7 @@ pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 {
1228/// Get the directory path that contains the current executable.1228/// Get the directory path that contains the current executable.
1229/// Returned value is a slice of out_buffer.1229/// Returned value is a slice of out_buffer.
1230pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const u8 {1230pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const u8 {
1231 if (os.linux.is_the_target) {1231 if (builtin.os == .linux) {
1232 // If the currently executing binary has been deleted,1232 // If the currently executing binary has been deleted,
1233 // the file path looks something like `/a/b/c/exe (deleted)`1233 // the file path looks something like `/a/b/c/exe (deleted)`
1234 // This path cannot be opened, but it's valid for determining the directory1234 // This path cannot be opened, but it's valid for determining the directory
lib/std/fs/file.zig+11-11
...@@ -27,7 +27,7 @@ pub const File = struct {...@@ -27,7 +27,7 @@ pub const File = struct {
2727
28 /// Call close to clean up.28 /// Call close to clean up.
29 pub fn openRead(path: []const u8) OpenError!File {29 pub fn openRead(path: []const u8) OpenError!File {
30 if (windows.is_the_target) {30 if (builtin.os == .windows) {
31 const path_w = try windows.sliceToPrefixedFileW(path);31 const path_w = try windows.sliceToPrefixedFileW(path);
32 return openReadW(&path_w);32 return openReadW(&path_w);
33 }33 }
...@@ -37,7 +37,7 @@ pub const File = struct {...@@ -37,7 +37,7 @@ pub const File = struct {
3737
38 /// `openRead` except with a null terminated path38 /// `openRead` except with a null terminated path
39 pub fn openReadC(path: [*]const u8) OpenError!File {39 pub fn openReadC(path: [*]const u8) OpenError!File {
40 if (windows.is_the_target) {40 if (builtin.os == .windows) {
41 const path_w = try windows.cStrToPrefixedFileW(path);41 const path_w = try windows.cStrToPrefixedFileW(path);
42 return openReadW(&path_w);42 return openReadW(&path_w);
43 }43 }
...@@ -69,7 +69,7 @@ pub const File = struct {...@@ -69,7 +69,7 @@ pub const File = struct {
69 /// If a file already exists in the destination it will be truncated.69 /// If a file already exists in the destination it will be truncated.
70 /// Call close to clean up.70 /// Call close to clean up.
71 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {71 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {
72 if (windows.is_the_target) {72 if (builtin.os == .windows) {
73 const path_w = try windows.sliceToPrefixedFileW(path);73 const path_w = try windows.sliceToPrefixedFileW(path);
74 return openWriteModeW(&path_w, file_mode);74 return openWriteModeW(&path_w, file_mode);
75 }75 }
...@@ -79,7 +79,7 @@ pub const File = struct {...@@ -79,7 +79,7 @@ pub const File = struct {
7979
80 /// Same as `openWriteMode` except `path` is null-terminated.80 /// Same as `openWriteMode` except `path` is null-terminated.
81 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {81 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {
82 if (windows.is_the_target) {82 if (builtin.os == .windows) {
83 const path_w = try windows.cStrToPrefixedFileW(path);83 const path_w = try windows.cStrToPrefixedFileW(path);
84 return openWriteModeW(&path_w, file_mode);84 return openWriteModeW(&path_w, file_mode);
85 }85 }
...@@ -106,7 +106,7 @@ pub const File = struct {...@@ -106,7 +106,7 @@ pub const File = struct {
106 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists106 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists
107 /// Call close to clean up.107 /// Call close to clean up.
108 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {108 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {
109 if (windows.is_the_target) {109 if (builtin.os == .windows) {
110 const path_w = try windows.sliceToPrefixedFileW(path);110 const path_w = try windows.sliceToPrefixedFileW(path);
111 return openWriteNoClobberW(&path_w, file_mode);111 return openWriteNoClobberW(&path_w, file_mode);
112 }112 }
...@@ -115,7 +115,7 @@ pub const File = struct {...@@ -115,7 +115,7 @@ pub const File = struct {
115 }115 }
116116
117 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {117 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {
118 if (windows.is_the_target) {118 if (builtin.os == .windows) {
119 const path_w = try windows.cStrToPrefixedFileW(path);119 const path_w = try windows.cStrToPrefixedFileW(path);
120 return openWriteNoClobberW(&path_w, file_mode);120 return openWriteNoClobberW(&path_w, file_mode);
121 }121 }
...@@ -174,7 +174,7 @@ pub const File = struct {...@@ -174,7 +174,7 @@ pub const File = struct {
174174
175 /// Test whether ANSI escape codes will be treated as such.175 /// Test whether ANSI escape codes will be treated as such.
176 pub fn supportsAnsiEscapeCodes(self: File) bool {176 pub fn supportsAnsiEscapeCodes(self: File) bool {
177 if (windows.is_the_target) {177 if (builtin.os == .windows) {
178 return os.isCygwinPty(self.handle);178 return os.isCygwinPty(self.handle);
179 }179 }
180 if (self.isTty()) {180 if (self.isTty()) {
...@@ -214,7 +214,7 @@ pub const File = struct {...@@ -214,7 +214,7 @@ pub const File = struct {
214 }214 }
215215
216 pub fn getEndPos(self: File) GetPosError!u64 {216 pub fn getEndPos(self: File) GetPosError!u64 {
217 if (windows.is_the_target) {217 if (builtin.os == .windows) {
218 return windows.GetFileSizeEx(self.handle);218 return windows.GetFileSizeEx(self.handle);
219 }219 }
220 return (try self.stat()).size;220 return (try self.stat()).size;
...@@ -223,7 +223,7 @@ pub const File = struct {...@@ -223,7 +223,7 @@ pub const File = struct {
223 pub const ModeError = os.FStatError;223 pub const ModeError = os.FStatError;
224224
225 pub fn mode(self: File) ModeError!Mode {225 pub fn mode(self: File) ModeError!Mode {
226 if (windows.is_the_target) {226 if (builtin.os == .windows) {
227 return {};227 return {};
228 }228 }
229 return (try self.stat()).mode;229 return (try self.stat()).mode;
...@@ -246,7 +246,7 @@ pub const File = struct {...@@ -246,7 +246,7 @@ pub const File = struct {
246 pub const StatError = os.FStatError;246 pub const StatError = os.FStatError;
247247
248 pub fn stat(self: File) StatError!Stat {248 pub fn stat(self: File) StatError!Stat {
249 if (windows.is_the_target) {249 if (builtin.os == .windows) {
250 var io_status_block: windows.IO_STATUS_BLOCK = undefined;250 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
251 var info: windows.FILE_ALL_INFORMATION = undefined;251 var info: windows.FILE_ALL_INFORMATION = undefined;
252 const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);252 const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
...@@ -291,7 +291,7 @@ pub const File = struct {...@@ -291,7 +291,7 @@ pub const File = struct {
291 /// last modification timestamp in nanoseconds291 /// last modification timestamp in nanoseconds
292 mtime: i64,292 mtime: i64,
293 ) UpdateTimesError!void {293 ) UpdateTimesError!void {
294 if (windows.is_the_target) {294 if (builtin.os == .windows) {
295 const atime_ft = windows.nanoSecondsToFileTime(atime);295 const atime_ft = windows.nanoSecondsToFileTime(atime);
296 const mtime_ft = windows.nanoSecondsToFileTime(mtime);296 const mtime_ft = windows.nanoSecondsToFileTime(mtime);
297 return windows.SetFileTime(self.handle, null, &atime_ft, &mtime_ft);297 return windows.SetFileTime(self.handle, null, &atime_ft, &mtime_ft);
lib/std/fs/path.zig+17-17
...@@ -13,16 +13,16 @@ const process = std.process;...@@ -13,16 +13,16 @@ const process = std.process;
1313
14pub const sep_windows = '\\';14pub const sep_windows = '\\';
15pub const sep_posix = '/';15pub const sep_posix = '/';
16pub const sep = if (windows.is_the_target) sep_windows else sep_posix;16pub const sep = if (builtin.os == .windows) sep_windows else sep_posix;
1717
18pub const sep_str = [1]u8{sep};18pub const sep_str = [1]u8{sep};
1919
20pub const delimiter_windows = ';';20pub const delimiter_windows = ';';
21pub const delimiter_posix = ':';21pub const delimiter_posix = ':';
22pub const delimiter = if (windows.is_the_target) delimiter_windows else delimiter_posix;22pub const delimiter = if (builtin.os == .windows) delimiter_windows else delimiter_posix;
2323
24pub fn isSep(byte: u8) bool {24pub fn isSep(byte: u8) bool {
25 if (windows.is_the_target) {25 if (builtin.os == .windows) {
26 return byte == '/' or byte == '\\';26 return byte == '/' or byte == '\\';
27 } else {27 } else {
28 return byte == '/';28 return byte == '/';
...@@ -72,7 +72,7 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u...@@ -72,7 +72,7 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u
72 return buf;72 return buf;
73}73}
7474
75pub const join = if (windows.is_the_target) joinWindows else joinPosix;75pub const join = if (builtin.os == .windows) joinWindows else joinPosix;
7676
77/// Naively combines a series of paths with the native path seperator.77/// Naively combines a series of paths with the native path seperator.
78/// Allocates memory for the result, which must be freed by the caller.78/// Allocates memory for the result, which must be freed by the caller.
...@@ -129,7 +129,7 @@ test "join" {...@@ -129,7 +129,7 @@ test "join" {
129}129}
130130
131pub fn isAbsolute(path: []const u8) bool {131pub fn isAbsolute(path: []const u8) bool {
132 if (windows.is_the_target) {132 if (builtin.os == .windows) {
133 return isAbsoluteWindows(path);133 return isAbsoluteWindows(path);
134 } else {134 } else {
135 return isAbsolutePosix(path);135 return isAbsolutePosix(path);
...@@ -327,7 +327,7 @@ test "windowsParsePath" {...@@ -327,7 +327,7 @@ test "windowsParsePath" {
327}327}
328328
329pub fn diskDesignator(path: []const u8) []const u8 {329pub fn diskDesignator(path: []const u8) []const u8 {
330 if (windows.is_the_target) {330 if (builtin.os == .windows) {
331 return diskDesignatorWindows(path);331 return diskDesignatorWindows(path);
332 } else {332 } else {
333 return "";333 return "";
...@@ -392,7 +392,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {...@@ -392,7 +392,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
392392
393/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.393/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
394pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {394pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
395 if (windows.is_the_target) {395 if (builtin.os == .windows) {
396 return resolveWindows(allocator, paths);396 return resolveWindows(allocator, paths);
397 } else {397 } else {
398 return resolvePosix(allocator, paths);398 return resolvePosix(allocator, paths);
...@@ -409,7 +409,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -409,7 +409,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
409/// Without performing actual syscalls, resolving `..` could be incorrect.409/// Without performing actual syscalls, resolving `..` could be incorrect.
410pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {410pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
411 if (paths.len == 0) {411 if (paths.len == 0) {
412 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd412 assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd
413 return process.getCwdAlloc(allocator);413 return process.getCwdAlloc(allocator);
414 }414 }
415415
...@@ -504,7 +504,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -504,7 +504,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
504 result_disk_designator = result[0..result_index];504 result_disk_designator = result[0..result_index];
505 },505 },
506 WindowsPath.Kind.None => {506 WindowsPath.Kind.None => {
507 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd507 assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd
508 const cwd = try process.getCwdAlloc(allocator);508 const cwd = try process.getCwdAlloc(allocator);
509 defer allocator.free(cwd);509 defer allocator.free(cwd);
510 const parsed_cwd = windowsParsePath(cwd);510 const parsed_cwd = windowsParsePath(cwd);
...@@ -519,7 +519,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -519,7 +519,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
519 },519 },
520 }520 }
521 } else {521 } else {
522 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd522 assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd
523 // TODO call get cwd for the result_disk_designator instead of the global one523 // TODO call get cwd for the result_disk_designator instead of the global one
524 const cwd = try process.getCwdAlloc(allocator);524 const cwd = try process.getCwdAlloc(allocator);
525 defer allocator.free(cwd);525 defer allocator.free(cwd);
...@@ -590,7 +590,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -590,7 +590,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
590/// Without performing actual syscalls, resolving `..` could be incorrect.590/// Without performing actual syscalls, resolving `..` could be incorrect.
591pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {591pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
592 if (paths.len == 0) {592 if (paths.len == 0) {
593 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd593 assert(builtin.os != .windows); // resolvePosix called on windows can't use getCwd
594 return process.getCwdAlloc(allocator);594 return process.getCwdAlloc(allocator);
595 }595 }
596596
...@@ -612,7 +612,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -612,7 +612,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
612 if (have_abs) {612 if (have_abs) {
613 result = try allocator.alloc(u8, max_size);613 result = try allocator.alloc(u8, max_size);
614 } else {614 } else {
615 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd615 assert(builtin.os != .windows); // resolvePosix called on windows can't use getCwd
616 const cwd = try process.getCwdAlloc(allocator);616 const cwd = try process.getCwdAlloc(allocator);
617 defer allocator.free(cwd);617 defer allocator.free(cwd);
618 result = try allocator.alloc(u8, max_size + cwd.len + 1);618 result = try allocator.alloc(u8, max_size + cwd.len + 1);
...@@ -653,7 +653,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -653,7 +653,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
653653
654test "resolve" {654test "resolve" {
655 const cwd = try process.getCwdAlloc(debug.global_allocator);655 const cwd = try process.getCwdAlloc(debug.global_allocator);
656 if (windows.is_the_target) {656 if (builtin.os == .windows) {
657 if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {657 if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
658 cwd[0] = asciiUpper(cwd[0]);658 cwd[0] = asciiUpper(cwd[0]);
659 }659 }
...@@ -669,7 +669,7 @@ test "resolveWindows" {...@@ -669,7 +669,7 @@ test "resolveWindows" {
669 // TODO https://github.com/ziglang/zig/issues/3288669 // TODO https://github.com/ziglang/zig/issues/3288
670 return error.SkipZigTest;670 return error.SkipZigTest;
671 }671 }
672 if (windows.is_the_target) {672 if (builtin.os == .windows) {
673 const cwd = try process.getCwdAlloc(debug.global_allocator);673 const cwd = try process.getCwdAlloc(debug.global_allocator);
674 const parsed_cwd = windowsParsePath(cwd);674 const parsed_cwd = windowsParsePath(cwd);
675 {675 {
...@@ -735,7 +735,7 @@ fn testResolvePosix(paths: []const []const u8) []u8 {...@@ -735,7 +735,7 @@ fn testResolvePosix(paths: []const []const u8) []u8 {
735/// If the path is a file in the current directory (no directory component)735/// If the path is a file in the current directory (no directory component)
736/// then returns null736/// then returns null
737pub fn dirname(path: []const u8) ?[]const u8 {737pub fn dirname(path: []const u8) ?[]const u8 {
738 if (windows.is_the_target) {738 if (builtin.os == .windows) {
739 return dirnameWindows(path);739 return dirnameWindows(path);
740 } else {740 } else {
741 return dirnamePosix(path);741 return dirnamePosix(path);
...@@ -867,7 +867,7 @@ fn testDirnameWindows(input: []const u8, expected_output: ?[]const u8) void {...@@ -867,7 +867,7 @@ fn testDirnameWindows(input: []const u8, expected_output: ?[]const u8) void {
867}867}
868868
869pub fn basename(path: []const u8) []const u8 {869pub fn basename(path: []const u8) []const u8 {
870 if (windows.is_the_target) {870 if (builtin.os == .windows) {
871 return basenameWindows(path);871 return basenameWindows(path);
872 } else {872 } else {
873 return basenamePosix(path);873 return basenamePosix(path);
...@@ -983,7 +983,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {...@@ -983,7 +983,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
983/// string is returned.983/// string is returned.
984/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.984/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.
985pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {985pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {
986 if (windows.is_the_target) {986 if (builtin.os == .windows) {
987 return relativeWindows(allocator, from, to);987 return relativeWindows(allocator, from, to);
988 } else {988 } else {
989 return relativePosix(allocator, from, to);989 return relativePosix(allocator, from, to);
lib/std/heap.zig+3-3
...@@ -44,7 +44,7 @@ const DirectAllocator = struct {...@@ -44,7 +44,7 @@ const DirectAllocator = struct {
44 if (n == 0)44 if (n == 0)
45 return (([*]u8)(undefined))[0..0];45 return (([*]u8)(undefined))[0..0];
4646
47 if (os.windows.is_the_target) {47 if (builtin.os == .windows) {
48 const w = os.windows;48 const w = os.windows;
4949
50 // Although officially it's at least aligned to page boundary,50 // Although officially it's at least aligned to page boundary,
...@@ -130,7 +130,7 @@ const DirectAllocator = struct {...@@ -130,7 +130,7 @@ const DirectAllocator = struct {
130130
131 fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {131 fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
132 const old_mem = @alignCast(mem.page_size, old_mem_unaligned);132 const old_mem = @alignCast(mem.page_size, old_mem_unaligned);
133 if (os.windows.is_the_target) {133 if (builtin.os == .windows) {
134 const w = os.windows;134 const w = os.windows;
135 if (new_size == 0) {135 if (new_size == 0) {
136 // From the docs:136 // From the docs:
...@@ -170,7 +170,7 @@ const DirectAllocator = struct {...@@ -170,7 +170,7 @@ const DirectAllocator = struct {
170170
171 fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {171 fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
172 const old_mem = @alignCast(mem.page_size, old_mem_unaligned);172 const old_mem = @alignCast(mem.page_size, old_mem_unaligned);
173 if (os.windows.is_the_target) {173 if (builtin.os == .windows) {
174 if (old_mem.len == 0) {174 if (old_mem.len == 0) {
175 return alloc(allocator, new_size, new_align);175 return alloc(allocator, new_size, new_align);
176 }176 }
lib/std/io.zig+3-3
...@@ -37,7 +37,7 @@ pub const is_async = mode != .blocking;...@@ -37,7 +37,7 @@ pub const is_async = mode != .blocking;
37pub const GetStdIoError = os.windows.GetStdHandleError;37pub const GetStdIoError = os.windows.GetStdHandleError;
3838
39pub fn getStdOut() GetStdIoError!File {39pub fn getStdOut() GetStdIoError!File {
40 if (os.windows.is_the_target) {40 if (builtin.os == .windows) {
41 const handle = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);41 const handle = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);
42 return File.openHandle(handle);42 return File.openHandle(handle);
43 }43 }
...@@ -45,7 +45,7 @@ pub fn getStdOut() GetStdIoError!File {...@@ -45,7 +45,7 @@ pub fn getStdOut() GetStdIoError!File {
45}45}
4646
47pub fn getStdErr() GetStdIoError!File {47pub fn getStdErr() GetStdIoError!File {
48 if (os.windows.is_the_target) {48 if (builtin.os == .windows) {
49 const handle = try os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE);49 const handle = try os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE);
50 return File.openHandle(handle);50 return File.openHandle(handle);
51 }51 }
...@@ -53,7 +53,7 @@ pub fn getStdErr() GetStdIoError!File {...@@ -53,7 +53,7 @@ pub fn getStdErr() GetStdIoError!File {
53}53}
5454
55pub fn getStdIn() GetStdIoError!File {55pub fn getStdIn() GetStdIoError!File {
56 if (os.windows.is_the_target) {56 if (builtin.os == .windows) {
57 const handle = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);57 const handle = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);
58 return File.openHandle(handle);58 return File.openHandle(handle);
59 }59 }
lib/std/math.zig+1-1
...@@ -202,7 +202,7 @@ pub const Complex = complex.Complex;...@@ -202,7 +202,7 @@ pub const Complex = complex.Complex;
202202
203pub const big = @import("math/big.zig");203pub const big = @import("math/big.zig");
204204
205comptime {205test "" {
206 std.meta.refAllDecls(@This());206 std.meta.refAllDecls(@This());
207}207}
208208
lib/std/os.zig+81-79
...@@ -23,10 +23,6 @@ const elf = std.elf;...@@ -23,10 +23,6 @@ const elf = std.elf;
23const dl = @import("dynamic_library.zig");23const dl = @import("dynamic_library.zig");
24const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;24const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
2525
26comptime {
27 assert(@import("std") == std); // std lib tests require --override-lib-dir
28}
29
30pub const darwin = @import("os/darwin.zig");26pub const darwin = @import("os/darwin.zig");
31pub const freebsd = @import("os/freebsd.zig");27pub const freebsd = @import("os/freebsd.zig");
32pub const linux = @import("os/linux.zig");28pub const linux = @import("os/linux.zig");
...@@ -36,6 +32,23 @@ pub const wasi = @import("os/wasi.zig");...@@ -36,6 +32,23 @@ pub const wasi = @import("os/wasi.zig");
36pub const windows = @import("os/windows.zig");32pub const windows = @import("os/windows.zig");
37pub const zen = @import("os/zen.zig");33pub const zen = @import("os/zen.zig");
3834
35comptime {
36 assert(@import("std") == std); // std lib tests require --override-lib-dir
37}
38
39test "" {
40 _ = darwin;
41 _ = freebsd;
42 _ = linux;
43 _ = netbsd;
44 _ = uefi;
45 _ = wasi;
46 _ = windows;
47 _ = zen;
48
49 _ = @import("os/test.zig");
50}
51
39/// When linking libc, this is the C API. Otherwise, it is the OS-specific system interface.52/// When linking libc, this is the C API. Otherwise, it is the OS-specific system interface.
40pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {53pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
41 .macosx, .ios, .watchos, .tvos => darwin,54 .macosx, .ios, .watchos, .tvos => darwin,
...@@ -72,13 +85,13 @@ pub const errno = system.getErrno;...@@ -72,13 +85,13 @@ pub const errno = system.getErrno;
72/// must call `fsync` before `close`.85/// must call `fsync` before `close`.
73/// Note: The Zig standard library does not support POSIX thread cancellation.86/// Note: The Zig standard library does not support POSIX thread cancellation.
74pub fn close(fd: fd_t) void {87pub fn close(fd: fd_t) void {
75 if (windows.is_the_target) {88 if (builtin.os == .windows) {
76 return windows.CloseHandle(fd);89 return windows.CloseHandle(fd);
77 }90 }
78 if (wasi.is_the_target) {91 if (builtin.os == .wasi) {
79 _ = wasi.fd_close(fd);92 _ = wasi.fd_close(fd);
80 }93 }
81 if (darwin.is_the_target) {94 if (comptime std.Target.current.isDarwin()) {
82 // This avoids the EINTR problem.95 // This avoids the EINTR problem.
83 switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {96 switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {
84 EBADF => unreachable, // Always a race condition.97 EBADF => unreachable, // Always a race condition.
...@@ -100,12 +113,12 @@ pub const GetRandomError = OpenError;...@@ -100,12 +113,12 @@ pub const GetRandomError = OpenError;
100/// appropriate OS-specific library call. Otherwise it uses the zig standard113/// appropriate OS-specific library call. Otherwise it uses the zig standard
101/// library implementation.114/// library implementation.
102pub fn getrandom(buffer: []u8) GetRandomError!void {115pub fn getrandom(buffer: []u8) GetRandomError!void {
103 if (windows.is_the_target) {116 if (builtin.os == .windows) {
104 return windows.RtlGenRandom(buffer);117 return windows.RtlGenRandom(buffer);
105 }118 }
106 if (linux.is_the_target or freebsd.is_the_target) {119 if (builtin.os == .linux or builtin.os == .freebsd) {
107 var buf = buffer;120 var buf = buffer;
108 const use_c = !linux.is_the_target or121 const use_c = builtin.os != .linux or
109 std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;122 std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;
110123
111 while (buf.len != 0) {124 while (buf.len != 0) {
...@@ -132,7 +145,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -132,7 +145,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
132 }145 }
133 return;146 return;
134 }147 }
135 if (wasi.is_the_target) {148 if (builtin.os == .wasi) {
136 switch (wasi.random_get(buffer.ptr, buffer.len)) {149 switch (wasi.random_get(buffer.ptr, buffer.len)) {
137 0 => return,150 0 => return,
138 else => |err| return unexpectedErrno(err),151 else => |err| return unexpectedErrno(err),
...@@ -162,7 +175,7 @@ pub fn abort() noreturn {...@@ -162,7 +175,7 @@ pub fn abort() noreturn {
162 // MSVCRT abort() sometimes opens a popup window which is undesirable, so175 // MSVCRT abort() sometimes opens a popup window which is undesirable, so
163 // even when linking libc on Windows we use our own abort implementation.176 // even when linking libc on Windows we use our own abort implementation.
164 // See https://github.com/ziglang/zig/issues/2071 for more details.177 // See https://github.com/ziglang/zig/issues/2071 for more details.
165 if (windows.is_the_target) {178 if (builtin.os == .windows) {
166 if (builtin.mode == .Debug) {179 if (builtin.mode == .Debug) {
167 @breakpoint();180 @breakpoint();
168 }181 }
...@@ -193,14 +206,14 @@ pub fn raise(sig: u8) RaiseError!void {...@@ -193,14 +206,14 @@ pub fn raise(sig: u8) RaiseError!void {
193 }206 }
194 }207 }
195208
196 if (wasi.is_the_target) {209 if (builtin.os == .wasi) {
197 switch (wasi.proc_raise(SIGABRT)) {210 switch (wasi.proc_raise(SIGABRT)) {
198 0 => return,211 0 => return,
199 else => |err| return unexpectedErrno(err),212 else => |err| return unexpectedErrno(err),
200 }213 }
201 }214 }
202215
203 if (linux.is_the_target) {216 if (builtin.os == .linux) {
204 var set: linux.sigset_t = undefined;217 var set: linux.sigset_t = undefined;
205 linux.blockAppSignals(&set);218 linux.blockAppSignals(&set);
206 const tid = linux.syscall0(linux.SYS_gettid);219 const tid = linux.syscall0(linux.SYS_gettid);
...@@ -232,16 +245,16 @@ pub fn exit(status: u8) noreturn {...@@ -232,16 +245,16 @@ pub fn exit(status: u8) noreturn {
232 if (builtin.link_libc) {245 if (builtin.link_libc) {
233 system.exit(status);246 system.exit(status);
234 }247 }
235 if (windows.is_the_target) {248 if (builtin.os == .windows) {
236 windows.kernel32.ExitProcess(status);249 windows.kernel32.ExitProcess(status);
237 }250 }
238 if (wasi.is_the_target) {251 if (builtin.os == .wasi) {
239 wasi.proc_exit(status);252 wasi.proc_exit(status);
240 }253 }
241 if (linux.is_the_target and !builtin.single_threaded) {254 if (builtin.os == .linux and !builtin.single_threaded) {
242 linux.exit_group(status);255 linux.exit_group(status);
243 }256 }
244 if (uefi.is_the_target) {257 if (builtin.os == .uefi) {
245 // exit() is only avaliable if exitBootServices() has not been called yet.258 // exit() is only avaliable if exitBootServices() has not been called yet.
246 // This call to exit should not fail, so we don't care about its return value.259 // This call to exit should not fail, so we don't care about its return value.
247 if (uefi.system_table.boot_services) |bs| {260 if (uefi.system_table.boot_services) |bs| {
...@@ -270,11 +283,11 @@ pub const ReadError = error{...@@ -270,11 +283,11 @@ pub const ReadError = error{
270/// If the application has a global event loop enabled, EAGAIN is handled283/// If the application has a global event loop enabled, EAGAIN is handled
271/// via the event loop. Otherwise EAGAIN results in error.WouldBlock.284/// via the event loop. Otherwise EAGAIN results in error.WouldBlock.
272pub fn read(fd: fd_t, buf: []u8) ReadError!usize {285pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
273 if (windows.is_the_target) {286 if (builtin.os == .windows) {
274 return windows.ReadFile(fd, buf);287 return windows.ReadFile(fd, buf);
275 }288 }
276289
277 if (wasi.is_the_target and !builtin.link_libc) {290 if (builtin.os == .wasi and !builtin.link_libc) {
278 const iovs = [1]iovec{iovec{291 const iovs = [1]iovec{iovec{
279 .iov_base = buf.ptr,292 .iov_base = buf.ptr,
280 .iov_len = buf.len,293 .iov_len = buf.len,
...@@ -314,7 +327,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -314,7 +327,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
314/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.327/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
315/// This function is for blocking file descriptors only.328/// This function is for blocking file descriptors only.
316pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize {329pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize {
317 if (darwin.is_the_target) {330 if (comptime std.Target.current.isDarwin()) {
318 // Darwin does not have preadv but it does have pread.331 // Darwin does not have preadv but it does have pread.
319 var off: usize = 0;332 var off: usize = 0;
320 var iov_i: usize = 0;333 var iov_i: usize = 0;
...@@ -385,11 +398,11 @@ pub const WriteError = error{...@@ -385,11 +398,11 @@ pub const WriteError = error{
385/// Write to a file descriptor. Keeps trying if it gets interrupted.398/// Write to a file descriptor. Keeps trying if it gets interrupted.
386/// This function is for blocking file descriptors only.399/// This function is for blocking file descriptors only.
387pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {400pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
388 if (windows.is_the_target) {401 if (builtin.os == .windows) {
389 return windows.WriteFile(fd, bytes);402 return windows.WriteFile(fd, bytes);
390 }403 }
391404
392 if (wasi.is_the_target and !builtin.link_libc) {405 if (builtin.os == .wasi and !builtin.link_libc) {
393 const ciovs = [1]iovec_const{iovec_const{406 const ciovs = [1]iovec_const{iovec_const{
394 .iov_base = bytes.ptr,407 .iov_base = bytes.ptr,
395 .iov_len = bytes.len,408 .iov_len = bytes.len,
...@@ -464,7 +477,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!void {...@@ -464,7 +477,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!void {
464/// This function is for blocking file descriptors only. For non-blocking, see477/// This function is for blocking file descriptors only. For non-blocking, see
465/// `pwritevAsync`.478/// `pwritevAsync`.
466pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void {479pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void {
467 if (darwin.is_the_target) {480 if (comptime std.Target.current.isDarwin()) {
468 // Darwin does not have pwritev but it does have pwrite.481 // Darwin does not have pwritev but it does have pwrite.
469 var off: usize = 0;482 var off: usize = 0;
470 var iov_i: usize = 0;483 var iov_i: usize = 0;
...@@ -828,7 +841,7 @@ pub const GetCwdError = error{...@@ -828,7 +841,7 @@ pub const GetCwdError = error{
828841
829/// The result is a slice of out_buffer, indexed from 0.842/// The result is a slice of out_buffer, indexed from 0.
830pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {843pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
831 if (windows.is_the_target) {844 if (builtin.os == .windows) {
832 return windows.GetCurrentDirectory(out_buffer);845 return windows.GetCurrentDirectory(out_buffer);
833 }846 }
834847
...@@ -869,7 +882,7 @@ pub const SymLinkError = error{...@@ -869,7 +882,7 @@ pub const SymLinkError = error{
869/// If `sym_link_path` exists, it will not be overwritten.882/// If `sym_link_path` exists, it will not be overwritten.
870/// See also `symlinkC` and `symlinkW`.883/// See also `symlinkC` and `symlinkW`.
871pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void {884pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void {
872 if (windows.is_the_target) {885 if (builtin.os == .windows) {
873 const target_path_w = try windows.sliceToPrefixedFileW(target_path);886 const target_path_w = try windows.sliceToPrefixedFileW(target_path);
874 const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);887 const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);
875 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);888 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);
...@@ -883,7 +896,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!...@@ -883,7 +896,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
883/// This is the same as `symlink` except the parameters are null-terminated pointers.896/// This is the same as `symlink` except the parameters are null-terminated pointers.
884/// See also `symlink`.897/// See also `symlink`.
885pub fn symlinkC(target_path: [*]const u8, sym_link_path: [*]const u8) SymLinkError!void {898pub fn symlinkC(target_path: [*]const u8, sym_link_path: [*]const u8) SymLinkError!void {
886 if (windows.is_the_target) {899 if (builtin.os == .windows) {
887 const target_path_w = try windows.cStrToPrefixedFileW(target_path);900 const target_path_w = try windows.cStrToPrefixedFileW(target_path);
888 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);901 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
889 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);902 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);
...@@ -958,7 +971,7 @@ pub const UnlinkError = error{...@@ -958,7 +971,7 @@ pub const UnlinkError = error{
958/// Delete a name and possibly the file it refers to.971/// Delete a name and possibly the file it refers to.
959/// See also `unlinkC`.972/// See also `unlinkC`.
960pub fn unlink(file_path: []const u8) UnlinkError!void {973pub fn unlink(file_path: []const u8) UnlinkError!void {
961 if (windows.is_the_target) {974 if (builtin.os == .windows) {
962 const file_path_w = try windows.sliceToPrefixedFileW(file_path);975 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
963 return windows.DeleteFileW(&file_path_w);976 return windows.DeleteFileW(&file_path_w);
964 } else {977 } else {
...@@ -969,7 +982,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void {...@@ -969,7 +982,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void {
969982
970/// Same as `unlink` except the parameter is a null terminated UTF8-encoded string.983/// Same as `unlink` except the parameter is a null terminated UTF8-encoded string.
971pub fn unlinkC(file_path: [*]const u8) UnlinkError!void {984pub fn unlinkC(file_path: [*]const u8) UnlinkError!void {
972 if (windows.is_the_target) {985 if (builtin.os == .windows) {
973 const file_path_w = try windows.cStrToPrefixedFileW(file_path);986 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
974 return windows.DeleteFileW(&file_path_w);987 return windows.DeleteFileW(&file_path_w);
975 }988 }
...@@ -999,7 +1012,7 @@ pub const UnlinkatError = UnlinkError || error{...@@ -999,7 +1012,7 @@ pub const UnlinkatError = UnlinkError || error{
9991012
1000/// Delete a file name and possibly the file it refers to, based on an open directory handle.1013/// Delete a file name and possibly the file it refers to, based on an open directory handle.
1001pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {1014pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
1002 if (windows.is_the_target) {1015 if (builtin.os == .windows) {
1003 const file_path_w = try windows.sliceToPrefixedFileW(file_path);1016 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
1004 return unlinkatW(dirfd, &file_path_w, flags);1017 return unlinkatW(dirfd, &file_path_w, flags);
1005 }1018 }
...@@ -1009,7 +1022,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo...@@ -1009,7 +1022,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo
10091022
1010/// Same as `unlinkat` but `file_path` is a null-terminated string.1023/// Same as `unlinkat` but `file_path` is a null-terminated string.
1011pub fn unlinkatC(dirfd: fd_t, file_path_c: [*]const u8, flags: u32) UnlinkatError!void {1024pub fn unlinkatC(dirfd: fd_t, file_path_c: [*]const u8, flags: u32) UnlinkatError!void {
1012 if (windows.is_the_target) {1025 if (builtin.os == .windows) {
1013 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);1026 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);
1014 return unlinkatW(dirfd, &file_path_w, flags);1027 return unlinkatW(dirfd, &file_path_w, flags);
1015 }1028 }
...@@ -1063,7 +1076,6 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro...@@ -1063,7 +1076,6 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro
1063 return error.FileBusy;1076 return error.FileBusy;
1064 }1077 }
10651078
1066
1067 var attr = w.OBJECT_ATTRIBUTES{1079 var attr = w.OBJECT_ATTRIBUTES{
1068 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),1080 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
1069 .RootDirectory = dirfd,1081 .RootDirectory = dirfd,
...@@ -1121,7 +1133,7 @@ const RenameError = error{...@@ -1121,7 +1133,7 @@ const RenameError = error{
11211133
1122/// Change the name or location of a file.1134/// Change the name or location of a file.
1123pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {1135pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
1124 if (windows.is_the_target) {1136 if (builtin.os == .windows) {
1125 const old_path_w = try windows.sliceToPrefixedFileW(old_path);1137 const old_path_w = try windows.sliceToPrefixedFileW(old_path);
1126 const new_path_w = try windows.sliceToPrefixedFileW(new_path);1138 const new_path_w = try windows.sliceToPrefixedFileW(new_path);
1127 return renameW(&old_path_w, &new_path_w);1139 return renameW(&old_path_w, &new_path_w);
...@@ -1134,7 +1146,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {...@@ -1134,7 +1146,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
11341146
1135/// Same as `rename` except the parameters are null-terminated byte arrays.1147/// Same as `rename` except the parameters are null-terminated byte arrays.
1136pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {1148pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {
1137 if (windows.is_the_target) {1149 if (builtin.os == .windows) {
1138 const old_path_w = try windows.cStrToPrefixedFileW(old_path);1150 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
1139 const new_path_w = try windows.cStrToPrefixedFileW(new_path);1151 const new_path_w = try windows.cStrToPrefixedFileW(new_path);
1140 return renameW(&old_path_w, &new_path_w);1152 return renameW(&old_path_w, &new_path_w);
...@@ -1189,7 +1201,7 @@ pub const MakeDirError = error{...@@ -1189,7 +1201,7 @@ pub const MakeDirError = error{
1189/// Create a directory.1201/// Create a directory.
1190/// `mode` is ignored on Windows.1202/// `mode` is ignored on Windows.
1191pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {1203pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
1192 if (windows.is_the_target) {1204 if (builtin.os == .windows) {
1193 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);1205 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
1194 return windows.CreateDirectoryW(&dir_path_w, null);1206 return windows.CreateDirectoryW(&dir_path_w, null);
1195 } else {1207 } else {
...@@ -1200,7 +1212,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {...@@ -1200,7 +1212,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
12001212
1201/// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string.1213/// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string.
1202pub fn mkdirC(dir_path: [*]const u8, mode: u32) MakeDirError!void {1214pub fn mkdirC(dir_path: [*]const u8, mode: u32) MakeDirError!void {
1203 if (windows.is_the_target) {1215 if (builtin.os == .windows) {
1204 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1216 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1205 return windows.CreateDirectoryW(&dir_path_w, null);1217 return windows.CreateDirectoryW(&dir_path_w, null);
1206 }1218 }
...@@ -1239,7 +1251,7 @@ pub const DeleteDirError = error{...@@ -1239,7 +1251,7 @@ pub const DeleteDirError = error{
12391251
1240/// Deletes an empty directory.1252/// Deletes an empty directory.
1241pub fn rmdir(dir_path: []const u8) DeleteDirError!void {1253pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
1242 if (windows.is_the_target) {1254 if (builtin.os == .windows) {
1243 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);1255 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
1244 return windows.RemoveDirectoryW(&dir_path_w);1256 return windows.RemoveDirectoryW(&dir_path_w);
1245 } else {1257 } else {
...@@ -1250,7 +1262,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void {...@@ -1250,7 +1262,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
12501262
1251/// Same as `rmdir` except the parameter is null-terminated.1263/// Same as `rmdir` except the parameter is null-terminated.
1252pub fn rmdirC(dir_path: [*]const u8) DeleteDirError!void {1264pub fn rmdirC(dir_path: [*]const u8) DeleteDirError!void {
1253 if (windows.is_the_target) {1265 if (builtin.os == .windows) {
1254 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1266 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1255 return windows.RemoveDirectoryW(&dir_path_w);1267 return windows.RemoveDirectoryW(&dir_path_w);
1256 }1268 }
...@@ -1286,7 +1298,7 @@ pub const ChangeCurDirError = error{...@@ -1286,7 +1298,7 @@ pub const ChangeCurDirError = error{
1286/// Changes the current working directory of the calling process.1298/// Changes the current working directory of the calling process.
1287/// `dir_path` is recommended to be a UTF-8 encoded string.1299/// `dir_path` is recommended to be a UTF-8 encoded string.
1288pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {1300pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
1289 if (windows.is_the_target) {1301 if (builtin.os == .windows) {
1290 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);1302 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
1291 @compileError("TODO implement chdir for Windows");1303 @compileError("TODO implement chdir for Windows");
1292 } else {1304 } else {
...@@ -1297,7 +1309,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {...@@ -1297,7 +1309,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
12971309
1298/// Same as `chdir` except the parameter is null-terminated.1310/// Same as `chdir` except the parameter is null-terminated.
1299pub fn chdirC(dir_path: [*]const u8) ChangeCurDirError!void {1311pub fn chdirC(dir_path: [*]const u8) ChangeCurDirError!void {
1300 if (windows.is_the_target) {1312 if (builtin.os == .windows) {
1301 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1313 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1302 @compileError("TODO implement chdir for Windows");1314 @compileError("TODO implement chdir for Windows");
1303 }1315 }
...@@ -1328,7 +1340,7 @@ pub const ReadLinkError = error{...@@ -1328,7 +1340,7 @@ pub const ReadLinkError = error{
1328/// Read value of a symbolic link.1340/// Read value of a symbolic link.
1329/// The return value is a slice of `out_buffer` from index 0.1341/// The return value is a slice of `out_buffer` from index 0.
1330pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {1342pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
1331 if (windows.is_the_target) {1343 if (builtin.os == .windows) {
1332 const file_path_w = try windows.sliceToPrefixedFileW(file_path);1344 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
1333 @compileError("TODO implement readlink for Windows");1345 @compileError("TODO implement readlink for Windows");
1334 } else {1346 } else {
...@@ -1339,7 +1351,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {...@@ -1339,7 +1351,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
13391351
1340/// Same as `readlink` except `file_path` is null-terminated.1352/// Same as `readlink` except `file_path` is null-terminated.
1341pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {1353pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1342 if (windows.is_the_target) {1354 if (builtin.os == .windows) {
1343 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1355 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1344 @compileError("TODO implement readlink for Windows");1356 @compileError("TODO implement readlink for Windows");
1345 }1357 }
...@@ -1360,7 +1372,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {...@@ -1360,7 +1372,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1360}1372}
13611373
1362pub fn readlinkatC(dirfd: fd_t, file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {1374pub fn readlinkatC(dirfd: fd_t, file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1363 if (windows.is_the_target) {1375 if (builtin.os == .windows) {
1364 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1376 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1365 @compileError("TODO implement readlink for Windows");1377 @compileError("TODO implement readlink for Windows");
1366 }1378 }
...@@ -1428,7 +1440,7 @@ pub fn setregid(rgid: u32, egid: u32) SetIdError!void {...@@ -1428,7 +1440,7 @@ pub fn setregid(rgid: u32, egid: u32) SetIdError!void {
14281440
1429/// Test whether a file descriptor refers to a terminal.1441/// Test whether a file descriptor refers to a terminal.
1430pub fn isatty(handle: fd_t) bool {1442pub fn isatty(handle: fd_t) bool {
1431 if (windows.is_the_target) {1443 if (builtin.os == .windows) {
1432 if (isCygwinPty(handle))1444 if (isCygwinPty(handle))
1433 return true;1445 return true;
14341446
...@@ -1438,10 +1450,10 @@ pub fn isatty(handle: fd_t) bool {...@@ -1438,10 +1450,10 @@ pub fn isatty(handle: fd_t) bool {
1438 if (builtin.link_libc) {1450 if (builtin.link_libc) {
1439 return system.isatty(handle) != 0;1451 return system.isatty(handle) != 0;
1440 }1452 }
1441 if (wasi.is_the_target) {1453 if (builtin.os == .wasi) {
1442 @compileError("TODO implement std.os.isatty for WASI");1454 @compileError("TODO implement std.os.isatty for WASI");
1443 }1455 }
1444 if (linux.is_the_target) {1456 if (builtin.os == .linux) {
1445 var wsz: linux.winsize = undefined;1457 var wsz: linux.winsize = undefined;
1446 return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, isize(handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;1458 return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, isize(handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
1447 }1459 }
...@@ -1449,7 +1461,7 @@ pub fn isatty(handle: fd_t) bool {...@@ -1449,7 +1461,7 @@ pub fn isatty(handle: fd_t) bool {
1449}1461}
14501462
1451pub fn isCygwinPty(handle: fd_t) bool {1463pub fn isCygwinPty(handle: fd_t) bool {
1452 if (!windows.is_the_target) return false;1464 if (builtin.os != .windows) return false;
14531465
1454 const size = @sizeOf(windows.FILE_NAME_INFO);1466 const size = @sizeOf(windows.FILE_NAME_INFO);
1455 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (size + windows.MAX_PATH);1467 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (size + windows.MAX_PATH);
...@@ -1949,7 +1961,7 @@ pub const FStatError = error{SystemResources} || UnexpectedError;...@@ -1949,7 +1961,7 @@ pub const FStatError = error{SystemResources} || UnexpectedError;
19491961
1950pub fn fstat(fd: fd_t) FStatError!Stat {1962pub fn fstat(fd: fd_t) FStatError!Stat {
1951 var stat: Stat = undefined;1963 var stat: Stat = undefined;
1952 if (darwin.is_the_target) {1964 if (comptime std.Target.current.isDarwin()) {
1953 switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) {1965 switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) {
1954 0 => return stat,1966 0 => return stat,
1955 EINVAL => unreachable,1967 EINVAL => unreachable,
...@@ -2215,7 +2227,7 @@ pub const AccessError = error{...@@ -2215,7 +2227,7 @@ pub const AccessError = error{
2215/// check user's permissions for a file2227/// check user's permissions for a file
2216/// TODO currently this assumes `mode` is `F_OK` on Windows.2228/// TODO currently this assumes `mode` is `F_OK` on Windows.
2217pub fn access(path: []const u8, mode: u32) AccessError!void {2229pub fn access(path: []const u8, mode: u32) AccessError!void {
2218 if (windows.is_the_target) {2230 if (builtin.os == .windows) {
2219 const path_w = try windows.sliceToPrefixedFileW(path);2231 const path_w = try windows.sliceToPrefixedFileW(path);
2220 _ = try windows.GetFileAttributesW(&path_w);2232 _ = try windows.GetFileAttributesW(&path_w);
2221 return;2233 return;
...@@ -2226,7 +2238,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {...@@ -2226,7 +2238,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
22262238
2227/// Same as `access` except `path` is null-terminated.2239/// Same as `access` except `path` is null-terminated.
2228pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {2240pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {
2229 if (windows.is_the_target) {2241 if (builtin.os == .windows) {
2230 const path_w = try windows.cStrToPrefixedFileW(path);2242 const path_w = try windows.cStrToPrefixedFileW(path);
2231 _ = try windows.GetFileAttributesW(&path_w);2243 _ = try windows.GetFileAttributesW(&path_w);
2232 return;2244 return;
...@@ -2346,7 +2358,7 @@ pub const SeekError = error{Unseekable} || UnexpectedError;...@@ -2346,7 +2358,7 @@ pub const SeekError = error{Unseekable} || UnexpectedError;
23462358
2347/// Repositions read/write file offset relative to the beginning.2359/// Repositions read/write file offset relative to the beginning.
2348pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {2360pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
2349 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {2361 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
2350 var result: u64 = undefined;2362 var result: u64 = undefined;
2351 switch (errno(system.llseek(fd, offset, &result, SEEK_SET))) {2363 switch (errno(system.llseek(fd, offset, &result, SEEK_SET))) {
2352 0 => return,2364 0 => return,
...@@ -2358,7 +2370,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -2358,7 +2370,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
2358 else => |err| return unexpectedErrno(err),2370 else => |err| return unexpectedErrno(err),
2359 }2371 }
2360 }2372 }
2361 if (windows.is_the_target) {2373 if (builtin.os == .windows) {
2362 return windows.SetFilePointerEx_BEGIN(fd, offset);2374 return windows.SetFilePointerEx_BEGIN(fd, offset);
2363 }2375 }
2364 const ipos = @bitCast(i64, offset); // the OS treats this as unsigned2376 const ipos = @bitCast(i64, offset); // the OS treats this as unsigned
...@@ -2375,7 +2387,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -2375,7 +2387,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
23752387
2376/// Repositions read/write file offset relative to the current offset.2388/// Repositions read/write file offset relative to the current offset.
2377pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {2389pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
2378 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {2390 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
2379 var result: u64 = undefined;2391 var result: u64 = undefined;
2380 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_CUR))) {2392 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_CUR))) {
2381 0 => return,2393 0 => return,
...@@ -2387,7 +2399,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -2387,7 +2399,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
2387 else => |err| return unexpectedErrno(err),2399 else => |err| return unexpectedErrno(err),
2388 }2400 }
2389 }2401 }
2390 if (windows.is_the_target) {2402 if (builtin.os == .windows) {
2391 return windows.SetFilePointerEx_CURRENT(fd, offset);2403 return windows.SetFilePointerEx_CURRENT(fd, offset);
2392 }2404 }
2393 switch (errno(system.lseek(fd, offset, SEEK_CUR))) {2405 switch (errno(system.lseek(fd, offset, SEEK_CUR))) {
...@@ -2403,7 +2415,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -2403,7 +2415,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
24032415
2404/// Repositions read/write file offset relative to the end.2416/// Repositions read/write file offset relative to the end.
2405pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {2417pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
2406 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {2418 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
2407 var result: u64 = undefined;2419 var result: u64 = undefined;
2408 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_END))) {2420 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_END))) {
2409 0 => return,2421 0 => return,
...@@ -2415,7 +2427,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -2415,7 +2427,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
2415 else => |err| return unexpectedErrno(err),2427 else => |err| return unexpectedErrno(err),
2416 }2428 }
2417 }2429 }
2418 if (windows.is_the_target) {2430 if (builtin.os == .windows) {
2419 return windows.SetFilePointerEx_END(fd, offset);2431 return windows.SetFilePointerEx_END(fd, offset);
2420 }2432 }
2421 switch (errno(system.lseek(fd, offset, SEEK_END))) {2433 switch (errno(system.lseek(fd, offset, SEEK_END))) {
...@@ -2431,7 +2443,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -2431,7 +2443,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
24312443
2432/// Returns the read/write file offset relative to the beginning.2444/// Returns the read/write file offset relative to the beginning.
2433pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {2445pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
2434 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {2446 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
2435 var result: u64 = undefined;2447 var result: u64 = undefined;
2436 switch (errno(system.llseek(fd, 0, &result, SEEK_CUR))) {2448 switch (errno(system.llseek(fd, 0, &result, SEEK_CUR))) {
2437 0 => return result,2449 0 => return result,
...@@ -2443,7 +2455,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {...@@ -2443,7 +2455,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
2443 else => |err| return unexpectedErrno(err),2455 else => |err| return unexpectedErrno(err),
2444 }2456 }
2445 }2457 }
2446 if (windows.is_the_target) {2458 if (builtin.os == .windows) {
2447 return windows.SetFilePointerEx_CURRENT_get(fd);2459 return windows.SetFilePointerEx_CURRENT_get(fd);
2448 }2460 }
2449 const rc = system.lseek(fd, 0, SEEK_CUR);2461 const rc = system.lseek(fd, 0, SEEK_CUR);
...@@ -2492,7 +2504,7 @@ pub const RealPathError = error{...@@ -2492,7 +2504,7 @@ pub const RealPathError = error{
2492/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.2504/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.
2493/// See also `realpathC` and `realpathW`.2505/// See also `realpathC` and `realpathW`.
2494pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {2506pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2495 if (windows.is_the_target) {2507 if (builtin.os == .windows) {
2496 const pathname_w = try windows.sliceToPrefixedFileW(pathname);2508 const pathname_w = try windows.sliceToPrefixedFileW(pathname);
2497 return realpathW(&pathname_w, out_buffer);2509 return realpathW(&pathname_w, out_buffer);
2498 }2510 }
...@@ -2502,11 +2514,11 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE...@@ -2502,11 +2514,11 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
25022514
2503/// Same as `realpath` except `pathname` is null-terminated.2515/// Same as `realpath` except `pathname` is null-terminated.
2504pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {2516pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2505 if (windows.is_the_target) {2517 if (builtin.os == .windows) {
2506 const pathname_w = try windows.cStrToPrefixedFileW(pathname);2518 const pathname_w = try windows.cStrToPrefixedFileW(pathname);
2507 return realpathW(&pathname_w, out_buffer);2519 return realpathW(&pathname_w, out_buffer);
2508 }2520 }
2509 if (linux.is_the_target and !builtin.link_libc) {2521 if (builtin.os == .linux and !builtin.link_libc) {
2510 const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);2522 const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);
2511 defer close(fd);2523 defer close(fd);
25122524
...@@ -2584,9 +2596,12 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {...@@ -2584,9 +2596,12 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
2584 }2596 }
2585}2597}
25862598
2587pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize {2599pub fn dl_iterate_phdr(
2588 // This is implemented only for systems using ELF executables2600 comptime T: type,
2589 if (windows.is_the_target or builtin.os == .uefi or wasi.is_the_target or darwin.is_the_target)2601 callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32,
2602 data: ?*T,
2603) isize {
2604 if (builtin.object_format != .elf)
2590 @compileError("dl_iterate_phdr is not available for this target");2605 @compileError("dl_iterate_phdr is not available for this target");
25912606
2592 if (builtin.link_libc) {2607 if (builtin.link_libc) {
...@@ -2725,7 +2740,7 @@ pub const SigaltstackError = error{...@@ -2725,7 +2740,7 @@ pub const SigaltstackError = error{
2725} || UnexpectedError;2740} || UnexpectedError;
27262741
2727pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {2742pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
2728 if (windows.is_the_target or uefi.is_the_target or wasi.is_the_target)2743 if (builtin.os == .windows or builtin.os == .uefi or builtin.os == .wasi)
2729 @compileError("std.os.sigaltstack not available for this target");2744 @compileError("std.os.sigaltstack not available for this target");
27302745
2731 switch (errno(system.sigaltstack(ss, old_ss))) {2746 switch (errno(system.sigaltstack(ss, old_ss))) {
...@@ -2797,7 +2812,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {...@@ -2797,7 +2812,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
2797 else => |err| return unexpectedErrno(err),2812 else => |err| return unexpectedErrno(err),
2798 }2813 }
2799 }2814 }
2800 if (linux.is_the_target) {2815 if (builtin.os == .linux) {
2801 var uts: utsname = undefined;2816 var uts: utsname = undefined;
2802 switch (errno(system.uname(&uts))) {2817 switch (errno(system.uname(&uts))) {
2803 0 => {2818 0 => {
...@@ -2813,16 +2828,3 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {...@@ -2813,16 +2828,3 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
28132828
2814 @compileError("TODO implement gethostname for this OS");2829 @compileError("TODO implement gethostname for this OS");
2815}2830}
2816
2817test "" {
2818 _ = @import("os/darwin.zig");
2819 _ = @import("os/freebsd.zig");
2820 _ = @import("os/linux.zig");
2821 _ = @import("os/netbsd.zig");
2822 _ = @import("os/uefi.zig");
2823 _ = @import("os/wasi.zig");
2824 _ = @import("os/windows.zig");
2825 _ = @import("os/zen.zig");
2826
2827 _ = @import("os/test.zig");
2828}
lib/std/os/darwin.zig-4
...@@ -1,8 +1,4 @@...@@ -1,8 +1,4 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("../std.zig");2const std = @import("../std.zig");
3pub const is_the_target = switch (builtin.os) {
4 .macosx, .tvos, .watchos, .ios => true,
5 else => false,
6};
7pub usingnamespace std.c;3pub usingnamespace std.c;
8pub usingnamespace @import("bits.zig");4pub usingnamespace @import("bits.zig");
lib/std/os/freebsd.zig-2
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");
3pub const is_the_target = builtin.os == .freebsd;
4pub usingnamespace std.c;2pub usingnamespace std.c;
5pub usingnamespace @import("bits.zig");3pub usingnamespace @import("bits.zig");
lib/std/os/linux.zig+1-2
...@@ -13,7 +13,6 @@ const elf = std.elf;...@@ -13,7 +13,6 @@ const elf = std.elf;
13const vdso = @import("linux/vdso.zig");13const vdso = @import("linux/vdso.zig");
14const dl = @import("../dynamic_library.zig");14const dl = @import("../dynamic_library.zig");
1515
16pub const is_the_target = builtin.os == .linux;
17pub usingnamespace switch (builtin.arch) {16pub usingnamespace switch (builtin.arch) {
18 .x86_64 => @import("linux/x86_64.zig"),17 .x86_64 => @import("linux/x86_64.zig"),
19 .aarch64 => @import("linux/arm64.zig"),18 .aarch64 => @import("linux/arm64.zig"),
...@@ -1079,7 +1078,7 @@ pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32...@@ -1079,7 +1078,7 @@ pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32
1079}1078}
10801079
1081test "" {1080test "" {
1082 if (is_the_target) {1081 if (builtin.os == .linux) {
1083 _ = @import("linux/test.zig");1082 _ = @import("linux/test.zig");
1084 }1083 }
1085}1084}
lib/std/os/netbsd.zig-2
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1const builtin = @import("builtin");
2const std = @import("../std.zig");1const std = @import("../std.zig");
3pub const is_the_target = builtin.os == .netbsd;
4pub usingnamespace std.c;2pub usingnamespace std.c;
5pub usingnamespace @import("bits.zig");3pub usingnamespace @import("bits.zig");
lib/std/os/test.zig+3-3
...@@ -53,7 +53,7 @@ test "std.Thread.getCurrentId" {...@@ -53,7 +53,7 @@ test "std.Thread.getCurrentId" {
53 thread.wait();53 thread.wait();
54 if (Thread.use_pthreads) {54 if (Thread.use_pthreads) {
55 expect(thread_current_id == thread_id);55 expect(thread_current_id == thread_id);
56 } else if (os.windows.is_the_target) {56 } else if (builtin.os == .windows) {
57 expect(Thread.getCurrentId() != thread_current_id);57 expect(Thread.getCurrentId() != thread_current_id);
58 } else {58 } else {
59 // If the thread completes very quickly, then thread_id can be 0. See the59 // If the thread completes very quickly, then thread_id can be 0. See the
...@@ -212,7 +212,7 @@ test "dl_iterate_phdr" {...@@ -212,7 +212,7 @@ test "dl_iterate_phdr" {
212}212}
213213
214test "gethostname" {214test "gethostname" {
215 if (os.windows.is_the_target)215 if (builtin.os == .windows)
216 return error.SkipZigTest;216 return error.SkipZigTest;
217217
218 var buf: [os.HOST_NAME_MAX]u8 = undefined;218 var buf: [os.HOST_NAME_MAX]u8 = undefined;
...@@ -221,7 +221,7 @@ test "gethostname" {...@@ -221,7 +221,7 @@ test "gethostname" {
221}221}
222222
223test "pipe" {223test "pipe" {
224 if (os.windows.is_the_target)224 if (builtin.os == .windows)
225 return error.SkipZigTest;225 return error.SkipZigTest;
226226
227 var fds = try os.pipe();227 var fds = try os.pipe();
lib/std/os/uefi.zig+13-3
...@@ -1,16 +1,15 @@...@@ -1,16 +1,15 @@
1/// A protocol is an interface identified by a GUID.1/// A protocol is an interface identified by a GUID.
2pub const protocols = @import("uefi/protocols.zig");2pub const protocols = @import("uefi/protocols.zig");
3
3/// Status codes returned by EFI interfaces4/// Status codes returned by EFI interfaces
4pub const status = @import("uefi/status.zig");5pub const status = @import("uefi/status.zig");
5pub const tables = @import("uefi/tables.zig");6pub const tables = @import("uefi/tables.zig");
67
7const fmt = @import("std").fmt;8const fmt = @import("std").fmt;
89
9const builtin = @import("builtin");
10pub const is_the_target = builtin.os == .uefi;
11
12/// The EFI image's handle that is passed to its entry point.10/// The EFI image's handle that is passed to its entry point.
13pub var handle: Handle = undefined;11pub var handle: Handle = undefined;
12
14/// A pointer to the EFI System Table that is passed to the EFI image's entry point.13/// A pointer to the EFI System Table that is passed to the EFI image's entry point.
15pub var system_table: *tables.SystemTable = undefined;14pub var system_table: *tables.SystemTable = undefined;
1615
...@@ -50,26 +49,35 @@ pub const Handle = *@OpaqueType();...@@ -50,26 +49,35 @@ pub const Handle = *@OpaqueType();
50pub const Time = extern struct {49pub const Time = extern struct {
51 /// 1900 - 999950 /// 1900 - 9999
52 year: u16,51 year: u16,
52
53 /// 1 - 1253 /// 1 - 12
54 month: u8,54 month: u8,
55
55 /// 1 - 3156 /// 1 - 31
56 day: u8,57 day: u8,
58
57 /// 0 - 2359 /// 0 - 23
58 hour: u8,60 hour: u8,
61
59 /// 0 - 5962 /// 0 - 59
60 minute: u8,63 minute: u8,
64
61 /// 0 - 5965 /// 0 - 59
62 second: u8,66 second: u8,
63 _pad1: u8,67 _pad1: u8,
68
64 /// 0 - 99999999969 /// 0 - 999999999
65 nanosecond: u32,70 nanosecond: u32,
71
66 /// The time's offset in minutes from UTC.72 /// The time's offset in minutes from UTC.
67 /// Allowed values are -1440 to 1440 or unspecified_timezone73 /// Allowed values are -1440 to 1440 or unspecified_timezone
68 timezone: i16,74 timezone: i16,
69 daylight: packed struct {75 daylight: packed struct {
70 _pad1: u6,76 _pad1: u6,
77
71 /// If true, the time has been adjusted for daylight savings time.78 /// If true, the time has been adjusted for daylight savings time.
72 in_daylight: bool,79 in_daylight: bool,
80
73 /// If true, the time is affected by daylight savings time.81 /// If true, the time is affected by daylight savings time.
74 adjust_daylight: bool,82 adjust_daylight: bool,
75 },83 },
...@@ -83,8 +91,10 @@ pub const Time = extern struct {...@@ -83,8 +91,10 @@ pub const Time = extern struct {
83pub const TimeCapabilities = extern struct {91pub const TimeCapabilities = extern struct {
84 /// Resolution in Hz92 /// Resolution in Hz
85 resolution: u32,93 resolution: u32,
94
86 /// Accuracy in an error rate of 1e-6 parts per million.95 /// Accuracy in an error rate of 1e-6 parts per million.
87 accuracy: u32,96 accuracy: u32,
97
88 /// If true, a time set operation clears the device's time below the resolution level.98 /// If true, a time set operation clears the device's time below the resolution level.
89 sets_to_zero: bool,99 sets_to_zero: bool,
90};100};
lib/std/os/wasi.zig-2
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h1// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h
2// and https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md2// and https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md
3const builtin = @import("builtin");
4const std = @import("std");3const std = @import("std");
5const assert = std.debug.assert;4const assert = std.debug.assert;
65
7pub const is_the_target = builtin.os == .wasi;
8pub usingnamespace @import("bits.zig");6pub usingnamespace @import("bits.zig");
97
10comptime {8comptime {
lib/std/os/windows.zig-27
...@@ -11,7 +11,6 @@ const assert = std.debug.assert;...@@ -11,7 +11,6 @@ const assert = std.debug.assert;
11const math = std.math;11const math = std.math;
12const maxInt = std.math.maxInt;12const maxInt = std.math.maxInt;
1313
14pub const is_the_target = builtin.os == .windows;
15pub const advapi32 = @import("windows/advapi32.zig");14pub const advapi32 = @import("windows/advapi32.zig");
16pub const kernel32 = @import("windows/kernel32.zig");15pub const kernel32 = @import("windows/kernel32.zig");
17pub const ntdll = @import("windows/ntdll.zig");16pub const ntdll = @import("windows/ntdll.zig");
...@@ -22,32 +21,6 @@ pub usingnamespace @import("windows/bits.zig");...@@ -22,32 +21,6 @@ pub usingnamespace @import("windows/bits.zig");
2221
23pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));22pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));
2423
25/// `builtin` is missing `subsystem` when the subsystem is automatically detected,
26/// so Zig standard library has the subsystem detection logic here. This should generally be
27/// used rather than `builtin.subsystem`.
28/// On non-windows targets, this is `null`.
29pub const subsystem: ?builtin.SubSystem = blk: {
30 if (@hasDecl(builtin, "subsystem")) break :blk builtin.subsystem;
31 switch (builtin.os) {
32 .windows => {
33 if (builtin.is_test) {
34 break :blk builtin.SubSystem.Console;
35 }
36 const root = @import("root");
37 if (@hasDecl(root, "WinMain") or
38 @hasDecl(root, "wWinMain") or
39 @hasDecl(root, "WinMainCRTStartup") or
40 @hasDecl(root, "wWinMainCRTStartup"))
41 {
42 break :blk builtin.SubSystem.Windows;
43 } else {
44 break :blk builtin.SubSystem.Console;
45 }
46 },
47 else => break :blk null,
48 }
49};
50
51pub const CreateFileError = error{24pub const CreateFileError = error{
52 SharingViolation,25 SharingViolation,
53 PathAlreadyExists,26 PathAlreadyExists,
lib/std/process.zig+2-2
...@@ -39,7 +39,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -39,7 +39,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
39 var result = BufMap.init(allocator);39 var result = BufMap.init(allocator);
40 errdefer result.deinit();40 errdefer result.deinit();
4141
42 if (os.windows.is_the_target) {42 if (builtin.os == .windows) {
43 const ptr = try os.windows.GetEnvironmentStringsW();43 const ptr = try os.windows.GetEnvironmentStringsW();
44 defer os.windows.FreeEnvironmentStringsW(ptr);44 defer os.windows.FreeEnvironmentStringsW(ptr);
4545
...@@ -129,7 +129,7 @@ pub const GetEnvVarOwnedError = error{...@@ -129,7 +129,7 @@ pub const GetEnvVarOwnedError = error{
129/// Caller must free returned memory.129/// Caller must free returned memory.
130/// TODO make this go through libc when we have it130/// TODO make this go through libc when we have it
131pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {131pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
132 if (os.windows.is_the_target) {132 if (builtin.os == .windows) {
133 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);133 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
134 defer allocator.free(key_with_null);134 defer allocator.free(key_with_null);
135135
lib/std/special/panic.zig deleted-31
...@@ -1,31 +0,0 @@
1// This file is the default panic handler if the root source file does not
2// have a `pub fn panic`.
3// If this file wants to import other files *by name*, support for that would
4// have to be added in the compiler.
5
6const builtin = @import("builtin");
7const std = @import("std");
8
9pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
10 @setCold(true);
11 switch (builtin.os) {
12 .freestanding => {
13 while (true) {
14 @breakpoint();
15 }
16 },
17 .wasi => {
18 std.debug.warn("{}", msg);
19 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
20 unreachable;
21 },
22 .uefi => {
23 // TODO look into using the debug info and logging helpful messages
24 std.os.abort();
25 },
26 else => {
27 const first_trace_addr = @returnAddress();
28 std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
29 },
30 }
31}
lib/std/std.zig+3-1
...@@ -22,11 +22,13 @@ pub const SpinLock = @import("spinlock.zig").SpinLock;...@@ -22,11 +22,13 @@ pub const SpinLock = @import("spinlock.zig").SpinLock;
22pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;22pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
23pub const StringHashMap = @import("hash_map.zig").StringHashMap;23pub const StringHashMap = @import("hash_map.zig").StringHashMap;
24pub const TailQueue = @import("linked_list.zig").TailQueue;24pub const TailQueue = @import("linked_list.zig").TailQueue;
25pub const Target = @import("target.zig").Target;
25pub const Thread = @import("thread.zig").Thread;26pub const Thread = @import("thread.zig").Thread;
2627
27pub const atomic = @import("atomic.zig");28pub const atomic = @import("atomic.zig");
28pub const base64 = @import("base64.zig");29pub const base64 = @import("base64.zig");
29pub const build = @import("build.zig");30pub const build = @import("build.zig");
31pub const builtin = @import("builtin.zig");
30pub const c = @import("c.zig");32pub const c = @import("c.zig");
31pub const coff = @import("coff.zig");33pub const coff = @import("coff.zig");
32pub const crypto = @import("crypto.zig");34pub const crypto = @import("crypto.zig");
...@@ -63,6 +65,6 @@ pub const unicode = @import("unicode.zig");...@@ -63,6 +65,6 @@ pub const unicode = @import("unicode.zig");
63pub const valgrind = @import("valgrind.zig");65pub const valgrind = @import("valgrind.zig");
64pub const zig = @import("zig.zig");66pub const zig = @import("zig.zig");
6567
66comptime {68test "" {
67 meta.refAllDecls(@This());69 meta.refAllDecls(@This());
68}70}
lib/std/target.zig created+617
...@@ -0,0 +1,617 @@
1const std = @import("std.zig");
2const builtin = std.builtin;
3
4/// TODO Nearly all the functions in this namespace would be
5/// better off if https://github.com/ziglang/zig/issues/425
6/// was solved.
7pub const Target = union(enum) {
8 Native: void,
9 Cross: Cross,
10
11 pub const Os = enum {
12 freestanding,
13 ananas,
14 cloudabi,
15 dragonfly,
16 freebsd,
17 fuchsia,
18 ios,
19 kfreebsd,
20 linux,
21 lv2,
22 macosx,
23 netbsd,
24 openbsd,
25 solaris,
26 windows,
27 haiku,
28 minix,
29 rtems,
30 nacl,
31 cnk,
32 aix,
33 cuda,
34 nvcl,
35 amdhsa,
36 ps4,
37 elfiamcu,
38 tvos,
39 watchos,
40 mesa3d,
41 contiki,
42 amdpal,
43 hermit,
44 hurd,
45 wasi,
46 emscripten,
47 zen,
48 uefi,
49 };
50
51 pub const Arch = union(enum) {
52 arm: Arm32,
53 armeb: Arm32,
54 aarch64: Arm64,
55 aarch64_be: Arm64,
56 aarch64_32: Arm64,
57 arc,
58 avr,
59 bpfel,
60 bpfeb,
61 hexagon,
62 mips,
63 mipsel,
64 mips64,
65 mips64el,
66 msp430,
67 powerpc,
68 powerpc64,
69 powerpc64le,
70 r600,
71 amdgcn,
72 riscv32,
73 riscv64,
74 sparc,
75 sparcv9,
76 sparcel,
77 s390x,
78 tce,
79 tcele,
80 thumb: Arm32,
81 thumbeb: Arm32,
82 i386,
83 x86_64,
84 xcore,
85 nvptx,
86 nvptx64,
87 le32,
88 le64,
89 amdil,
90 amdil64,
91 hsail,
92 hsail64,
93 spir,
94 spir64,
95 kalimba: Kalimba,
96 shave,
97 lanai,
98 wasm32,
99 wasm64,
100 renderscript32,
101 renderscript64,
102
103 pub const Arm32 = enum {
104 v8_5a,
105 v8_4a,
106 v8_3a,
107 v8_2a,
108 v8_1a,
109 v8,
110 v8r,
111 v8m_baseline,
112 v8m_mainline,
113 v8_1m_mainline,
114 v7,
115 v7em,
116 v7m,
117 v7s,
118 v7k,
119 v7ve,
120 v6,
121 v6m,
122 v6k,
123 v6t2,
124 v5,
125 v5te,
126 v4t,
127 };
128 pub const Arm64 = enum {
129 v8_5a,
130 v8_4a,
131 v8_3a,
132 v8_2a,
133 v8_1a,
134 v8,
135 v8r,
136 v8m_baseline,
137 v8m_mainline,
138 };
139 pub const Kalimba = enum {
140 v5,
141 v4,
142 v3,
143 };
144 pub const Mips = enum {
145 r6,
146 };
147 };
148
149 pub const Abi = enum {
150 none,
151 gnu,
152 gnuabin32,
153 gnuabi64,
154 gnueabi,
155 gnueabihf,
156 gnux32,
157 code16,
158 eabi,
159 eabihf,
160 elfv1,
161 elfv2,
162 android,
163 musl,
164 musleabi,
165 musleabihf,
166 msvc,
167 itanium,
168 cygnus,
169 coreclr,
170 simulator,
171 macabi,
172 };
173
174 pub const ObjectFormat = enum {
175 unknown,
176 coff,
177 elf,
178 macho,
179 wasm,
180 };
181
182 pub const SubSystem = enum {
183 Console,
184 Windows,
185 Posix,
186 Native,
187 EfiApplication,
188 EfiBootServiceDriver,
189 EfiRom,
190 EfiRuntimeDriver,
191 };
192
193 pub const Cross = struct {
194 arch: Arch,
195 os: Os,
196 abi: Abi,
197 };
198
199 pub const current = Target{
200 .Cross = Cross{
201 .arch = builtin.arch,
202 .os = builtin.os,
203 .abi = builtin.abi,
204 },
205 };
206
207 pub fn zigTriple(self: Target, allocator: *std.mem.Allocator) ![]u8 {
208 return std.fmt.allocPrint(
209 allocator,
210 "{}{}-{}-{}",
211 @tagName(self.getArch()),
212 Target.archSubArchName(self.getArch()),
213 @tagName(self.getOs()),
214 @tagName(self.getAbi()),
215 );
216 }
217
218 pub fn allocDescription(self: Target, allocator: *std.mem.Allocator) ![]u8 {
219 // TODO is there anything else worthy of the description that is not
220 // already captured in the triple?
221 return self.zigTriple(allocator);
222 }
223
224 pub fn zigTripleNoSubArch(self: Target, allocator: *std.mem.Allocator) ![]u8 {
225 return std.fmt.allocPrint(
226 allocator,
227 "{}-{}-{}",
228 @tagName(self.getArch()),
229 @tagName(self.getOs()),
230 @tagName(self.getAbi()),
231 );
232 }
233
234 pub fn linuxTriple(self: Target, allocator: *std.mem.Allocator) ![]u8 {
235 return std.fmt.allocPrint(
236 allocator,
237 "{}-{}-{}",
238 @tagName(self.getArch()),
239 @tagName(self.getOs()),
240 @tagName(self.getAbi()),
241 );
242 }
243
244 pub fn parse(text: []const u8) !Target {
245 var it = mem.separate(text, "-");
246 const arch_name = it.next() orelse return error.MissingArchitecture;
247 const os_name = it.next() orelse return error.MissingOperatingSystem;
248 const abi_name = it.next();
249
250 var cross = Cross{
251 .arch = try parseArchSub(arch_name),
252 .os = try parseOs(os_name),
253 .abi = undefined,
254 };
255 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
256 return Target{ .Cross = cross };
257 }
258
259 pub fn defaultAbi(arch: Arch, target_os: Os) Abi {
260 switch (arch) {
261 .wasm32, .wasm64 => return .musl,
262 else => {},
263 }
264 switch (target_os) {
265 .freestanding,
266 .ananas,
267 .cloudabi,
268 .dragonfly,
269 .lv2,
270 .solaris,
271 .haiku,
272 .minix,
273 .rtems,
274 .nacl,
275 .cnk,
276 .aix,
277 .cuda,
278 .nvcl,
279 .amdhsa,
280 .ps4,
281 .elfiamcu,
282 .mesa3d,
283 .contiki,
284 .amdpal,
285 .zen,
286 .hermit,
287 => return .eabi,
288 .openbsd,
289 .macosx,
290 .freebsd,
291 .ios,
292 .tvos,
293 .watchos,
294 .fuchsia,
295 .kfreebsd,
296 .netbsd,
297 .hurd,
298 => return .gnu,
299 .windows,
300 .uefi,
301 => return .msvc,
302 .linux,
303 .wasi,
304 .emscripten,
305 => return .musl,
306 }
307 }
308
309 pub const ParseArchSubError = error{
310 UnknownArchitecture,
311 UnknownSubArchitecture,
312 };
313
314 pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {
315 const info = @typeInfo(Arch);
316 inline for (info.Union.fields) |field| {
317 if (mem.eql(u8, text, field.name)) {
318 if (field.field_type == void) {
319 return (Arch)(@field(Arch, field.name));
320 } else {
321 const sub_info = @typeInfo(field.field_type);
322 inline for (sub_info.Enum.fields) |sub_field| {
323 const combined = field.name ++ sub_field.name;
324 if (mem.eql(u8, text, combined)) {
325 return @unionInit(Arch, field.name, @field(field.field_type, sub_field.name));
326 }
327 }
328 return error.UnknownSubArchitecture;
329 }
330 }
331 }
332 return error.UnknownArchitecture;
333 }
334
335 pub fn parseOs(text: []const u8) !Os {
336 const info = @typeInfo(Os);
337 inline for (info.Enum.fields) |field| {
338 if (mem.eql(u8, text, field.name)) {
339 return @field(Os, field.name);
340 }
341 }
342 return error.UnknownOperatingSystem;
343 }
344
345 pub fn parseAbi(text: []const u8) !Abi {
346 const info = @typeInfo(Abi);
347 inline for (info.Enum.fields) |field| {
348 if (mem.eql(u8, text, field.name)) {
349 return @field(Abi, field.name);
350 }
351 }
352 return error.UnknownApplicationBinaryInterface;
353 }
354
355 fn archSubArchName(arch: Arch) []const u8 {
356 return switch (arch) {
357 .arm => |sub| @tagName(sub),
358 .armeb => |sub| @tagName(sub),
359 .thumb => |sub| @tagName(sub),
360 .thumbeb => |sub| @tagName(sub),
361 .aarch64 => |sub| @tagName(sub),
362 .aarch64_be => |sub| @tagName(sub),
363 .kalimba => |sub| @tagName(sub),
364 else => "",
365 };
366 }
367
368 pub fn subArchName(self: Target) []const u8 {
369 switch (self) {
370 .Native => return archSubArchName(builtin.arch),
371 .Cross => |cross| return archSubArchName(cross.arch),
372 }
373 }
374
375 pub fn oFileExt(self: Target) []const u8 {
376 return switch (self.getAbi()) {
377 .msvc => ".obj",
378 else => ".o",
379 };
380 }
381
382 pub fn exeFileExt(self: Target) []const u8 {
383 if (self.isWindows()) {
384 return ".exe";
385 } else if (self.isUefi()) {
386 return ".efi";
387 } else if (self.isWasm()) {
388 return ".wasm";
389 } else {
390 return "";
391 }
392 }
393
394 pub fn staticLibSuffix(self: Target) []const u8 {
395 if (self.isWasm()) {
396 return ".wasm";
397 }
398 switch (self.getAbi()) {
399 .msvc => return ".lib",
400 else => return ".a",
401 }
402 }
403
404 pub fn dynamicLibSuffix(self: Target) []const u8 {
405 if (self.isDarwin()) {
406 return ".dylib";
407 }
408 switch (self.getOs()) {
409 .windows => return ".dll",
410 else => return ".so",
411 }
412 }
413
414 pub fn libPrefix(self: Target) []const u8 {
415 if (self.isWasm()) {
416 return "";
417 }
418 switch (self.getAbi()) {
419 .msvc => return "",
420 else => return "lib",
421 }
422 }
423
424 pub fn getOs(self: Target) Os {
425 return switch (self) {
426 .Native => builtin.os,
427 .Cross => |t| t.os,
428 };
429 }
430
431 pub fn getArch(self: Target) Arch {
432 switch (self) {
433 .Native => return builtin.arch,
434 .Cross => |t| return t.arch,
435 }
436 }
437
438 pub fn getAbi(self: Target) Abi {
439 switch (self) {
440 .Native => return builtin.abi,
441 .Cross => |t| return t.abi,
442 }
443 }
444
445 pub fn isMinGW(self: Target) bool {
446 return self.isWindows() and self.isGnu();
447 }
448
449 pub fn isGnu(self: Target) bool {
450 return switch (self.getAbi()) {
451 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
452 else => false,
453 };
454 }
455
456 pub fn isDarwin(self: Target) bool {
457 return switch (self.getOs()) {
458 .ios, .macosx, .watchos, .tvos => true,
459 else => false,
460 };
461 }
462
463 pub fn isWindows(self: Target) bool {
464 return switch (self.getOs()) {
465 .windows => true,
466 else => false,
467 };
468 }
469
470 pub fn isLinux(self: Target) bool {
471 return switch (self.getOs()) {
472 .linux => true,
473 else => false,
474 };
475 }
476
477 pub fn isUefi(self: Target) bool {
478 return switch (self.getOs()) {
479 .uefi => true,
480 else => false,
481 };
482 }
483
484 pub fn isWasm(self: Target) bool {
485 return switch (self.getArch()) {
486 .wasm32, .wasm64 => true,
487 else => false,
488 };
489 }
490
491 pub fn isFreeBSD(self: Target) bool {
492 return switch (self.getOs()) {
493 .freebsd => true,
494 else => false,
495 };
496 }
497
498 pub fn isNetBSD(self: Target) bool {
499 return switch (self.getOs()) {
500 .netbsd => true,
501 else => false,
502 };
503 }
504
505 pub fn wantSharedLibSymLinks(self: Target) bool {
506 return !self.isWindows();
507 }
508
509 pub fn osRequiresLibC(self: Target) bool {
510 return self.isDarwin() or self.isFreeBSD() or self.isNetBSD();
511 }
512
513 pub fn getArchPtrBitWidth(self: Target) u32 {
514 switch (self.getArch()) {
515 .avr,
516 .msp430,
517 => return 16,
518
519 .arc,
520 .arm,
521 .armeb,
522 .hexagon,
523 .le32,
524 .mips,
525 .mipsel,
526 .powerpc,
527 .r600,
528 .riscv32,
529 .sparc,
530 .sparcel,
531 .tce,
532 .tcele,
533 .thumb,
534 .thumbeb,
535 .i386,
536 .xcore,
537 .nvptx,
538 .amdil,
539 .hsail,
540 .spir,
541 .kalimba,
542 .shave,
543 .lanai,
544 .wasm32,
545 .renderscript32,
546 .aarch64_32,
547 => return 32,
548
549 .aarch64,
550 .aarch64_be,
551 .mips64,
552 .mips64el,
553 .powerpc64,
554 .powerpc64le,
555 .riscv64,
556 .x86_64,
557 .nvptx64,
558 .le64,
559 .amdil64,
560 .hsail64,
561 .spir64,
562 .wasm64,
563 .renderscript64,
564 .amdgcn,
565 .bpfel,
566 .bpfeb,
567 .sparcv9,
568 .s390x,
569 => return 64,
570 }
571 }
572
573 pub const Executor = union(enum) {
574 native,
575 qemu: []const u8,
576 wine: []const u8,
577 unavailable,
578 };
579
580 pub fn getExternalExecutor(self: Target) Executor {
581 if (@TagType(Target)(self) == .Native) return .native;
582
583 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
584 if (self.getOs() == builtin.os) {
585 return switch (self.getArch()) {
586 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
587 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
588 .arm => Executor{ .qemu = "qemu-arm" },
589 .armeb => Executor{ .qemu = "qemu-armeb" },
590 .i386 => Executor{ .qemu = "qemu-i386" },
591 .mips => Executor{ .qemu = "qemu-mips" },
592 .mipsel => Executor{ .qemu = "qemu-mipsel" },
593 .mips64 => Executor{ .qemu = "qemu-mips64" },
594 .mips64el => Executor{ .qemu = "qemu-mips64el" },
595 .powerpc => Executor{ .qemu = "qemu-ppc" },
596 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
597 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
598 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
599 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
600 .s390x => Executor{ .qemu = "qemu-s390x" },
601 .sparc => Executor{ .qemu = "qemu-sparc" },
602 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
603 else => return .unavailable,
604 };
605 }
606
607 if (self.isWindows()) {
608 switch (self.getArchPtrBitWidth()) {
609 32 => return Executor{ .wine = "wine" },
610 64 => return Executor{ .wine = "wine64" },
611 else => return .unavailable,
612 }
613 }
614
615 return .unavailable;
616 }
617};
lib/std/thread.zig+5-5
...@@ -9,7 +9,7 @@ const assert = std.debug.assert;...@@ -9,7 +9,7 @@ const assert = std.debug.assert;
9pub const Thread = struct {9pub const Thread = struct {
10 data: Data,10 data: Data,
1111
12 pub const use_pthreads = !windows.is_the_target and builtin.link_libc;12 pub const use_pthreads = builtin.os != .windows and builtin.link_libc;
1313
14 /// Represents a kernel thread handle.14 /// Represents a kernel thread handle.
15 /// May be an integer or a pointer depending on the platform.15 /// May be an integer or a pointer depending on the platform.
...@@ -309,7 +309,7 @@ pub const Thread = struct {...@@ -309,7 +309,7 @@ pub const Thread = struct {
309 os.EINVAL => unreachable,309 os.EINVAL => unreachable,
310 else => return os.unexpectedErrno(@intCast(usize, err)),310 else => return os.unexpectedErrno(@intCast(usize, err)),
311 }311 }
312 } else if (os.linux.is_the_target) {312 } else if (builtin.os == .linux) {
313 var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |313 var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |
314 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |314 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
315 os.CLONE_DETACHED;315 os.CLONE_DETACHED;
...@@ -342,18 +342,18 @@ pub const Thread = struct {...@@ -342,18 +342,18 @@ pub const Thread = struct {
342 };342 };
343343
344 pub fn cpuCount() CpuCountError!usize {344 pub fn cpuCount() CpuCountError!usize {
345 if (os.linux.is_the_target) {345 if (builtin.os == .linux) {
346 const cpu_set = try os.sched_getaffinity(0);346 const cpu_set = try os.sched_getaffinity(0);
347 return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast347 return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
348 }348 }
349 if (os.windows.is_the_target) {349 if (builtin.os == .windows) {
350 var system_info: windows.SYSTEM_INFO = undefined;350 var system_info: windows.SYSTEM_INFO = undefined;
351 windows.kernel32.GetSystemInfo(&system_info);351 windows.kernel32.GetSystemInfo(&system_info);
352 return @intCast(usize, system_info.dwNumberOfProcessors);352 return @intCast(usize, system_info.dwNumberOfProcessors);
353 }353 }
354 var count: c_int = undefined;354 var count: c_int = undefined;
355 var count_len: usize = @sizeOf(c_int);355 var count_len: usize = @sizeOf(c_int);
356 const name = if (os.darwin.is_the_target) c"hw.logicalcpu" else c"hw.ncpu";356 const name = if (comptime std.Target.current.isDarwin()) c"hw.logicalcpu" else c"hw.ncpu";
357 os.sysctlbynameC(name, &count, &count_len, null, 0) catch |err| switch (err) {357 os.sysctlbynameC(name, &count, &count_len, null, 0) catch |err| switch (err) {
358 error.NameTooLong => unreachable,358 error.NameTooLong => unreachable,
359 else => |e| return e,359 else => |e| return e,
lib/std/time.zig+10-10
...@@ -9,7 +9,7 @@ pub const epoch = @import("time/epoch.zig");...@@ -9,7 +9,7 @@ pub const epoch = @import("time/epoch.zig");
99
10/// Spurious wakeups are possible and no precision of timing is guaranteed.10/// Spurious wakeups are possible and no precision of timing is guaranteed.
11pub fn sleep(nanoseconds: u64) void {11pub fn sleep(nanoseconds: u64) void {
12 if (os.windows.is_the_target) {12 if (builtin.os == .windows) {
13 const ns_per_ms = ns_per_s / ms_per_s;13 const ns_per_ms = ns_per_s / ms_per_s;
14 const big_ms_from_ns = nanoseconds / ns_per_ms;14 const big_ms_from_ns = nanoseconds / ns_per_ms;
15 const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD);15 const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD);
...@@ -30,7 +30,7 @@ pub fn timestamp() u64 {...@@ -30,7 +30,7 @@ pub fn timestamp() u64 {
30/// Get the posix timestamp, UTC, in milliseconds30/// Get the posix timestamp, UTC, in milliseconds
31/// TODO audit this function. is it possible to return an error?31/// TODO audit this function. is it possible to return an error?
32pub fn milliTimestamp() u64 {32pub fn milliTimestamp() u64 {
33 if (os.windows.is_the_target) {33 if (builtin.os == .windows) {
34 //FileTime has a granularity of 100 nanoseconds34 //FileTime has a granularity of 100 nanoseconds
35 // and uses the NTFS/Windows epoch35 // and uses the NTFS/Windows epoch
36 var ft: os.windows.FILETIME = undefined;36 var ft: os.windows.FILETIME = undefined;
...@@ -41,7 +41,7 @@ pub fn milliTimestamp() u64 {...@@ -41,7 +41,7 @@ pub fn milliTimestamp() u64 {
41 const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;41 const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
42 return @divFloor(ft64, hns_per_ms) - -epoch_adj;42 return @divFloor(ft64, hns_per_ms) - -epoch_adj;
43 }43 }
44 if (os.wasi.is_the_target and !builtin.link_libc) {44 if (builtin.os == .wasi and !builtin.link_libc) {
45 var ns: os.wasi.timestamp_t = undefined;45 var ns: os.wasi.timestamp_t = undefined;
4646
47 // TODO: Verify that precision is ignored47 // TODO: Verify that precision is ignored
...@@ -51,7 +51,7 @@ pub fn milliTimestamp() u64 {...@@ -51,7 +51,7 @@ pub fn milliTimestamp() u64 {
51 const ns_per_ms = 1000;51 const ns_per_ms = 1000;
52 return @divFloor(ns, ns_per_ms);52 return @divFloor(ns, ns_per_ms);
53 }53 }
54 if (os.darwin.is_the_target) {54 if (comptime std.Target.current.isDarwin()) {
55 var tv: os.darwin.timeval = undefined;55 var tv: os.darwin.timeval = undefined;
56 var err = os.darwin.gettimeofday(&tv, null);56 var err = os.darwin.gettimeofday(&tv, null);
57 assert(err == 0);57 assert(err == 0);
...@@ -126,11 +126,11 @@ pub const Timer = struct {...@@ -126,11 +126,11 @@ pub const Timer = struct {
126 pub fn start() Error!Timer {126 pub fn start() Error!Timer {
127 var self: Timer = undefined;127 var self: Timer = undefined;
128128
129 if (os.windows.is_the_target) {129 if (builtin.os == .windows) {
130 self.frequency = os.windows.QueryPerformanceFrequency();130 self.frequency = os.windows.QueryPerformanceFrequency();
131 self.resolution = @divFloor(ns_per_s, self.frequency);131 self.resolution = @divFloor(ns_per_s, self.frequency);
132 self.start_time = os.windows.QueryPerformanceCounter();132 self.start_time = os.windows.QueryPerformanceCounter();
133 } else if (os.darwin.is_the_target) {133 } else if (comptime std.Target.current.isDarwin()) {
134 os.darwin.mach_timebase_info(&self.frequency);134 os.darwin.mach_timebase_info(&self.frequency);
135 self.resolution = @divFloor(self.frequency.numer, self.frequency.denom);135 self.resolution = @divFloor(self.frequency.numer, self.frequency.denom);
136 self.start_time = os.darwin.mach_absolute_time();136 self.start_time = os.darwin.mach_absolute_time();
...@@ -154,10 +154,10 @@ pub const Timer = struct {...@@ -154,10 +154,10 @@ pub const Timer = struct {
154 /// Reads the timer value since start or the last reset in nanoseconds154 /// Reads the timer value since start or the last reset in nanoseconds
155 pub fn read(self: *Timer) u64 {155 pub fn read(self: *Timer) u64 {
156 var clock = clockNative() - self.start_time;156 var clock = clockNative() - self.start_time;
157 if (os.windows.is_the_target) {157 if (builtin.os == .windows) {
158 return @divFloor(clock * ns_per_s, self.frequency);158 return @divFloor(clock * ns_per_s, self.frequency);
159 }159 }
160 if (os.darwin.is_the_target) {160 if (comptime std.Target.current.isDarwin()) {
161 return @divFloor(clock * self.frequency.numer, self.frequency.denom);161 return @divFloor(clock * self.frequency.numer, self.frequency.denom);
162 }162 }
163 return clock;163 return clock;
...@@ -177,10 +177,10 @@ pub const Timer = struct {...@@ -177,10 +177,10 @@ pub const Timer = struct {
177 }177 }
178178
179 fn clockNative() u64 {179 fn clockNative() u64 {
180 if (os.windows.is_the_target) {180 if (builtin.os == .windows) {
181 return os.windows.QueryPerformanceCounter();181 return os.windows.QueryPerformanceCounter();
182 }182 }
183 if (os.darwin.is_the_target) {183 if (comptime std.Target.current.isDarwin()) {
184 return os.darwin.mach_absolute_time();184 return os.darwin.mach_absolute_time();
185 }185 }
186 var ts: os.timespec = undefined;186 var ts: os.timespec = undefined;
src-self-hosted/target.zig+2
...@@ -3,6 +3,8 @@ const builtin = @import("builtin");...@@ -3,6 +3,8 @@ const builtin = @import("builtin");
3const llvm = @import("llvm.zig");3const llvm = @import("llvm.zig");
4const CInt = @import("c_int.zig").CInt;4const CInt = @import("c_int.zig").CInt;
55
6// TODO delete this file and use std.Target
7
6pub const FloatAbi = enum {8pub const FloatAbi = enum {
7 Hard,9 Hard,
8 Soft,10 Soft,
src/all_types.hpp-3
...@@ -1930,7 +1930,6 @@ struct CodeGen {...@@ -1930,7 +1930,6 @@ struct CodeGen {
1930 ZigList<ZigType *> type_resolve_stack;1930 ZigList<ZigType *> type_resolve_stack;
19311931
1932 ZigPackage *std_package;1932 ZigPackage *std_package;
1933 ZigPackage *panic_package;
1934 ZigPackage *test_runner_package;1933 ZigPackage *test_runner_package;
1935 ZigPackage *compile_var_package;1934 ZigPackage *compile_var_package;
1936 ZigType *compile_var_import;1935 ZigType *compile_var_import;
...@@ -2006,7 +2005,6 @@ struct CodeGen {...@@ -2006,7 +2005,6 @@ struct CodeGen {
2006 ZigFn *cur_fn;2005 ZigFn *cur_fn;
2007 ZigFn *main_fn;2006 ZigFn *main_fn;
2008 ZigFn *panic_fn;2007 ZigFn *panic_fn;
2009 TldFn *panic_tld_fn;
20102008
2011 ZigFn *largest_frame_fn;2009 ZigFn *largest_frame_fn;
20122010
...@@ -2030,7 +2028,6 @@ struct CodeGen {...@@ -2030,7 +2028,6 @@ struct CodeGen {
2030 bool have_winmain;2028 bool have_winmain;
2031 bool have_winmain_crt_startup;2029 bool have_winmain_crt_startup;
2032 bool have_dllmain_crt_startup;2030 bool have_dllmain_crt_startup;
2033 bool have_pub_panic;
2034 bool have_err_ret_tracing;2031 bool have_err_ret_tracing;
2035 bool c_want_stdint;2032 bool c_want_stdint;
2036 bool c_want_stdbool;2033 bool c_want_stdbool;
src/analyze.cpp+62-27
...@@ -3232,21 +3232,6 @@ static bool scope_is_root_decls(Scope *scope) {...@@ -3232,21 +3232,6 @@ static bool scope_is_root_decls(Scope *scope) {
3232 zig_unreachable();3232 zig_unreachable();
3233}3233}
32343234
3235void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) {
3236 ConstExprValue *panic_fn_type_val = get_builtin_value(g, "PanicFn");
3237 assert(panic_fn_type_val != nullptr);
3238 assert(panic_fn_type_val->type->id == ZigTypeIdMetaType);
3239 ZigType *panic_fn_type = panic_fn_type_val->data.x_type;
3240
3241 AstNode *fake_decl = allocate<AstNode>(1);
3242 *fake_decl = *panic_fn->proto_node;
3243 fake_decl->type = NodeTypeSymbol;
3244 fake_decl->data.symbol_expr.symbol = tld_fn->base.name;
3245
3246 // call this for the side effects of casting to panic_fn_type
3247 analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr, UndefBad);
3248}
3249
3250ZigType *get_test_fn_type(CodeGen *g) {3235ZigType *get_test_fn_type(CodeGen *g) {
3251 if (g->test_fn_type)3236 if (g->test_fn_type)
3252 return g->test_fn_type;3237 return g->test_fn_type;
...@@ -3356,16 +3341,9 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3356,16 +3341,9 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3356 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;3341 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
3357 }3342 }
33583343
3359 if (scope_is_root_decls(tld_fn->base.parent_scope) &&3344 if (scope_is_root_decls(tld_fn->base.parent_scope) && import == g->root_import) {
3360 (import == g->root_import || import->data.structure.root_struct->package == g->panic_package))
3361 {
3362 if (g->have_pub_main && buf_eql_str(tld_fn->base.name, "main")) {3345 if (g->have_pub_main && buf_eql_str(tld_fn->base.name, "main")) {
3363 g->main_fn = fn_table_entry;3346 g->main_fn = fn_table_entry;
3364 } else if ((import->data.structure.root_struct->package == g->panic_package || g->have_pub_panic) &&
3365 buf_eql_str(tld_fn->base.name, "panic"))
3366 {
3367 g->panic_fn = fn_table_entry;
3368 g->panic_tld_fn = tld_fn;
3369 }3347 }
3370 }3348 }
3371 } else if (source_node->type == NodeTypeTestDecl) {3349 } else if (source_node->type == NodeTypeTestDecl) {
...@@ -4710,8 +4688,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu...@@ -4710,8 +4688,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
4710 ast_print(stderr, root_node, 0);4688 ast_print(stderr, root_node, 0);
4711 }4689 }
47124690
4713 if (source_kind == SourceKindRoot || package == g->panic_package) {4691 if (source_kind == SourceKindRoot) {
4714 // Look for panic and main4692 // Look for main
4715 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {4693 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
4716 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);4694 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
47174695
...@@ -4724,8 +4702,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu...@@ -4724,8 +4702,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
4724 if (is_pub) {4702 if (is_pub) {
4725 if (buf_eql_str(proto_name, "main")) {4703 if (buf_eql_str(proto_name, "main")) {
4726 g->have_pub_main = true;4704 g->have_pub_main = true;
4727 } else if (buf_eql_str(proto_name, "panic")) {
4728 g->have_pub_panic = true;
4729 }4705 }
4730 }4706 }
4731 }4707 }
...@@ -8932,3 +8908,62 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node,...@@ -8932,3 +8908,62 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node,
8932 return &alloca_gen->base;8908 return &alloca_gen->base;
8933}8909}
89348910
8911Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
8912 ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path)
8913{
8914 Error err;
8915
8916 Buf *search_dir;
8917 ZigPackage *cur_scope_pkg = source_import->data.structure.root_struct->package;
8918 assert(cur_scope_pkg);
8919 ZigPackage *target_package;
8920 auto package_entry = cur_scope_pkg->package_table.maybe_get(import_target_str);
8921 SourceKind source_kind;
8922 if (package_entry) {
8923 target_package = package_entry->value;
8924 *out_import_target_path = &target_package->root_src_path;
8925 search_dir = &target_package->root_src_dir;
8926 source_kind = SourceKindPkgMain;
8927 } else {
8928 // try it as a filename
8929 target_package = cur_scope_pkg;
8930 *out_import_target_path = import_target_str;
8931
8932 // search relative to importing file
8933 search_dir = buf_alloc();
8934 os_path_dirname(source_import->data.structure.root_struct->path, search_dir);
8935
8936 source_kind = SourceKindNonRoot;
8937 }
8938
8939 buf_resize(out_full_path, 0);
8940 os_path_join(search_dir, *out_import_target_path, out_full_path);
8941
8942 Buf *import_code = buf_alloc();
8943 Buf *resolved_path = buf_alloc();
8944
8945 Buf *resolve_paths[] = { out_full_path, };
8946 *resolved_path = os_path_resolve(resolve_paths, 1);
8947
8948 auto import_entry = g->import_table.maybe_get(resolved_path);
8949 if (import_entry) {
8950 *out_import = import_entry->value;
8951 return ErrorNone;
8952 }
8953
8954 if (source_kind == SourceKindNonRoot) {
8955 Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir;
8956 Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
8957 if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) {
8958 return ErrorImportOutsidePkgPath;
8959 }
8960 }
8961
8962 if ((err = file_fetch(g, resolved_path, import_code))) {
8963 return err;
8964 }
8965
8966 *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);
8967 return ErrorNone;
8968}
8969
src/analyze.hpp+2
...@@ -262,5 +262,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn);...@@ -262,5 +262,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn);
262262
263IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,263IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
264 ZigType *var_type, const char *name_hint);264 ZigType *var_type, const char *name_hint);
265Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str,
266 ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path);
265267
266#endif268#endif
src/codegen.cpp+67-357
...@@ -8125,55 +8125,37 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8125,55 +8125,37 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8125 g->have_err_ret_tracing = detect_err_ret_tracing(g);8125 g->have_err_ret_tracing = detect_err_ret_tracing(g);
81268126
8127 Buf *contents = buf_alloc();8127 Buf *contents = buf_alloc();
81288128 buf_appendf(contents, "usingnamespace @import(\"std\").builtin;\n\n");
8129 // NOTE: when editing this file, you may need to make modifications to the
8130 // cache input parameters in define_builtin_compile_vars
8131
8132 // Modifications to this struct must be coordinated with code that does anything with
8133 // g->stack_trace_type. There are hard-coded references to the field indexes.
8134 buf_append_str(contents,
8135 "pub const StackTrace = struct {\n"
8136 " index: usize,\n"
8137 " instruction_addresses: []usize,\n"
8138 "};\n\n");
8139
8140 buf_append_str(contents, "pub const PanicFn = fn([]const u8, ?*StackTrace) noreturn;\n\n");
81418129
8142 const char *cur_os = nullptr;8130 const char *cur_os = nullptr;
8143 {8131 {
8144 buf_appendf(contents, "pub const Os = enum {\n");
8145 uint32_t field_count = (uint32_t)target_os_count();8132 uint32_t field_count = (uint32_t)target_os_count();
8146 for (uint32_t i = 0; i < field_count; i += 1) {8133 for (uint32_t i = 0; i < field_count; i += 1) {
8147 Os os_type = target_os_enum(i);8134 Os os_type = target_os_enum(i);
8148 const char *name = target_os_name(os_type);8135 const char *name = target_os_name(os_type);
8149 buf_appendf(contents, " %s,\n", name);
81508136
8151 if (os_type == g->zig_target->os) {8137 if (os_type == g->zig_target->os) {
8152 g->target_os_index = i;8138 g->target_os_index = i;
8153 cur_os = name;8139 cur_os = name;
8154 }8140 }
8155 }8141 }
8156 buf_appendf(contents, "};\n\n");
8157 }8142 }
8158 assert(cur_os != nullptr);8143 assert(cur_os != nullptr);
81598144
8160 const char *cur_arch = nullptr;8145 const char *cur_arch = nullptr;
8161 {8146 {
8162 buf_appendf(contents, "pub const Arch = union(enum) {\n");
8163 uint32_t field_count = (uint32_t)target_arch_count();8147 uint32_t field_count = (uint32_t)target_arch_count();
8164 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) {8148 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) {
8165 ZigLLVM_ArchType arch = target_arch_enum(arch_i);8149 ZigLLVM_ArchType arch = target_arch_enum(arch_i);
8166 const char *arch_name = target_arch_name(arch);8150 const char *arch_name = target_arch_name(arch);
8167 SubArchList sub_arch_list = target_subarch_list(arch);8151 SubArchList sub_arch_list = target_subarch_list(arch);
8168 if (sub_arch_list == SubArchListNone) {8152 if (sub_arch_list == SubArchListNone) {
8169 buf_appendf(contents, " %s,\n", arch_name);
8170 if (arch == g->zig_target->arch) {8153 if (arch == g->zig_target->arch) {
8171 g->target_arch_index = arch_i;8154 g->target_arch_index = arch_i;
8172 cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name));8155 cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name));
8173 }8156 }
8174 } else {8157 } else {
8175 const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list);8158 const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list);
8176 buf_appendf(contents, " %s: %s,\n", arch_name, sub_arch_list_name);
8177 if (arch == g->zig_target->arch) {8159 if (arch == g->zig_target->arch) {
8178 size_t sub_count = target_subarch_count(sub_arch_list);8160 size_t sub_count = target_subarch_count(sub_arch_list);
8179 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {8161 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
...@@ -8187,50 +8169,30 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8187,50 +8169,30 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8187 }8169 }
8188 }8170 }
8189 }8171 }
8190
8191 uint32_t list_count = target_subarch_list_count();
8192 // start at index 1 to skip None
8193 for (uint32_t list_i = 1; list_i < list_count; list_i += 1) {
8194 SubArchList sub_arch_list = target_subarch_list_enum(list_i);
8195 const char *subarch_list_name = target_subarch_list_name(sub_arch_list);
8196 buf_appendf(contents, " pub const %s = enum {\n", subarch_list_name);
8197 size_t sub_count = target_subarch_count(sub_arch_list);
8198 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
8199 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
8200 buf_appendf(contents, " %s,\n", target_subarch_name(sub));
8201 }
8202 buf_appendf(contents, " };\n");
8203 }
8204 buf_appendf(contents, "};\n\n");
8205 }8172 }
8206 assert(cur_arch != nullptr);8173 assert(cur_arch != nullptr);
82078174
8208 const char *cur_abi = nullptr;8175 const char *cur_abi = nullptr;
8209 {8176 {
8210 buf_appendf(contents, "pub const Abi = enum {\n");
8211 uint32_t field_count = (uint32_t)target_abi_count();8177 uint32_t field_count = (uint32_t)target_abi_count();
8212 for (uint32_t i = 0; i < field_count; i += 1) {8178 for (uint32_t i = 0; i < field_count; i += 1) {
8213 ZigLLVM_EnvironmentType abi = target_abi_enum(i);8179 ZigLLVM_EnvironmentType abi = target_abi_enum(i);
8214 const char *name = target_abi_name(abi);8180 const char *name = target_abi_name(abi);
8215 buf_appendf(contents, " %s,\n", name);
82168181
8217 if (abi == g->zig_target->abi) {8182 if (abi == g->zig_target->abi) {
8218 g->target_abi_index = i;8183 g->target_abi_index = i;
8219 cur_abi = name;8184 cur_abi = name;
8220 }8185 }
8221 }8186 }
8222 buf_appendf(contents, "};\n\n");
8223 }8187 }
8224 assert(cur_abi != nullptr);8188 assert(cur_abi != nullptr);
82258189
8226 const char *cur_obj_fmt = nullptr;8190 const char *cur_obj_fmt = nullptr;
8227 {8191 {
8228 buf_appendf(contents, "pub const ObjectFormat = enum {\n");
8229 uint32_t field_count = (uint32_t)target_oformat_count();8192 uint32_t field_count = (uint32_t)target_oformat_count();
8230 for (uint32_t i = 0; i < field_count; i += 1) {8193 for (uint32_t i = 0; i < field_count; i += 1) {
8231 ZigLLVM_ObjectFormatType oformat = target_oformat_enum(i);8194 ZigLLVM_ObjectFormatType oformat = target_oformat_enum(i);
8232 const char *name = target_oformat_name(oformat);8195 const char *name = target_oformat_name(oformat);
8233 buf_appendf(contents, " %s,\n", name);
82348196
8235 ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target);8197 ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target);
8236 if (oformat == target_oformat) {8198 if (oformat == target_oformat) {
...@@ -8239,311 +8201,39 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8239,311 +8201,39 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8239 }8201 }
8240 }8202 }
82418203
8242 buf_appendf(contents, "};\n\n");
8243 }8204 }
8244 assert(cur_obj_fmt != nullptr);8205 assert(cur_obj_fmt != nullptr);
82458206
8246 {8207 // If any of these asserts trip then you need to either fix the internal compiler enum
8247 buf_appendf(contents, "pub const GlobalLinkage = enum {\n");8208 // or the corresponding one in std.Target or std.builtin.
8248 uint32_t field_count = array_length(global_linkage_values);8209 static_assert(ContainerLayoutAuto == 0, "");
8249 for (uint32_t i = 0; i < field_count; i += 1) {8210 static_assert(ContainerLayoutExtern == 1, "");
8250 const GlobalLinkageValue *value = &global_linkage_values[i];8211 static_assert(ContainerLayoutPacked == 2, "");
8251 buf_appendf(contents, " %s,\n", value->name);8212
8252 }8213 static_assert(CallingConventionUnspecified == 0, "");
8253 buf_appendf(contents, "};\n\n");8214 static_assert(CallingConventionC == 1, "");
8254 }8215 static_assert(CallingConventionCold == 2, "");
8255 {8216 static_assert(CallingConventionNaked == 3, "");
8256 buf_appendf(contents,8217 static_assert(CallingConventionStdcall == 4, "");
8257 "pub const AtomicOrder = enum {\n"8218 static_assert(CallingConventionAsync == 5, "");
8258 " Unordered,\n"8219
8259 " Monotonic,\n"8220 static_assert(FnInlineAuto == 0, "");
8260 " Acquire,\n"8221 static_assert(FnInlineAlways == 1, "");
8261 " Release,\n"8222 static_assert(FnInlineNever == 2, "");
8262 " AcqRel,\n"8223
8263 " SeqCst,\n"8224 static_assert(BuiltinPtrSizeOne == 0, "");
8264 "};\n\n");8225 static_assert(BuiltinPtrSizeMany == 1, "");
8265 }8226 static_assert(BuiltinPtrSizeSlice == 2, "");
8266 {8227 static_assert(BuiltinPtrSizeC == 3, "");
8267 buf_appendf(contents,8228
8268 "pub const AtomicRmwOp = enum {\n"8229 static_assert(TargetSubsystemConsole == 0, "");
8269 " Xchg,\n"8230 static_assert(TargetSubsystemWindows == 1, "");
8270 " Add,\n"8231 static_assert(TargetSubsystemPosix == 2, "");
8271 " Sub,\n"8232 static_assert(TargetSubsystemNative == 3, "");
8272 " And,\n"8233 static_assert(TargetSubsystemEfiApplication == 4, "");
8273 " Nand,\n"8234 static_assert(TargetSubsystemEfiBootServiceDriver == 5, "");
8274 " Or,\n"8235 static_assert(TargetSubsystemEfiRom == 6, "");
8275 " Xor,\n"8236 static_assert(TargetSubsystemEfiRuntimeDriver == 7, "");
8276 " Max,\n"
8277 " Min,\n"
8278 "};\n\n");
8279 }
8280 {
8281 buf_appendf(contents,
8282 "pub const Mode = enum {\n"
8283 " Debug,\n"
8284 " ReleaseSafe,\n"
8285 " ReleaseFast,\n"
8286 " ReleaseSmall,\n"
8287 "};\n\n");
8288 }
8289 {
8290 buf_appendf(contents, "pub const TypeId = enum {\n");
8291 size_t field_count = type_id_len();
8292 for (size_t i = 0; i < field_count; i += 1) {
8293 const ZigTypeId id = type_id_at_index(i);
8294 buf_appendf(contents, " %s,\n", type_id_name(id));
8295 }
8296 buf_appendf(contents, "};\n\n");
8297 }
8298 {
8299 buf_appendf(contents,
8300 "pub const TypeInfo = union(TypeId) {\n"
8301 " Type: void,\n"
8302 " Void: void,\n"
8303 " Bool: void,\n"
8304 " NoReturn: void,\n"
8305 " Int: Int,\n"
8306 " Float: Float,\n"
8307 " Pointer: Pointer,\n"
8308 " Array: Array,\n"
8309 " Struct: Struct,\n"
8310 " ComptimeFloat: void,\n"
8311 " ComptimeInt: void,\n"
8312 " Undefined: void,\n"
8313 " Null: void,\n"
8314 " Optional: Optional,\n"
8315 " ErrorUnion: ErrorUnion,\n"
8316 " ErrorSet: ErrorSet,\n"
8317 " Enum: Enum,\n"
8318 " Union: Union,\n"
8319 " Fn: Fn,\n"
8320 " BoundFn: Fn,\n"
8321 " ArgTuple: void,\n"
8322 " Opaque: void,\n"
8323 " Frame: void,\n"
8324 " AnyFrame: AnyFrame,\n"
8325 " Vector: Vector,\n"
8326 " EnumLiteral: void,\n"
8327 "\n\n"
8328 " pub const Int = struct {\n"
8329 " is_signed: bool,\n"
8330 " bits: comptime_int,\n"
8331 " };\n"
8332 "\n"
8333 " pub const Float = struct {\n"
8334 " bits: comptime_int,\n"
8335 " };\n"
8336 "\n"
8337 " pub const Pointer = struct {\n"
8338 " size: Size,\n"
8339 " is_const: bool,\n"
8340 " is_volatile: bool,\n"
8341 " alignment: comptime_int,\n"
8342 " child: type,\n"
8343 " is_allowzero: bool,\n"
8344 "\n"
8345 " pub const Size = enum {\n"
8346 " One,\n"
8347 " Many,\n"
8348 " Slice,\n"
8349 " C,\n"
8350 " };\n"
8351 " };\n"
8352 "\n"
8353 " pub const Array = struct {\n"
8354 " len: comptime_int,\n"
8355 " child: type,\n"
8356 " };\n"
8357 "\n"
8358 " pub const ContainerLayout = enum {\n"
8359 " Auto,\n"
8360 " Extern,\n"
8361 " Packed,\n"
8362 " };\n"
8363 "\n"
8364 " pub const StructField = struct {\n"
8365 " name: []const u8,\n"
8366 " offset: ?comptime_int,\n"
8367 " field_type: type,\n"
8368 " };\n"
8369 "\n"
8370 " pub const Struct = struct {\n"
8371 " layout: ContainerLayout,\n"
8372 " fields: []StructField,\n"
8373 " decls: []Declaration,\n"
8374 " };\n"
8375 "\n"
8376 " pub const Optional = struct {\n"
8377 " child: type,\n"
8378 " };\n"
8379 "\n"
8380 " pub const ErrorUnion = struct {\n"
8381 " error_set: type,\n"
8382 " payload: type,\n"
8383 " };\n"
8384 "\n"
8385 " pub const Error = struct {\n"
8386 " name: []const u8,\n"
8387 " value: comptime_int,\n"
8388 " };\n"
8389 "\n"
8390 " pub const ErrorSet = ?[]Error;\n"
8391 "\n"
8392 " pub const EnumField = struct {\n"
8393 " name: []const u8,\n"
8394 " value: comptime_int,\n"
8395 " };\n"
8396 "\n"
8397 " pub const Enum = struct {\n"
8398 " layout: ContainerLayout,\n"
8399 " tag_type: type,\n"
8400 " fields: []EnumField,\n"
8401 " decls: []Declaration,\n"
8402 " };\n"
8403 "\n"
8404 " pub const UnionField = struct {\n"
8405 " name: []const u8,\n"
8406 " enum_field: ?EnumField,\n"
8407 " field_type: type,\n"
8408 " };\n"
8409 "\n"
8410 " pub const Union = struct {\n"
8411 " layout: ContainerLayout,\n"
8412 " tag_type: ?type,\n"
8413 " fields: []UnionField,\n"
8414 " decls: []Declaration,\n"
8415 " };\n"
8416 "\n"
8417 " pub const CallingConvention = enum {\n"
8418 " Unspecified,\n"
8419 " C,\n"
8420 " Cold,\n"
8421 " Naked,\n"
8422 " Stdcall,\n"
8423 " Async,\n"
8424 " };\n"
8425 "\n"
8426 " pub const FnArg = struct {\n"
8427 " is_generic: bool,\n"
8428 " is_noalias: bool,\n"
8429 " arg_type: ?type,\n"
8430 " };\n"
8431 "\n"
8432 " pub const Fn = struct {\n"
8433 " calling_convention: CallingConvention,\n"
8434 " is_generic: bool,\n"
8435 " is_var_args: bool,\n"
8436 " return_type: ?type,\n"
8437 " args: []FnArg,\n"
8438 " };\n"
8439 "\n"
8440 " pub const AnyFrame = struct {\n"
8441 " child: ?type,\n"
8442 " };\n"
8443 "\n"
8444 " pub const Vector = struct {\n"
8445 " len: comptime_int,\n"
8446 " child: type,\n"
8447 " };\n"
8448 "\n"
8449 " pub const Declaration = struct {\n"
8450 " name: []const u8,\n"
8451 " is_pub: bool,\n"
8452 " data: Data,\n"
8453 "\n"
8454 " pub const Data = union(enum) {\n"
8455 " Type: type,\n"
8456 " Var: type,\n"
8457 " Fn: FnDecl,\n"
8458 "\n"
8459 " pub const FnDecl = struct {\n"
8460 " fn_type: type,\n"
8461 " inline_type: Inline,\n"
8462 " calling_convention: CallingConvention,\n"
8463 " is_var_args: bool,\n"
8464 " is_extern: bool,\n"
8465 " is_export: bool,\n"
8466 " lib_name: ?[]const u8,\n"
8467 " return_type: type,\n"
8468 " arg_names: [][] const u8,\n"
8469 "\n"
8470 " pub const Inline = enum {\n"
8471 " Auto,\n"
8472 " Always,\n"
8473 " Never,\n"
8474 " };\n"
8475 " };\n"
8476 " };\n"
8477 " };\n"
8478 "};\n\n");
8479 static_assert(ContainerLayoutAuto == 0, "");
8480 static_assert(ContainerLayoutExtern == 1, "");
8481 static_assert(ContainerLayoutPacked == 2, "");
8482
8483 static_assert(CallingConventionUnspecified == 0, "");
8484 static_assert(CallingConventionC == 1, "");
8485 static_assert(CallingConventionCold == 2, "");
8486 static_assert(CallingConventionNaked == 3, "");
8487 static_assert(CallingConventionStdcall == 4, "");
8488 static_assert(CallingConventionAsync == 5, "");
8489
8490 static_assert(FnInlineAuto == 0, "");
8491 static_assert(FnInlineAlways == 1, "");
8492 static_assert(FnInlineNever == 2, "");
8493
8494 static_assert(BuiltinPtrSizeOne == 0, "");
8495 static_assert(BuiltinPtrSizeMany == 1, "");
8496 static_assert(BuiltinPtrSizeSlice == 2, "");
8497 static_assert(BuiltinPtrSizeC == 3, "");
8498 }
8499 {
8500 buf_appendf(contents,
8501 "pub const FloatMode = enum {\n"
8502 " Strict,\n"
8503 " Optimized,\n"
8504 "};\n\n");
8505 assert(FloatModeStrict == 0);
8506 assert(FloatModeOptimized == 1);
8507 }
8508 {
8509 buf_appendf(contents,
8510 "pub const Endian = enum {\n"
8511 " Big,\n"
8512 " Little,\n"
8513 "};\n\n");
8514 //assert(EndianBig == 0);
8515 //assert(EndianLittle == 1);
8516 }
8517 {
8518 buf_appendf(contents,
8519 "pub const Version = struct {\n"
8520 " major: u32,\n"
8521 " minor: u32,\n"
8522 " patch: u32,\n"
8523 "};\n\n");
8524 }
8525 {
8526 buf_appendf(contents,
8527 "pub const SubSystem = enum {\n"
8528 " Console,\n"
8529 " Windows,\n"
8530 " Posix,\n"
8531 " Native,\n"
8532 " EfiApplication,\n"
8533 " EfiBootServiceDriver,\n"
8534 " EfiRom,\n"
8535 " EfiRuntimeDriver,\n"
8536 "};\n\n");
8537
8538 assert(TargetSubsystemConsole == 0);
8539 assert(TargetSubsystemWindows == 1);
8540 assert(TargetSubsystemPosix == 2);
8541 assert(TargetSubsystemNative == 3);
8542 assert(TargetSubsystemEfiApplication == 4);
8543 assert(TargetSubsystemEfiBootServiceDriver == 5);
8544 assert(TargetSubsystemEfiRom == 6);
8545 assert(TargetSubsystemEfiRuntimeDriver == 7);
8546 }
8547 {8237 {
8548 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";8238 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
8549 buf_appendf(contents, "pub const endian = %s;\n", endian_str);8239 buf_appendf(contents, "pub const endian = %s;\n", endian_str);
...@@ -8573,7 +8263,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8573,7 +8263,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8573 {8263 {
8574 TargetSubsystem detected_subsystem = detect_subsystem(g);8264 TargetSubsystem detected_subsystem = detect_subsystem(g);
8575 if (detected_subsystem != TargetSubsystemAuto) {8265 if (detected_subsystem != TargetSubsystemAuto) {
8576 buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));8266 buf_appendf(contents, "pub const explicit_subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
8577 }8267 }
8578 }8268 }
85798269
...@@ -8594,10 +8284,6 @@ static ZigPackage *create_test_runner_pkg(CodeGen *g) {...@@ -8594,10 +8284,6 @@ static ZigPackage *create_test_runner_pkg(CodeGen *g) {
8594 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "test_runner.zig", "std.special");8284 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "test_runner.zig", "std.special");
8595}8285}
85968286
8597static ZigPackage *create_panic_pkg(CodeGen *g) {
8598 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "panic.zig", "std.special");
8599}
8600
8601static Error define_builtin_compile_vars(CodeGen *g) {8287static Error define_builtin_compile_vars(CodeGen *g) {
8602 if (g->std_package == nullptr)8288 if (g->std_package == nullptr)
8603 return ErrorNone;8289 return ErrorNone;
...@@ -8679,6 +8365,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -8679,6 +8365,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
8679 assert(g->root_package);8365 assert(g->root_package);
8680 assert(g->std_package);8366 assert(g->std_package);
8681 g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin");8367 g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin");
8368 g->compile_var_package->package_table.put(buf_create_from_str("std"), g->std_package);
8682 g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);8369 g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
8683 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);8370 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
8684 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);8371 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
...@@ -9377,16 +9064,43 @@ static void gen_root_source(CodeGen *g) {...@@ -9377,16 +9064,43 @@ static void gen_root_source(CodeGen *g) {
93779064
9378 if (!g->is_dummy_so) {9065 if (!g->is_dummy_so) {
9379 // Zig has lazy top level definitions. Here we semantically analyze the panic function.9066 // Zig has lazy top level definitions. Here we semantically analyze the panic function.
9380 ZigType *import_with_panic;9067 Buf *import_target_path;
9381 if (g->have_pub_panic) {9068 Buf full_path = BUF_INIT;
9382 import_with_panic = g->root_import;9069 ZigType *std_import;
9383 } else {9070 if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import,
9384 g->panic_package = create_panic_pkg(g);9071 &import_target_path, &full_path)))
9385 import_with_panic = add_special_code(g, g->panic_package, "panic.zig");9072 {
9073 if (err == ErrorFileNotFound) {
9074 fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path));
9075 } else {
9076 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err));
9077 }
9078 exit(1);
9386 }9079 }
9387 Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic"));9080
9081 Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base,
9082 buf_create_from_str("builtin"));
9083 assert(builtin_tld != nullptr);
9084 resolve_top_level_decl(g, builtin_tld, nullptr, false);
9085 report_errors_and_maybe_exit(g);
9086 assert(builtin_tld->id == TldIdVar);
9087 TldVar *builtin_tld_var = (TldVar*)builtin_tld;
9088 ConstExprValue *builtin_val = builtin_tld_var->var->const_value;
9089 assert(builtin_val->type->id == ZigTypeIdMetaType);
9090 ZigType *builtin_type = builtin_val->data.x_type;
9091
9092 Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base,
9093 buf_create_from_str("panic"));
9388 assert(panic_tld != nullptr);9094 assert(panic_tld != nullptr);
9389 resolve_top_level_decl(g, panic_tld, nullptr, false);9095 resolve_top_level_decl(g, panic_tld, nullptr, false);
9096 report_errors_and_maybe_exit(g);
9097 assert(panic_tld->id == TldIdVar);
9098 TldVar *panic_tld_var = (TldVar*)panic_tld;
9099 ConstExprValue *panic_fn_val = panic_tld_var->var->const_value;
9100 assert(panic_fn_val->type->id == ZigTypeIdFn);
9101 assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction);
9102 g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry;
9103 assert(g->panic_fn != nullptr);
9390 }9104 }
93919105
93929106
...@@ -9416,10 +9130,6 @@ static void gen_root_source(CodeGen *g) {...@@ -9416,10 +9130,6 @@ static void gen_root_source(CodeGen *g) {
9416 }9130 }
9417 }9131 }
94189132
9419 if (!g->is_dummy_so) {
9420 typecheck_panic_fn(g, g->panic_tld_fn, g->panic_fn);
9421 }
9422
9423 report_errors_and_maybe_exit(g);9133 report_errors_and_maybe_exit(g);
94249134
9425}9135}
src/error.cpp+1
...@@ -57,6 +57,7 @@ const char *err_str(Error err) {...@@ -57,6 +57,7 @@ const char *err_str(Error err) {
57 case ErrorNoCCompilerInstalled: return "no C compiler installed";57 case ErrorNoCCompilerInstalled: return "no C compiler installed";
58 case ErrorNotLazy: return "not lazy";58 case ErrorNotLazy: return "not lazy";
59 case ErrorIsAsync: return "is async";59 case ErrorIsAsync: return "is async";
60 case ErrorImportOutsidePkgPath: return "import of file outside package path";
60 }61 }
61 return "(invalid error)";62 return "(invalid error)";
62}63}
src/ir.cpp+6-47
...@@ -19589,57 +19589,18 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio...@@ -19589,57 +19589,18 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio
19589 AstNode *source_node = import_instruction->base.source_node;19589 AstNode *source_node = import_instruction->base.source_node;
19590 ZigType *import = source_node->owner;19590 ZigType *import = source_node->owner;
1959119591
19592 ZigType *target_import;
19592 Buf *import_target_path;19593 Buf *import_target_path;
19593 Buf *search_dir;
19594 assert(import->data.structure.root_struct->package);
19595 ZigPackage *target_package;
19596 auto package_entry = import->data.structure.root_struct->package->package_table.maybe_get(import_target_str);
19597 SourceKind source_kind;
19598 if (package_entry) {
19599 target_package = package_entry->value;
19600 import_target_path = &target_package->root_src_path;
19601 search_dir = &target_package->root_src_dir;
19602 source_kind = SourceKindPkgMain;
19603 } else {
19604 // try it as a filename
19605 target_package = import->data.structure.root_struct->package;
19606 import_target_path = import_target_str;
19607
19608 // search relative to importing file
19609 search_dir = buf_alloc();
19610 os_path_dirname(import->data.structure.root_struct->path, search_dir);
19611
19612 source_kind = SourceKindNonRoot;
19613 }
19614
19615 Buf full_path = BUF_INIT;19594 Buf full_path = BUF_INIT;
19616 os_path_join(search_dir, import_target_path, &full_path);19595 if ((err = analyze_import(ira->codegen, import, import_target_str, &target_import,
1961719596 &import_target_path, &full_path)))
19618 Buf *import_code = buf_alloc();19597 {
19619 Buf *resolved_path = buf_alloc();19598 if (err == ErrorImportOutsidePkgPath) {
19620
19621 Buf *resolve_paths[] = { &full_path, };
19622 *resolved_path = os_path_resolve(resolve_paths, 1);
19623
19624 auto import_entry = ira->codegen->import_table.maybe_get(resolved_path);
19625 if (import_entry) {
19626 return ir_const_type(ira, &import_instruction->base, import_entry->value);
19627 }
19628
19629 if (source_kind == SourceKindNonRoot) {
19630 ZigPackage *cur_scope_pkg = scope_package(import_instruction->base.scope);
19631 Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir;
19632 Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
19633 if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) {
19634 ir_add_error_node(ira, source_node,19599 ir_add_error_node(ira, source_node,
19635 buf_sprintf("import of file outside package path: '%s'",19600 buf_sprintf("import of file outside package path: '%s'",
19636 buf_ptr(import_target_path)));19601 buf_ptr(import_target_path)));
19637 return ira->codegen->invalid_instruction;19602 return ira->codegen->invalid_instruction;
19638 }19603 } else if (err == ErrorFileNotFound) {
19639 }
19640
19641 if ((err = file_fetch(ira->codegen, resolved_path, import_code))) {
19642 if (err == ErrorFileNotFound) {
19643 ir_add_error_node(ira, source_node,19604 ir_add_error_node(ira, source_node,
19644 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));19605 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
19645 return ira->codegen->invalid_instruction;19606 return ira->codegen->invalid_instruction;
...@@ -19650,8 +19611,6 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio...@@ -19650,8 +19611,6 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio
19650 }19611 }
19651 }19612 }
1965219613
19653 ZigType *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code, source_kind);
19654
19655 return ir_const_type(ira, &import_instruction->base, target_import);19614 return ir_const_type(ira, &import_instruction->base, target_import);
19656}19615}
1965719616
src/userland.h+1
...@@ -77,6 +77,7 @@ enum Error {...@@ -77,6 +77,7 @@ enum Error {
77 ErrorNoSpaceLeft,77 ErrorNoSpaceLeft,
78 ErrorNotLazy,78 ErrorNotLazy,
79 ErrorIsAsync,79 ErrorIsAsync,
80 ErrorImportOutsidePkgPath,
80};81};
8182
82// ABI warning83// ABI warning
test/compile_errors.zig+18-13
...@@ -64,7 +64,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -64,7 +64,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64 \\ _ = @Type(0);64 \\ _ = @Type(0);
65 \\}65 \\}
66 ,66 ,
67 "tmp.zig:2:15: error: expected type 'builtin.TypeInfo', found 'comptime_int'",67 "tmp.zig:2:15: error: expected type 'std.builtin.TypeInfo', found 'comptime_int'",
68 );68 );
6969
70 cases.add(70 cases.add(
...@@ -88,7 +88,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -88,7 +88,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
88 \\ });88 \\ });
89 \\}89 \\}
90 ,90 ,
91 "tmp.zig:3:36: error: expected type 'builtin.TypeInfo', found 'builtin.Int'",91 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",
92 );92 );
9393
94 cases.add(94 cases.add(
...@@ -806,7 +806,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -806,7 +806,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
806 \\pub fn panic() void {}806 \\pub fn panic() void {}
807 \\807 \\
808 ,808 ,
809 "tmp.zig:3:5: error: expected type 'fn([]const u8, ?*builtin.StackTrace) noreturn', found 'fn() void'",809 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn() void'",
810 );810 );
811811
812 cases.add(812 cases.add(
...@@ -815,8 +815,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -815,8 +815,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
815 \\ while (true) {}815 \\ while (true) {}
816 \\}816 \\}
817 ,817 ,
818 "tmp.zig:1:5: error: expected type 'fn([]const u8, ?*builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'",818 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'",
819 "tmp.zig:1:5: note: only one of the functions is generic",819 "note: only one of the functions is generic",
820 );820 );
821821
822 cases.add(822 cases.add(
...@@ -1473,7 +1473,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1473,7 +1473,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1473 \\ const field = @typeInfo(Struct).Struct.fields[index];1473 \\ const field = @typeInfo(Struct).Struct.fields[index];
1474 \\}1474 \\}
1475 ,1475 ,
1476 "tmp.zig:9:51: error: values of type 'builtin.StructField' must be comptime known, but index value is runtime known",1476 "tmp.zig:9:51: error: values of type 'std.builtin.StructField' must be comptime known, but index value is runtime known",
1477 );1477 );
14781478
1479 cases.add(1479 cases.add(
...@@ -3743,13 +3743,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3743,13 +3743,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3743 );3743 );
37443744
3745 cases.add(3745 cases.add(
3746 "missing function name and param name",3746 "missing function name",
3747 \\fn () void {}3747 \\fn () void {}
3748 \\fn f(i32) void {}
3749 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }3748 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
3750 ,3749 ,
3751 "tmp.zig:1:1: error: missing function name",3750 "tmp.zig:1:1: error: missing function name",
3752 "tmp.zig:2:6: error: missing parameter name",3751 );
3752
3753 cases.add(
3754 "missing param name",
3755 \\fn f(i32) void {}
3756 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
3757 ,
3758 "tmp.zig:1:6: error: missing parameter name",
3753 );3759 );
37543760
3755 cases.add(3761 cases.add(
...@@ -3782,7 +3788,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3782,7 +3788,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3782 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }3788 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }
3783 ,3789 ,
3784 "tmp.zig:2:1: error: redefinition of 'func'",3790 "tmp.zig:2:1: error: redefinition of 'func'",
3785 "tmp.zig:1:11: error: use of undeclared identifier 'bogus'",
3786 );3791 );
37873792
3788 cases.add(3793 cases.add(
...@@ -5086,7 +5091,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5086,7 +5091,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5086 \\ const foo = builtin.Arch.x86;5091 \\ const foo = builtin.Arch.x86;
5087 \\}5092 \\}
5088 ,5093 ,
5089 "tmp.zig:3:29: error: container 'builtin.Arch' has no member called 'x86'",5094 "tmp.zig:3:29: error: container 'std.target.Arch' has no member called 'x86'",
5090 );5095 );
50915096
5092 cases.add(5097 cases.add(
...@@ -5731,7 +5736,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5731,7 +5736,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5731 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}5736 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}
5732 \\}5737 \\}
5733 ,5738 ,
5734 "tmp.zig:3:50: error: expected type 'builtin.AtomicOrder', found 'u32'",5739 "tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
5735 );5740 );
57365741
5737 cases.add(5742 cases.add(
...@@ -5741,7 +5746,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5741,7 +5746,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5741 \\ @export("entry", entry, u32(1234));5746 \\ @export("entry", entry, u32(1234));
5742 \\}5747 \\}
5743 ,5748 ,
5744 "tmp.zig:3:32: error: expected type 'builtin.GlobalLinkage', found 'u32'",5749 "tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
5745 );5750 );
57465751
5747 cases.add(5752 cases.add(