2024-03-24 08:58:05 -06:00

491 lines
13 KiB
Plaintext

const std = #import("std");
const expect = std.testing.expect;
const run_c_tests :: extern = fn cc(.c) () void;
const has_i128 = false;
const main = fn () *!void {
run_c_tests();
c_u8(0xff);
c_u16(0xfffe);
c_u32(0xfffffffd);
c_u64(0xfffffffffffffffc);
if (has_i128) {
c_struct_u128(.{ .value = 0xfffffffffffffffc, });
}
c_s8(-1);
c_s16(-2);
c_s32(-3);
c_s64(-4);
if (has_i128) {
c_struct_i128(.{ .value = -6, });
}
c_bool(true);
c_five_integers(12, 34, 56, 78, 90);
const s = c_ret_struct_u64_u64();
try expect(s.a == 21);
try expect(s.b == 22);
c_struct_u64_u64_0(.{ .a = 23, .b = 24, });
c_struct_u64_u64_1(0, .{ .a = 25, .b = 26, });
c_struct_u64_u64_2(0, 1, .{ .a = 27, .b = 28, });
c_struct_u64_u64_3(0, 1, 2, .{ .a = 29, .b = 30, });
c_struct_u64_u64_4(0, 1, 2, 3, .{ .a = 31, .b = 32, });
c_struct_u64_u64_5(0, 1, 2, 3, 4, .{ .a = 33, .b = 34, });
c_struct_u64_u64_6(0, 1, 2, 3, 4, 5, .{ .a = 35, .b = 36, });
c_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, .{ .a = 37, .b = 38, });
c_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, .{ .a = 39, .b = 40, });
const big_struct = BigStruct{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
.e = 5,
};
c_big_struct(big_struct);
const small = SmallStructInts{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
};
c_small_struct_ints(small);
const small2 = c_ret_small_struct_ints();
try expect(small2.a == 1);
try expect(small2.b == 2);
try expect(small2.c == 3);
try expect(small2.d == 4);
const med = MedStructInts{
.x = 1,
.y = 2,
.z = 3,
};
c_med_struct_ints(med);
const med2 = c_ret_med_struct_ints();
try expect(med2.x == 1);
try expect(med2.y == 2);
try expect(med2.z == 3);
const p = SmallPackedStruct{ .a = 0, .b = 1, .c = 2, .d = 3, };
c_small_packed_struct(p);
const p2 = c_ret_small_packed_struct();
try expect(p2.a == 0);
try expect(p2.b == 1);
try expect(p2.c == 2);
try expect(p2.d == 3);
const split = SplitStructInt{
.a = 1234,
.b = 100,
.c = 1337,
};
c_split_struct_ints(split);
const big = BigStruct{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
.e = 5,
};
const big2 = c_big_struct_both(big);
try expect(big2.a == 10);
try expect(big2.b == 11);
try expect(big2.c == 12);
try expect(big2.d == 13);
try expect(big2.e == 14);
const r1 = Rect{
.left = 1,
.right = 21,
.top = 16,
.bottom = 4,
};
const r2 = Rect{
.left = 178,
.right = 189,
.top = 21,
.bottom = 15,
};
c_multiple_struct_ints(r1, r2);
try expect(c_ret_bool() == true);
try expect(c_ret_u8() == 0xff);
try expect(c_ret_u16() == 0xffff);
try expect(c_ret_u32() == 0xffffffff);
try expect(c_ret_u64() == 0xffffffffffffffff);
try expect(c_ret_s8() == -1);
try expect(c_ret_s16() == -1);
try expect(c_ret_s32() == -1);
try expect(c_ret_s64() == -1);
c_struct_with_array(.{ .a = 1, .padding = undefined, .b = 2, });
const x = c_ret_struct_with_array();
try expect(x.a == 4);
try expect(x.b == 155);
const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined, });
try expect(res.val == 42);
var function_pointer = c_func_ptr_byval.&;
function_pointer(1, 2, .{ .origin = .{ .x = 9, .y = 10, .z = 11, }, .size = .{ .width = 12, .height = 13, .depth = 14, }, }, 3, 4, 5);
}
const ByRef = struct {
val: s32,
arr: [15]s32,
};
const ByVal = struct {
origin: ByValOrigin,
size: ByValSize,
};
const ByValOrigin = struct{
x: u64,
y: u64,
z: u64,
};
const ByValSize = struct{
width: u64,
height: u64,
depth: u64,
};
const c_u8 :: extern = fn cc(.c) (x: u8) void;
const c_u16 :: extern = fn cc(.c) (x: u16) void;
const c_u32 :: extern = fn cc(.c) (x: u32) void;
const c_u64 :: extern = fn cc(.c) (x: u64) void;
const c_s8 :: extern = fn cc(.c) (x: s8) void;
const c_s16 :: extern = fn cc(.c) (x: s16) void;
const c_s32 :: extern = fn cc(.c) (x: s32) void;
const c_s64 :: extern = fn cc(.c) (x: s64) void;
const c_bool :: extern = fn cc(.c) (x: bool) void;
const c_five_integers :: extern = fn cc(.c) (a: s32, b: s32, c: s32, d: s32, e: s32) void;
const c_ret_struct_u64_u64 :: extern = fn cc(.c) () Struct_u64_u64;
const c_struct_u64_u64_0 :: extern = fn cc(.c) (x: Struct_u64_u64) void;
const c_struct_u64_u64_1 :: extern = fn cc(.c) (a: usize, b: Struct_u64_u64) void;
const c_struct_u64_u64_2 :: extern = fn cc(.c) (a: usize, b: usize, c: Struct_u64_u64) void;
const c_struct_u64_u64_3 :: extern = fn cc(.c) (a: usize, b: usize, c: usize, d: Struct_u64_u64) void;
const c_struct_u64_u64_4 :: extern = fn cc(.c) (a: usize, b: usize, c: usize, d: usize, e: Struct_u64_u64) void;
const c_struct_u64_u64_5 :: extern = fn cc(.c) (a: usize, b: usize, c: usize, d: usize, e: usize, f: Struct_u64_u64) void;
const c_struct_u64_u64_6 :: extern = fn cc(.c) (a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: Struct_u64_u64) void;
const c_struct_u64_u64_7 :: extern = fn cc(.c) (a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: Struct_u64_u64) void;
const c_struct_u64_u64_8 :: extern = fn cc(.c) (a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: Struct_u64_u64) void;
const c_big_struct :: extern = fn cc(.c) (x: BigStruct) void;
const c_small_struct_ints :: extern = fn cc(.c) (x: SmallStructInts) void;
const c_ret_small_struct_ints :: extern = fn cc(.c) () SmallStructInts;
const c_med_struct_ints :: extern = fn cc(.c) (x: MedStructInts) void;
const c_ret_med_struct_ints :: extern = fn cc(.c) () MedStructInts;
const c_small_packed_struct :: extern = fn cc(.c) (x: SmallPackedStruct) void;
const c_ret_small_packed_struct :: extern = fn cc(.c) () SmallPackedStruct;
const c_split_struct_ints :: extern = fn cc(.c) (x: SplitStructInt) void;
const c_big_struct_both :: extern = fn cc(.c) (x: BigStruct) BigStruct;
const c_multiple_struct_ints :: extern = fn cc(.c) (r1: Rect, r2: Rect) void;
const c_ret_bool :: extern = fn cc(.c) () bool;
const c_ret_u8 :: extern = fn cc(.c) () u8;
const c_ret_u16 :: extern = fn cc(.c) () u16;
const c_ret_u32 :: extern = fn cc(.c) () u32;
const c_ret_u64 :: extern = fn cc(.c) () u64;
const c_ret_s8 :: extern = fn cc(.c) () s8;
const c_ret_s16 :: extern = fn cc(.c) () s16;
const c_ret_s32 :: extern = fn cc(.c) () s32;
const c_ret_s64 :: extern = fn cc(.c) () s64;
const StructWithArray = struct{
a: s32,
padding: [4]u8,
b: s64,
};
const c_struct_with_array :: extern = fn cc(.c) (x: StructWithArray) void;
const c_ret_struct_with_array :: extern = fn cc(.c) () StructWithArray;
const c_modify_by_ref_param :: extern = fn cc(.c) (x: ByRef) ByRef;
const c_func_ptr_byval :: extern = fn cc(.c) (a: usize, b: usize, c: ByVal, d: u64, e: u64, f: u64) void;
const nat_u8 :: export = fn cc(.c) (x: u8) void {
expect(x == 0xff) catch #trap();
}
const nat_u16 :: export = fn cc(.c) (x: u16) void {
expect(x == 0xfffe) catch #trap();
}
const nat_u32 :: export = fn cc(.c) (x: u32) void {
expect(x == 0xfffffffd) catch #trap();
}
const nat_u64 :: export = fn cc(.c) (x: u64) void {
expect(x == 0xfffffffffffffffc) catch #trap();
}
const nat_s8 :: export = fn cc(.c) (x: s8) void {
expect(x == -1) catch #trap();
}
const nat_s16 :: export = fn cc(.c) (x: s16) void {
expect(x == -2) catch #trap();
}
const nat_s32 :: export = fn cc(.c) (x: s32) void {
expect(x == -3) catch #trap();
}
const nat_s64 :: export = fn cc(.c) (x: s64) void {
expect(x == -4) catch #trap();
}
// TODO: transform into a real pointer
const nat_ptr :: export = fn cc(.c) (x: usize) void {
expect(x == 0xdeadbeef) catch #trap();
}
const nat_five_integers :: export = fn cc(.c) (a: s32, b: s32, c: s32, d: s32, e: s32) void {
expect(a == 12) catch #trap();
expect(b == 34) catch #trap();
expect(c == 56) catch #trap();
expect(d == 78) catch #trap();
expect(e == 90) catch #trap();
}
const nat_bool:: export = fn cc(.c) (x: bool) void {
expect(x) catch #trap();
}
const Struct_u64_u64 = struct{
a: u64,
b: u64,
};
const nat_ret_struct_u64_u64 :: export = fn cc(.c) () Struct_u64_u64 {
return .{ .a = 1, .b = 2, };
}
const nat_struct_u64_u64_0 :: export = fn cc(.c) (s: Struct_u64_u64) void {
expect(s.a == 3) catch #trap();
expect(s.b == 4) catch #trap();
}
const nat_struct_u64_u64_1 :: export = fn cc(.c) (_: usize, s: Struct_u64_u64) void {
expect(s.a == 5) catch #trap();
expect(s.b == 6) catch #trap();
}
const nat_struct_u64_u64_2 :: export = fn cc(.c) (_: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 7) catch #trap();
expect(s.b == 8) catch #trap();
}
const nat_struct_u64_u64_3 :: export = fn cc(.c) (_: usize, _: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 9) catch #trap();
expect(s.b == 10) catch #trap();
}
const nat_struct_u64_u64_4 :: export = fn cc(.c) (_: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 11) catch #trap();
expect(s.b == 12) catch #trap();
}
const nat_struct_u64_u64_5 :: export = fn cc(.c) (_: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 13) catch #trap();
expect(s.b == 14) catch #trap();
}
const nat_struct_u64_u64_6 :: export = fn cc(.c) (_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 15) catch #trap();
expect(s.b == 16) catch #trap();
}
const nat_struct_u64_u64_7 :: export = fn cc(.c) (_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 17) catch #trap();
expect(s.b == 18) catch #trap();
}
const nat_struct_u64_u64_8 :: export = fn cc(.c) (_: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, _: usize, s: Struct_u64_u64) void {
expect(s.a == 19) catch #trap();
expect(s.b == 20) catch #trap();
}
const BigStruct = struct {
a: u64,
b: u64,
c: u64,
d: u64,
e: u8,
};
const nat_big_struct:: export = fn cc(.c) (x: BigStruct) void {
expect(x.a == 1) catch #trap();
expect(x.b == 2) catch #trap();
expect(x.c == 3) catch #trap();
expect(x.d == 4) catch #trap();
expect(x.e == 5) catch #trap();
}
const SmallStructInts = struct {
a: u8,
b: u8,
c: u8,
d: u8,
};
const nat_small_struct_ints :: export = fn cc(.c) (x: SmallStructInts) void {
expect(x.a == 1) catch #trap();
expect(x.b == 2) catch #trap();
expect(x.c == 3) catch #trap();
expect(x.d == 4) catch #trap();
}
const MedStructInts = struct {
x: s32,
y: s32,
z: s32,
};
const nat_med_struct_ints :: export = fn cc(.c) (s: MedStructInts) void {
expect(s.x == 1) catch #trap();
expect(s.y == 2) catch #trap();
expect(s.z == 3) catch #trap();
}
const SmallPackedStruct = bitfield(u8) {
a: u2,
b: u2,
c: u2,
d: u2,
};
const nat_small_packed_struct :: export = fn cc(.c) (x: SmallPackedStruct) void {
expect(x.a == 0) catch #trap();
expect(x.b == 1) catch #trap();
expect(x.c == 2) catch #trap();
expect(x.d == 3) catch #trap();
}
const SplitStructInt = struct {
a: u64,
b: u8,
c: u32,
};
const nat_split_struct_ints :: export = fn cc(.c) (x: SplitStructInt) void {
expect(x.a == 1234) catch #trap();
expect(x.b == 100) catch #trap();
expect(x.c == 1337) catch #trap();
}
const nat_big_struct_both :: export = fn cc(.c) (x: BigStruct) BigStruct {
expect(x.a == 30) catch #trap();
expect(x.b == 31) catch #trap();
expect(x.c == 32) catch #trap();
expect(x.d == 33) catch #trap();
expect(x.e == 34) catch #trap();
const s = BigStruct{
.a = 20,
.b = 21,
.c = 22,
.d = 23,
.e = 24,
};
return s;
}
const Rect = struct {
left: u32,
right: u32,
top: u32,
bottom: u32,
};
const nat_multiple_struct_ints :: export = fn cc(.c) (x: Rect, y: Rect) void {
expect(x.left == 1) catch #trap();
expect(x.right == 21) catch #trap();
expect(x.top == 16) catch #trap();
expect(x.bottom == 4) catch #trap();
expect(y.left == 178) catch #trap();
expect(y.right == 189) catch #trap();
expect(y.top == 21) catch #trap();
expect(y.bottom == 15) catch #trap();
}
const nat_ret_bool :: export = fn cc(.c) () bool {
return true;
}
const nat_ret_u8 :: export = fn cc(.c) () u8 {
return 0xff;
}
const nat_ret_u16 :: export = fn cc(.c) () u16 {
return 0xffff;
}
const nat_ret_u32 :: export = fn cc(.c) () u32 {
return 0xffffffff;
}
const nat_ret_u64 :: export = fn cc(.c) () u64 {
return 0xffffffffffffffff;
}
const nat_ret_s8 :: export = fn cc(.c) () s8 {
return -1;
}
const nat_ret_s16 :: export = fn cc(.c) () s16 {
return -1;
}
const nat_ret_s32 :: export = fn cc(.c) () s32 {
return -1;
}
const nat_ret_s64 :: export = fn cc(.c) () s64 {
return -1;
}
const nat_ret_small_struct_ints :: export = fn cc(.c) () SmallStructInts {
return .{
.a = 1,
.b = 2,
.c = 3,
.d = 4,
};
}
const nat_ret_med_struct_ints :: export = fn cc(.c) () MedStructInts {
return .{
.x = 1,
.y = 2,
.z = 3,
};
}