zig icon indicating copy to clipboard operation
zig copied to clipboard

Bug trying a C single header library(termbox)

Open AngelJumbo opened this issue 1 year ago • 3 comments

Zig Version

0.9.1

Steps to Reproduce

I was trying to use termbox , in fact I tried this example , but the run instruction looked weird and when I tried it, it didn't work (maybe the guy had an older older version of zig). After reading the docs of zig, I modified the code a bit like this:

const c = @cImport({
    @cDefine("TB_IMPL", "");
    @cInclude("termbox.h");
});
const std = @import("std");

pub fn main() void {
    _ = c.tb_init();
    var ev = c.tb_event{
        .type = 0,
        .mod = 0,
        .key = 0,
        .ch = 0,
        .w = 0,
        .h = 0,
        .x = 0,
        .y = 0,
    };

    var y: i32 = 0;
    _ = c.tb_printf(0, y, 0x02 | 0x0100, 0x00, "hello from zig");
    y += 1;
    _ = c.tb_printf(0, y, 0x03, 0x00, "press any key");
    y += 1;
    _ = c.tb_present();
    _ = c.tb_poll_event(&ev);

    _ = c.tb_printf(0, y, 0x04, 0x00, "event: type=%d mod=%d key=%d ch=%d w=%d h=%d x=%d y=%d", ev.type, ev.mod, ev.key, ev.ch, ev.w, ev.h, ev.x, ev.y);
    y += 1;
    _ = c.tb_present();

    _ = c.tb_printf(0, y, 0x05, 0x00, "press any key to quit");
    y += 1;
    _ = c.tb_present();
    _ = c.tb_poll_event(&ev);

    _ = c.tb_shutdown();
}

Then I ran: zig run example.zig -lc -isystem <dir/of/the/header/file>

Expected Behavior

I expected I message in the terminal: hello from zig press any key After pressing a key I should get a response: event: type=%d mod=%d key=%d ch=%d w=%d h=%d x=%d y=%d press any key to quit

Actual Behavior

I got this error: Semantic Analysis [70/172] Unreachable at /home/andy/dev/bootstrap-zig/zig/src/stage1/ir.cpp:23023 in buf_write_value_bytes. This is a bug in the Zig compiler.thread 3258 panic: Unable to dump stack trace: debug info stripped fish: Job 1, 'zig run example.zig -lc -isyste…' terminated by signal SIGABRT (Abort) I notice that the home directory that appears in the error "/home/andy/" it's not my home directory and the computer does not have any user called "andy".

AngelJumbo avatar Oct 12 '22 08:10 AngelJumbo

On master this hits a translate-c bug:

int foo(void) {
    int tmp;
    int bar;
    if (bar = tmp == 0) return 1;
}
pub export fn foo() c_int {
    var tmp: c_int = undefined;
    _ = @TypeOf(tmp);
    var bar: c_int = undefined;
    if ((blk: {
        const tmp_1 = tmp_1 == @as(c_int, 0);
        bar = tmp_1;
        break :blk tmp_1;
    }) != 0) return 1;
    return 0;
}

After that is fixed it hits a TODO in stage2:

zig/src/value.zig:1414:21: 0x1080663 in readFromMemory (zig)
            else => @panic("TODO implement readFromMemory for more types"),

Vexu avatar Oct 12 '22 09:10 Vexu

Using the command they provide at the top of the example file, it works for me.

zig version
0.9.1
git clone --depth=1 -j4 https://github.com/termbox/termbox2
cd termbox2
make libtermbox.so
ln -sf libtermbox.so libtermbox.so.2

cd demo
zig run -I.. -I/usr/include -I/usr/include/x86_64-linux-gnu/ -rpath .. -L.. -ltermbox -lc example.zig
hello from zig
press any key
event: type=1 mod=2 key=13 ch=0 w=0 h=0 x=0 y=0
press any key to quit

JCallicoat avatar Oct 21 '22 02:10 JCallicoat

Well I didn't know that I had to compile termbox as a library, but it's still is supposed to work only importing the header file, right?

AngelJumbo avatar Oct 21 '22 03:10 AngelJumbo

You need to compile the definitions, one way or another. In a C project that means a #define TB_IMPL in one source file; for other languages you will need to generate the library with make. That works successfully on master, so I think this issue can be closed.

tau-dev avatar Dec 16 '22 11:12 tau-dev

@tau-dev but zig has this translate-c thing, so the define TB_IMPL in one source file should work just like in C. Am I wrong?

AngelJumbo avatar Dec 16 '22 18:12 AngelJumbo

Sorry, I completely missed that! Yeah, translate-c currently generates invalid code:

/home/tau/.cache/zig/o/.../cimport.zig:4752:119: error: use of undeclared identifier 'tmp_1'
            const tmp_1 = load_terminfo_from_path(@ptrCast([*c]u8, @alignCast(@import("std").meta.alignment([*c]u8), &tmp_1)), term);

Interesting. I'll investigate.

tau-dev avatar Dec 18 '22 21:12 tau-dev

Creduce'd it down to:

void e() {
    int d;
    int tmp;
    (d = tmp);
}

which gets turned into

pub export fn e() void {
    var d: c_int = undefined;
    _ = @TypeOf(d);
    var tmp: c_int = undefined;
    _ = @TypeOf(tmp);
    _ = blk: {
        const tmp_1 = tmp_1;
        d = tmp_1;
        break :blk tmp_1;
    };
}

So temporary variables just need additional mangling to not collide with identifiers named tmp in the source.

tau-dev avatar Dec 18 '22 22:12 tau-dev

So temporary variables just need additional mangling to not collide with identifiers named tmp in the source.

Sounds like what was described in #15411 and fixed by #15420 so maybe this is fixed too.

wooster0 avatar May 08 '23 22:05 wooster0