mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Apple's own headers and tbd files prefer to think of Mac Catalyst as a distinct OS target. Earlier, when DriverKit support was added to LLVM, it was represented a distinct OS. So why Apple decided to only represent Mac Catalyst as an ABI in the target triple is beyond me. But this isn't the first time they've ignored established target triple norms (see: armv7k and aarch64_32) and it probably won't be the last. While doing this, I also audited all Darwin OS prongs throughout the codebase and made sure they cover all the tags.
307 lines
12 KiB
Zig
307 lines
12 KiB
Zig
const builtin = @import("builtin");
|
|
const std = @import("std");
|
|
const expect = std.testing.expect;
|
|
|
|
fn add(args: anytype) i32 {
|
|
var sum = @as(i32, 0);
|
|
{
|
|
comptime var i: usize = 0;
|
|
inline while (i < args.len) : (i += 1) {
|
|
sum += args[i];
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
test "add arbitrary args" {
|
|
try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
|
|
try expect(add(.{@as(i32, 1234)}) == 1234);
|
|
try expect(add(.{}) == 0);
|
|
}
|
|
|
|
fn readFirstVarArg(args: anytype) void {
|
|
_ = args[0];
|
|
}
|
|
|
|
test "send void arg to var args" {
|
|
readFirstVarArg(.{{}});
|
|
}
|
|
|
|
test "pass args directly" {
|
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
|
|
|
try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
|
|
try expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);
|
|
try expect(addSomeStuff(.{}) == 0);
|
|
}
|
|
|
|
fn addSomeStuff(args: anytype) i32 {
|
|
return add(args);
|
|
}
|
|
|
|
test "runtime parameter before var args" {
|
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
|
|
|
try expect((try extraFn(10, .{})) == 0);
|
|
try expect((try extraFn(10, .{false})) == 1);
|
|
try expect((try extraFn(10, .{ false, true })) == 2);
|
|
|
|
comptime {
|
|
try expect((try extraFn(10, .{})) == 0);
|
|
try expect((try extraFn(10, .{false})) == 1);
|
|
try expect((try extraFn(10, .{ false, true })) == 2);
|
|
}
|
|
}
|
|
|
|
fn extraFn(extra: u32, args: anytype) !usize {
|
|
_ = extra;
|
|
if (args.len >= 1) {
|
|
try expect(args[0] == false);
|
|
}
|
|
if (args.len >= 2) {
|
|
try expect(args[1] == true);
|
|
}
|
|
return args.len;
|
|
}
|
|
|
|
const foos = [_]fn (anytype) bool{
|
|
foo1,
|
|
foo2,
|
|
};
|
|
|
|
fn foo1(args: anytype) bool {
|
|
_ = args;
|
|
return true;
|
|
}
|
|
fn foo2(args: anytype) bool {
|
|
_ = args;
|
|
return false;
|
|
}
|
|
|
|
test "array of var args functions" {
|
|
try expect(foos[0](.{}));
|
|
try expect(!foos[1](.{}));
|
|
}
|
|
|
|
test "pass zero length array to var args param" {
|
|
doNothingWithFirstArg(.{""});
|
|
}
|
|
|
|
fn doNothingWithFirstArg(args: anytype) void {
|
|
_ = args[0];
|
|
}
|
|
|
|
test "simple variadic function" {
|
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_llvm and !builtin.os.tag.isDarwin() and builtin.cpu.arch.isAARCH64()) {
|
|
// https://github.com/ziglang/zig/issues/14096
|
|
return error.SkipZigTest;
|
|
}
|
|
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; // TODO
|
|
if (builtin.cpu.arch == .s390x and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21350
|
|
if (builtin.cpu.arch.isSPARC() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23718
|
|
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25064
|
|
|
|
const S = struct {
|
|
fn simple(...) callconv(.c) c_int {
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
return @cVaArg(&ap, c_int);
|
|
}
|
|
|
|
fn compatible(_: c_int, ...) callconv(.c) c_int {
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
return @cVaArg(&ap, c_int);
|
|
}
|
|
|
|
fn add(count: c_int, ...) callconv(.c) c_int {
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
var i: usize = 0;
|
|
var sum: c_int = 0;
|
|
while (i < count) : (i += 1) {
|
|
sum += @cVaArg(&ap, c_int);
|
|
}
|
|
return sum;
|
|
}
|
|
};
|
|
|
|
if (builtin.zig_backend != .stage2_c) {
|
|
// pre C23 doesn't support varargs without a preceding runtime arg.
|
|
try std.testing.expectEqual(@as(c_int, 0), S.simple(@as(c_int, 0)));
|
|
try std.testing.expectEqual(@as(c_int, 1024), S.simple(@as(c_int, 1024)));
|
|
}
|
|
try std.testing.expectEqual(@as(c_int, 0), S.compatible(undefined, @as(c_int, 0)));
|
|
try std.testing.expectEqual(@as(c_int, 1024), S.compatible(undefined, @as(c_int, 1024)));
|
|
try std.testing.expectEqual(@as(c_int, 0), S.add(0));
|
|
try std.testing.expectEqual(@as(c_int, 1), S.add(1, @as(c_int, 1)));
|
|
try std.testing.expectEqual(@as(c_int, 3), S.add(2, @as(c_int, 1), @as(c_int, 2)));
|
|
|
|
{
|
|
// Test type coercion of a var args argument.
|
|
// Originally reported at https://github.com/ziglang/zig/issues/16197
|
|
var runtime: bool = true;
|
|
var a: i32 = 1;
|
|
var b: i32 = 2;
|
|
_ = .{ &runtime, &a, &b };
|
|
try expect(1 == S.add(1, if (runtime) a else b));
|
|
}
|
|
}
|
|
|
|
test "coerce reference to var arg" {
|
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_llvm and !builtin.os.tag.isDarwin() and builtin.cpu.arch.isAARCH64()) {
|
|
// https://github.com/ziglang/zig/issues/14096
|
|
return error.SkipZigTest;
|
|
}
|
|
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; // TODO
|
|
if (builtin.cpu.arch == .s390x and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21350
|
|
|
|
const S = struct {
|
|
fn addPtr(count: c_int, ...) callconv(.c) c_int {
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
var i: usize = 0;
|
|
var sum: c_int = 0;
|
|
while (i < count) : (i += 1) {
|
|
sum += @cVaArg(&ap, *c_int).*;
|
|
}
|
|
return sum;
|
|
}
|
|
};
|
|
|
|
// Originally reported at https://github.com/ziglang/zig/issues/17494
|
|
var a: i32 = 12;
|
|
var b: i32 = 34;
|
|
try expect(46 == S.addPtr(2, &a, &b));
|
|
}
|
|
|
|
test "variadic functions" {
|
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_llvm and !builtin.os.tag.isDarwin() and builtin.cpu.arch.isAARCH64()) {
|
|
// https://github.com/ziglang/zig/issues/14096
|
|
return error.SkipZigTest;
|
|
}
|
|
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; // TODO
|
|
if (builtin.cpu.arch == .s390x and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21350
|
|
if (builtin.cpu.arch.isSPARC() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23718
|
|
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25064
|
|
|
|
const S = struct {
|
|
fn printf(buffer: [*]u8, format: [*:0]const u8, ...) callconv(.c) void {
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
vprintf(buffer, format, &ap);
|
|
}
|
|
|
|
fn vprintf(buffer: [*]u8, format: [*:0]const u8, ap: *std.builtin.VaList) callconv(.c) void {
|
|
var i: usize = 0;
|
|
for (format[0..3]) |byte| switch (byte) {
|
|
's' => {
|
|
const arg = @cVaArg(ap, [*:0]const u8);
|
|
buffer[i..][0..5].* = arg[0..5].*;
|
|
i += 5;
|
|
},
|
|
'd' => {
|
|
const arg = @cVaArg(ap, c_int);
|
|
switch (arg) {
|
|
1 => {
|
|
buffer[i] = '1';
|
|
i += 1;
|
|
},
|
|
5 => {
|
|
buffer[i] = '5';
|
|
i += 1;
|
|
},
|
|
else => unreachable,
|
|
}
|
|
},
|
|
else => unreachable,
|
|
};
|
|
}
|
|
};
|
|
|
|
var buffer: [7]u8 = undefined;
|
|
S.printf(&buffer, "dsd", @as(c_int, 1), @as([*:0]const u8, "hello"), @as(c_int, 5));
|
|
try expect(std.mem.eql(u8, &buffer, "1hello5"));
|
|
}
|
|
|
|
test "copy VaList" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_llvm and !builtin.os.tag.isDarwin() and builtin.cpu.arch.isAARCH64()) {
|
|
// https://github.com/ziglang/zig/issues/14096
|
|
return error.SkipZigTest;
|
|
}
|
|
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; // TODO
|
|
if (builtin.cpu.arch == .s390x and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21350
|
|
if (builtin.cpu.arch.isSPARC() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23718
|
|
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25064
|
|
|
|
const S = struct {
|
|
fn add(count: c_int, ...) callconv(.c) c_int {
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
var copy = @cVaCopy(&ap);
|
|
defer @cVaEnd(©);
|
|
var i: usize = 0;
|
|
var sum: c_int = 0;
|
|
while (i < count) : (i += 1) {
|
|
sum += @cVaArg(&ap, c_int);
|
|
sum += @cVaArg(©, c_int) * 2;
|
|
}
|
|
return sum;
|
|
}
|
|
};
|
|
|
|
try std.testing.expectEqual(@as(c_int, 0), S.add(0));
|
|
try std.testing.expectEqual(@as(c_int, 3), S.add(1, @as(c_int, 1)));
|
|
try std.testing.expectEqual(@as(c_int, 9), S.add(2, @as(c_int, 1), @as(c_int, 2)));
|
|
}
|
|
|
|
test "unused VaList arg" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_llvm and !builtin.os.tag.isDarwin() and builtin.cpu.arch.isAARCH64()) {
|
|
// https://github.com/ziglang/zig/issues/14096
|
|
return error.SkipZigTest;
|
|
}
|
|
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) {
|
|
// https://github.com/ziglang/zig/issues/16961
|
|
return error.SkipZigTest; // TODO
|
|
}
|
|
if (builtin.cpu.arch == .s390x and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21350
|
|
if (builtin.cpu.arch.isSPARC() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23718
|
|
if (builtin.cpu.arch.isRISCV() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25064
|
|
|
|
const S = struct {
|
|
fn thirdArg(dummy: c_int, ...) callconv(.c) c_int {
|
|
_ = dummy;
|
|
|
|
var ap = @cVaStart();
|
|
defer @cVaEnd(&ap);
|
|
|
|
_ = @cVaArg(&ap, c_int);
|
|
return @cVaArg(&ap, c_int);
|
|
}
|
|
};
|
|
const x = S.thirdArg(0, @as(c_int, 1), @as(c_int, 2));
|
|
try std.testing.expectEqual(@as(c_int, 2), x);
|
|
}
|