diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-09-14 02:47:54 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-09-14 02:47:54 -0400 |
| commit | c65fe384ddb5f5f6a5f22cb636539fd91701de4d (patch) | |
| tree | 8ae6966a01439c347bd69f87e40a9fc5e4f62476 | |
| parent | 06f2f4d64b63cf78a3ff77cc64dbc822123f454d (diff) | |
| parent | f1761632dae8951d21e62cb13e14bd4b4b0ed8a8 (diff) | |
| download | zig-c65fe384ddb5f5f6a5f22cb636539fd91701de4d.tar.gz zig-c65fe384ddb5f5f6a5f22cb636539fd91701de4d.zip | |
Merge branch 'macos-aindigo'
Closes #189
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/codegen.cpp | 2 | ||||
| -rw-r--r-- | src/link.cpp | 6 | ||||
| -rw-r--r-- | src/main.cpp | 2 | ||||
| -rw-r--r-- | std/darwin.zig | 113 | ||||
| -rw-r--r-- | std/darwin_x86_64.zig | 86 | ||||
| -rw-r--r-- | std/debug.zig | 2 | ||||
| -rw-r--r-- | std/index.zig | 5 | ||||
| -rw-r--r-- | std/io.zig | 104 | ||||
| -rw-r--r-- | std/os.zig | 41 | ||||
| -rw-r--r-- | test/run_tests.cpp | 63 |
11 files changed, 334 insertions, 92 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8781167245..6a2b366912 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,6 +213,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/io.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/linux.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}") +install(FILES "${CMAKE_SOURCE_DIR}/std/darwin.zig" DESTINATION "${ZIG_STD_DEST}") +install(FILES "${CMAKE_SOURCE_DIR}/std/darwin_x86_64.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/list.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/mem.zig" DESTINATION "${ZIG_STD_DEST}") diff --git a/src/codegen.cpp b/src/codegen.cpp index ddf06b7eef..827836925c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -42,8 +42,6 @@ static void init_darwin_native(CodeGen *g) { g->mmacosx_version_min = buf_create_from_str(osx_target); } else if (ios_target) { g->mios_version_min = buf_create_from_str(ios_target); - } else { - zig_panic("unable to determine -mmacosx-version-min or -mios-version-min"); } } diff --git a/src/link.cpp b/src/link.cpp index 6b3d3dce83..56a44c4612 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -643,6 +643,12 @@ static void construct_linker_job_darwin(LinkJob *lj) { lj->args.append((const char *)buf_ptr(&lj->out_file_o)); + if (g->is_test_build) { + const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc"; + Buf *test_runner_o_path = build_o(g, test_runner_name); + lj->args.append(buf_ptr(test_runner_o_path)); + } + for (int i = 0; i < g->link_libs.length; i += 1) { Buf *link_lib = g->link_libs.at(i); Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib)); diff --git a/src/main.cpp b/src/main.cpp index 5caa37c66a..e55350a274 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -388,9 +388,11 @@ int main(int argc, char **argv) { fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n"); return EXIT_FAILURE; } + if (mmacosx_version_min) { codegen_set_mmacosx_version_min(g, buf_create_from_str(mmacosx_version_min)); } + if (mios_version_min) { codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min)); } diff --git a/std/darwin.zig b/std/darwin.zig new file mode 100644 index 0000000000..0bf8b62f58 --- /dev/null +++ b/std/darwin.zig @@ -0,0 +1,113 @@ + +const arch = switch (@compileVar("arch")) { + x86_64 => @import("darwin_x86_64.zig"), + else => @compile_err("unsupported arch"), +}; + +const errno = @import("errno.zig"); + +pub const O_LARGEFILE = 0x0000; +pub const O_RDONLY = 0x0000; + +pub const SEEK_SET = 0x0; +pub const SEEK_CUR = 0x1; +pub const SEEK_END = 0x2; + +pub const SIGHUP = 1; +pub const SIGINT = 2; +pub const SIGQUIT = 3; +pub const SIGILL = 4; +pub const SIGTRAP = 5; +pub const SIGABRT = 6; +pub const SIGIOT = SIGABRT; +pub const SIGBUS = 7; +pub const SIGFPE = 8; +pub const SIGKILL = 9; +pub const SIGUSR1 = 10; +pub const SIGSEGV = 11; +pub const SIGUSR2 = 12; +pub const SIGPIPE = 13; +pub const SIGALRM = 14; +pub const SIGTERM = 15; +pub const SIGSTKFLT = 16; +pub const SIGCHLD = 17; +pub const SIGCONT = 18; +pub const SIGSTOP = 19; +pub const SIGTSTP = 20; +pub const SIGTTIN = 21; +pub const SIGTTOU = 22; +pub const SIGURG = 23; +pub const SIGXCPU = 24; +pub const SIGXFSZ = 25; +pub const SIGVTALRM = 26; +pub const SIGPROF = 27; +pub const SIGWINCH = 28; +pub const SIGIO = 29; +pub const SIGPOLL = 29; +pub const SIGPWR = 30; +pub const SIGSYS = 31; +pub const SIGUNUSED = SIGSYS; + +/// Get the errno from a syscall return value, or 0 for no error. +pub fn getErrno(r: usize) -> usize { + const signed_r = *(&isize)(&r); + if (signed_r > -4096 && signed_r < 0) usize(-signed_r) else 0 +} + +pub fn write(fd: i32, buf: &const u8, count: usize) -> usize { + arch.syscall3(arch.SYS_write, usize(fd), usize(buf), count) +} + +pub fn close(fd: i32) -> usize { + arch.syscall1(arch.SYS_close, usize(fd)) +} + +pub fn open_c(path: &const u8, flags: usize, perm: usize) -> usize { + arch.syscall3(arch.SYS_open, usize(path), flags, perm) +} + +pub fn open(path: []const u8, flags: usize, perm: usize) -> usize { + var buf: [path.len + 1]u8 = undefined; + @memcpy(&buf[0], &path[0], path.len); + buf[path.len] = 0; + return open_c(buf.ptr, flags, perm); +} + +pub fn read(fd: i32, buf: &u8, count: usize) -> usize { + arch.syscall3(arch.SYS_read, usize(fd), usize(buf), count) +} + +pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize { + arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos) +} + +pub const stat = arch.stat; +pub const timespec = arch.timespec; + +pub fn fstat(fd: i32, stat_buf: &stat) -> usize { + arch.syscall2(arch.SYS_fstat, usize(fd), usize(stat_buf)) +} + +pub error Unexpected; + +pub fn getrandom(buf: &u8, count: usize) -> usize { + const rr = open_c(c"/dev/urandom", O_LARGEFILE | O_RDONLY, 0); + + if(getErrno(rr) > 0) return rr; + + var fd: i32 = i32(rr); + const readRes = read(fd, buf, count); + readRes +} + +pub fn raise(sig: i32) -> i32 { + // TODO investigate whether we need to block signals before calling kill + // like we do in the linux version of raise + + //var set: sigset_t = undefined; + //blockAppSignals(&set); + const pid = i32(arch.syscall0(arch.SYS_getpid)); + const ret = i32(arch.syscall2(arch.SYS_kill, usize(pid), usize(sig))); + //restoreSignals(&set); + return ret; +} diff --git a/std/darwin_x86_64.zig b/std/darwin_x86_64.zig new file mode 100644 index 0000000000..2dc98513e9 --- /dev/null +++ b/std/darwin_x86_64.zig @@ -0,0 +1,86 @@ + +pub const SYSCALL_CLASS_SHIFT = 24; +pub const SYSCALL_CLASS_MASK = 0xFF << SYSCALL_CLASS_SHIFT; +// pub const SYSCALL_NUMBER_MASK = ~SYSCALL_CLASS_MASK; // ~ modifier not supported yet + +pub const SYSCALL_CLASS_NONE = 0; // Invalid +pub const SYSCALL_CLASS_MACH = 1; // Mach +pub const SYSCALL_CLASS_UNIX = 2; // Unix/BSD +pub const SYSCALL_CLASS_MDEP = 3; // Machine-dependent +pub const SYSCALL_CLASS_DIAG = 4; // Diagnostics + +// TODO: use the above constants to create the below values + +pub const SYS_read = 0x2000003; +pub const SYS_write = 0x2000004; +pub const SYS_open = 0x2000005; +pub const SYS_close = 0x2000006; +pub const SYS_kill = 0x2000025; +pub const SYS_getpid = 0x2000030; +pub const SYS_fstat = 0x20000BD; +pub const SYS_lseek = 0x20000C7; + +pub inline fn syscall0(number: usize) -> usize { + asm volatile ("syscall" + : [ret] "={rax}" (-> usize) + : [number] "{rax}" (number) + : "rcx", "r11") +} + +pub inline fn syscall1(number: usize, arg1: usize) -> usize { + asm volatile ("syscall" + : [ret] "={rax}" (-> usize) + : [number] "{rax}" (number), + [arg1] "{rdi}" (arg1) + : "rcx", "r11") +} + +pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize { + asm volatile ("syscall" + : [ret] "={rax}" (-> usize) + : [number] "{rax}" (number), + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2) + : "rcx", "r11") +} + +pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize { + asm volatile ("syscall" + : [ret] "={rax}" (-> usize) + : [number] "{rax}" (number), + [arg1] "{rdi}" (arg1), + [arg2] "{rsi}" (arg2), + [arg3] "{rdx}" (arg3) + : "rcx", "r11") +} + + + + +export struct stat { + dev: u32, + mode: u16, + nlink: u16, + ino: u64, + uid: u32, + gid: u32, + rdev: u64, + + atim: timespec, + mtim: timespec, + ctim: timespec, + + size: u64, + blocks: u64, + blksize: u32, + flags: u32, + gen: u32, + lspare: i32, + qspare: [2]u64, + +} + +export struct timespec { + tv_sec: isize, + tv_nsec: isize, +} diff --git a/std/debug.zig b/std/debug.zig index dd864f4f0a..8b3d4c9b05 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -49,7 +49,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void { out_stream.write("(stack trace unavailable for COFF object format)\n"); }, macho => { - out_stream.write("(stack trace unavailable for Mach-O object format)\n"); + %return out_stream.write("(stack trace unavailable for Mach-O object format)\n"); }, unknown => { out_stream.write("(stack trace unavailable for unknown object format)\n"); diff --git a/std/index.zig b/std/index.zig index e7cda17b28..0b7333b138 100644 --- a/std/index.zig +++ b/std/index.zig @@ -13,5 +13,8 @@ pub const linux = switch(@compileVar("os")) { linux => @import("linux.zig"), else => null_import, }; - +pub const darwin = switch(@compileVar("os")) { + darwin => @import("darwin.zig"), + else => null_import, +}; const null_import = @import("empty.zig"); diff --git a/std/io.zig b/std/io.zig index 762d65cc64..9c30233cb4 100644 --- a/std/io.zig +++ b/std/io.zig @@ -1,9 +1,15 @@ -const linux = @import("linux.zig"); +const system = switch(@compileVar("os")) { + linux => @import("linux.zig"), + darwin => @import("darwin.zig"), + else => @compileError("Unsupported OS"), +}; + const errno = @import("errno.zig"); const math = @import("math.zig"); const endian = @import("endian.zig"); const debug = @import("debug.zig"); const assert = debug.assert; +const os = @import("os.zig"); pub const stdin_fileno = 0; pub const stdout_fileno = 1; @@ -67,23 +73,23 @@ pub struct OutStream { buffer: [buffer_size]u8, index: usize, - pub fn writeByte(os: &OutStream, b: u8) -> %void { - if (os.buffer.len == os.index) %return os.flush(); - os.buffer[os.index] = b; - os.index += 1; + pub fn writeByte(self: &OutStream, b: u8) -> %void { + if (self.buffer.len == self.index) %return self.flush(); + self.buffer[self.index] = b; + self.index += 1; } - pub fn write(os: &OutStream, bytes: []const u8) -> %usize { + pub fn write(self: &OutStream, bytes: []const u8) -> %usize { var src_bytes_left = bytes.len; var src_index: @typeOf(bytes.len) = 0; - const dest_space_left = os.buffer.len - os.index; + const dest_space_left = self.buffer.len - self.index; while (src_bytes_left > 0) { const copy_amt = math.min(dest_space_left, src_bytes_left); - @memcpy(&os.buffer[os.index], &bytes[src_index], copy_amt); - os.index += copy_amt; - if (os.index == os.buffer.len) { - %return os.flush(); + @memcpy(&self.buffer[self.index], &bytes[src_index], copy_amt); + self.index += copy_amt; + if (self.index == self.buffer.len) { + %return self.flush(); } src_bytes_left -= copy_amt; } @@ -92,30 +98,29 @@ pub struct OutStream { /// Prints a byte buffer, flushes the buffer, then returns the number of /// bytes printed. The "f" is for "flush". - pub fn printf(os: &OutStream, str: []const u8) -> %usize { - const byte_count = %return os.write(str); - %return os.flush(); + pub fn printf(self: &OutStream, str: []const u8) -> %usize { + const byte_count = %return self.write(str); + %return self.flush(); return byte_count; } - pub fn printInt(os: &OutStream, inline T: type, x: T) -> %usize { + pub fn printInt(self: &OutStream, inline T: type, x: T) -> %usize { // TODO replace max_u64_base10_digits with math.log10(math.pow(2, @sizeOf(T))) - if (os.index + max_u64_base10_digits >= os.buffer.len) { - %return os.flush(); + if (self.index + max_u64_base10_digits >= self.buffer.len) { + %return self.flush(); } - const amt_printed = bufPrintInt(T, os.buffer[os.index...], x); - os.index += amt_printed; + const amt_printed = bufPrintInt(T, self.buffer[self.index...], x); + self.index += amt_printed; return amt_printed; } - pub fn flush(os: &OutStream) -> %void { + pub fn flush(self: &OutStream) -> %void { while (true) { - const write_ret = linux.write(os.fd, &os.buffer[0], os.index); - const write_err = linux.getErrno(write_ret); + const write_ret = system.write(self.fd, &self.buffer[0], self.index); + const write_err = system.getErrno(write_ret); if (write_err > 0) { return switch (write_err) { errno.EINTR => continue, - errno.EINVAL => @unreachable(), errno.EDQUOT => error.DiskQuota, errno.EFBIG => error.FileTooBig, @@ -126,15 +131,15 @@ pub struct OutStream { else => error.Unexpected, } } - os.index = 0; + self.index = 0; return; } } - pub fn close(os: &OutStream) -> %void { + pub fn close(self: &OutStream) -> %void { while (true) { - const close_ret = linux.close(os.fd); - const close_err = linux.getErrno(close_ret); + const close_ret = system.close(self.fd); + const close_err = system.getErrno(close_ret); if (close_err > 0) { return switch (close_err) { errno.EINTR => continue, @@ -157,10 +162,10 @@ pub struct InStream { /// Call close to clean up. pub fn open(is: &InStream, path: []const u8) -> %void { switch (@compileVar("os")) { - linux => { + linux, darwin => { while (true) { - const result = linux.open(path, linux.O_LARGEFILE|linux.O_RDONLY, 0); - const err = linux.getErrno(result); + const result = system.open(path, system.O_LARGEFILE|system.O_RDONLY, 0); + const err = system.getErrno(result); if (err > 0) { return switch (err) { errno.EINTR => continue, @@ -189,16 +194,17 @@ pub struct InStream { }, else => @compileError("unsupported OS"), } + } /// Upon success, the stream is in an uninitialized state. To continue using it, /// you must use the open() function. pub fn close(is: &InStream) -> %void { switch (@compileVar("os")) { - linux => { + linux, darwin => { while (true) { - const close_ret = linux.close(is.fd); - const close_err = linux.getErrno(close_ret); + const close_ret = system.close(is.fd); + const close_err = system.getErrno(close_ret); if (close_err > 0) { return switch (close_err) { errno.EINTR => continue, @@ -219,11 +225,11 @@ pub struct InStream { /// the stream reached End Of File. pub fn read(is: &InStream, buf: []u8) -> %usize { switch (@compileVar("os")) { - linux => { + linux, darwin => { var index: usize = 0; while (index < buf.len) { - const amt_read = linux.read(is.fd, &buf[index], buf.len - index); - const read_err = linux.getErrno(amt_read); + const amt_read = system.read(is.fd, &buf[index], buf.len - index); + const read_err = system.getErrno(amt_read); if (read_err > 0) { switch (read_err) { errno.EINTR => continue, @@ -287,9 +293,9 @@ pub struct InStream { pub fn seekForward(is: &InStream, amount: usize) -> %void { switch (@compileVar("os")) { - linux => { - const result = linux.lseek(is.fd, amount, linux.SEEK_CUR); - const err = linux.getErrno(result); + linux, darwin => { + const result = system.lseek(is.fd, amount, system.SEEK_CUR); + const err = system.getErrno(result); if (err > 0) { return switch (err) { errno.EBADF => error.BadFd, @@ -307,9 +313,9 @@ pub struct InStream { pub fn seekTo(is: &InStream, pos: usize) -> %void { switch (@compileVar("os")) { - linux => { - const result = linux.lseek(is.fd, pos, linux.SEEK_SET); - const err = linux.getErrno(result); + linux, darwin => { + const result = system.lseek(is.fd, pos, system.SEEK_SET); + const err = system.getErrno(result); if (err > 0) { return switch (err) { errno.EBADF => error.BadFd, @@ -327,9 +333,9 @@ pub struct InStream { pub fn getPos(is: &InStream) -> %usize { switch (@compileVar("os")) { - linux => { - const result = linux.lseek(is.fd, 0, linux.SEEK_CUR); - const err = linux.getErrno(result); + linux, darwin => { + const result = system.lseek(is.fd, 0, system.SEEK_CUR); + const err = system.getErrno(result); if (err > 0) { return switch (err) { errno.EBADF => error.BadFd, @@ -347,8 +353,8 @@ pub struct InStream { } pub fn getEndPos(is: &InStream) -> %usize { - var stat: linux.stat = undefined; - const err = linux.getErrno(linux.fstat(is.fd, &stat)); + var stat: system.stat = undefined; + const err = system.getErrno(system.fstat(is.fd, &stat)); if (err > 0) { return switch (err) { errno.EBADF => error.BadFd, @@ -436,6 +442,10 @@ pub fn openSelfExe(stream: &InStream) -> %void { linux => { %return stream.open("/proc/self/exe"); }, + darwin => { + %%stderr.printf("TODO: openSelfExe on Darwin\n"); + os.abort(); + }, else => @compileError("unsupported os"), } } diff --git a/std/os.zig b/std/os.zig index bfdc97220a..806cc43f33 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1,33 +1,38 @@ -const linux = @import("linux.zig"); +const system = switch(@compileVar("os")) { + linux => @import("linux.zig"), + darwin => @import("darwin.zig"), + else => @compileError("Unsupported OS"), +}; const errno = @import("errno.zig"); -pub error SigInterrupt; pub error Unexpected; pub fn getRandomBytes(buf: []u8) -> %void { - switch (@compileVar("os")) { - linux => { - const ret = linux.getrandom(buf.ptr, buf.len, 0); - const err = linux.getErrno(ret); - if (err > 0) { - return switch (err) { - errno.EINVAL => @unreachable(), - errno.EFAULT => @unreachable(), - errno.EINTR => error.SigInterrupt, - else => error.Unexpected, - } + while (true) { + const ret = switch (@compileVar("os")) { + linux => system.getrandom(buf.ptr, buf.len, 0), + darwin => system.getrandom(buf.ptr, buf.len), + else => @compileError("unsupported os"), + }; + const err = system.getErrno(ret); + if (err > 0) { + return switch (err) { + errno.EINVAL => @unreachable(), + errno.EFAULT => @unreachable(), + errno.EINTR => continue, + else => error.Unexpected, } - }, - else => @compileError("unsupported os"), + } + return; } } #attribute("cold") pub fn abort() -> unreachable { switch (@compileVar("os")) { - linux => { - linux.raise(linux.SIGABRT); - linux.raise(linux.SIGKILL); + linux, darwin => { + system.raise(system.SIGABRT); + system.raise(system.SIGKILL); while (true) {} }, else => @compileError("unsupported os"), diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 725c391ebb..a0fa1c7ad4 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -18,6 +18,11 @@ struct TestSourceFile { const char *source_code; }; +enum AllowWarnings { + AllowWarningsNo, + AllowWarningsYes, +}; + struct TestCase { const char *case_name; const char *output; @@ -29,6 +34,7 @@ struct TestCase { bool is_self_hosted; bool is_release_mode; bool is_debug_safety; + AllowWarnings allow_warnings; }; static ZigList<TestCase*> test_cases = {0}; @@ -173,13 +179,16 @@ static void add_debug_safety_case(const char *case_name, const char *source) { } } -static TestCase *add_parseh_case(const char *case_name, const char *source, int count, ...) { +static TestCase *add_parseh_case(const char *case_name, AllowWarnings allow_warnings, + const char *source, int count, ...) +{ va_list ap; va_start(ap, count); TestCase *test_case = allocate<TestCase>(1); test_case->case_name = case_name; test_case->is_parseh = true; + test_case->allow_warnings = allow_warnings; test_case->source_files.resize(1); test_case->source_files.at(0).relative_path = tmp_h_path; @@ -1635,7 +1644,7 @@ fn unsigned_cast(x: i32) -> u32 { ////////////////////////////////////////////////////////////////////////////// static void add_parseh_test_cases(void) { - add_parseh_case("simple data types", R"SOURCE( + add_parseh_case("simple data types", AllowWarningsYes, R"SOURCE( #include <stdint.h> int foo(char a, unsigned char b, signed char c); int foo(char a, unsigned char b, signed char c); // test a duplicate prototype @@ -1646,11 +1655,11 @@ void baz(int8_t a, int16_t b, int32_t c, int64_t d); "pub extern fn bar(a: u8, b: u16, c: u32, d: u64);", "pub extern fn baz(a: i8, b: i16, c: i32, d: i64);"); - add_parseh_case("noreturn attribute", R"SOURCE( + add_parseh_case("noreturn attribute", AllowWarningsNo, R"SOURCE( void foo(void) __attribute__((noreturn)); )SOURCE", 1, R"OUTPUT(pub extern fn foo() -> unreachable;)OUTPUT"); - add_parseh_case("enums", R"SOURCE( + add_parseh_case("enums", AllowWarningsNo, R"SOURCE( enum Foo { FooA, FooB, @@ -1665,11 +1674,11 @@ pub const FooB = enum_Foo.B; pub const Foo1 = enum_Foo.@"1";)", R"(pub const Foo = enum_Foo;)"); - add_parseh_case("restrict -> noalias", R"SOURCE( + add_parseh_case("restrict -> noalias", AllowWarningsNo, R"SOURCE( void foo(void *restrict bar, void *restrict); )SOURCE", 1, R"OUTPUT(pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);)OUTPUT"); - add_parseh_case("simple struct", R"SOURCE( + add_parseh_case("simple struct", AllowWarningsNo, R"SOURCE( struct Foo { int x; char *y; @@ -1680,7 +1689,7 @@ struct Foo { y: ?&u8, })OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT"); - add_parseh_case("qualified struct and enum", R"SOURCE( + add_parseh_case("qualified struct and enum", AllowWarningsNo, R"SOURCE( struct Foo { int x; int y; @@ -1703,12 +1712,13 @@ pub const BarB = enum_Bar.B;)OUTPUT", R"OUTPUT(pub const Foo = struct_Foo; pub const Bar = enum_Bar;)OUTPUT"); - add_parseh_case("constant size array", R"SOURCE( + add_parseh_case("constant size array", AllowWarningsNo, R"SOURCE( void func(int array[20]); )SOURCE", 1, "pub extern fn func(array: ?&c_int);"); - add_parseh_case("self referential struct with function pointer", R"SOURCE( + add_parseh_case("self referential struct with function pointer", + AllowWarningsNo, R"SOURCE( struct Foo { void (*derp)(struct Foo *foo); }; @@ -1717,7 +1727,7 @@ struct Foo { })OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT"); - add_parseh_case("struct prototype used in func", R"SOURCE( + add_parseh_case("struct prototype used in func", AllowWarningsNo, R"SOURCE( struct Foo; struct Foo *some_func(struct Foo *foo, int x); )SOURCE", 2, R"OUTPUT(pub type struct_Foo = u8; @@ -1725,17 +1735,19 @@ pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT"); - add_parseh_case("#define a char literal", R"SOURCE( + add_parseh_case("#define a char literal", AllowWarningsNo, R"SOURCE( #define A_CHAR 'a' )SOURCE", 1, R"OUTPUT(pub const A_CHAR = 'a';)OUTPUT"); - add_parseh_case("#define an unsigned integer literal", R"SOURCE( + add_parseh_case("#define an unsigned integer literal", AllowWarningsNo, + R"SOURCE( #define CHANNEL_COUNT 24 )SOURCE", 1, R"OUTPUT(pub const CHANNEL_COUNT = 24;)OUTPUT"); - add_parseh_case("#define referencing another #define", R"SOURCE( + add_parseh_case("#define referencing another #define", AllowWarningsNo, + R"SOURCE( #define THING2 THING1 #define THING1 1234 )SOURCE", 2, @@ -1743,7 +1755,7 @@ pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT", "pub const THING2 = THING1;"); - add_parseh_case("variables", R"SOURCE( + add_parseh_case("variables", AllowWarningsNo, R"SOURCE( extern int extern_var; static const int int_var = 13; )SOURCE", 2, @@ -1751,7 +1763,7 @@ static const int int_var = 13; "pub const int_var: c_int = 13;"); - add_parseh_case("circular struct definitions", R"SOURCE( + add_parseh_case("circular struct definitions", AllowWarningsNo, R"SOURCE( struct Bar; struct Foo { @@ -1770,14 +1782,15 @@ struct Bar { })SOURCE"); - add_parseh_case("typedef void", R"SOURCE( + add_parseh_case("typedef void", AllowWarningsNo, R"SOURCE( typedef void Foo; Foo fun(Foo *a); )SOURCE", 2, "pub const Foo = c_void;", "pub extern fn fun(a: ?&c_void);"); - add_parseh_case("generate inline func for #define global extern fn", R"SOURCE( + add_parseh_case("generate inline func for #define global extern fn", AllowWarningsNo, + R"SOURCE( extern void (*fn_ptr)(void); #define foo fn_ptr )SOURCE", 2, @@ -1787,19 +1800,19 @@ extern void (*fn_ptr)(void); })SOURCE"); - add_parseh_case("#define string", R"SOURCE( + add_parseh_case("#define string", AllowWarningsNo, R"SOURCE( #define foo "a string" )SOURCE", 1, "pub const foo = c\"a string\";"); - add_parseh_case("__cdecl doesn't mess up function pointers", R"SOURCE( + add_parseh_case("__cdecl doesn't mess up function pointers", AllowWarningsNo, R"SOURCE( void foo(void (__cdecl *fn_ptr)(void)); )SOURCE", 1, "pub extern fn foo(fn_ptr: ?extern fn());"); - add_parseh_case("comment after integer literal", R"SOURCE( + add_parseh_case("comment after integer literal", AllowWarningsNo, R"SOURCE( #define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ )SOURCE", 1, "pub const SDL_INIT_VIDEO = 32;"); - add_parseh_case("zig keywords in C code", R"SOURCE( + add_parseh_case("zig keywords in C code", AllowWarningsNo, R"SOURCE( struct type { int defer; }; @@ -1807,7 +1820,7 @@ struct type { @"defer": c_int, })", R"(pub const @"type" = struct_type;)"); - add_parseh_case("macro defines string literal with octal", R"SOURCE( + add_parseh_case("macro defines string literal with octal", AllowWarningsNo, R"SOURCE( #define FOO "aoeu\023 derp" #define FOO2 "aoeu\0234 derp" #define FOO_CHAR '\077' @@ -1926,9 +1939,13 @@ static void run_test(TestCase *test_case) { if (test_case->is_parseh) { if (buf_len(&zig_stderr) > 0) { printf("\nparseh emitted warnings:\n"); + printf("------------------------------\n"); print_compiler_invocation(test_case); printf("%s\n", buf_ptr(&zig_stderr)); - exit(1); + printf("------------------------------\n"); + if (test_case->allow_warnings == AllowWarningsNo) { + exit(1); + } } for (int i = 0; i < test_case->compile_errors.length; i += 1) { |
