Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support exporting a c-style var args function #515

Closed
andrewrk opened this issue Oct 1, 2017 · 9 comments · Fixed by #13914
Closed

support exporting a c-style var args function #515

andrewrk opened this issue Oct 1, 2017 · 9 comments · Fixed by #13914
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Oct 1, 2017

Generally we don't want zig programmers to use c-style var args functions. But sometimes you have to interface with C code.

Here are some use cases:

_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL printf(
    _In_z_ _Printf_format_string_ char const* const _Format,
    ...)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
    int _Result;
    va_list _ArgList;
    __crt_va_start(_ArgList, _Format);
    _Result = _vfprintf_l(stdout, _Format, NULL, _ArgList);
    __crt_va_end(_ArgList);
    return _Result;
}
#endif

LLVM docs on how to do it:
http://llvm.org/docs/LangRef.html#variable-argument-handling-intrinsics

@andrewrk andrewrk added the enhancement Solving this issue will likely involve adding new logic or components to the codebase. label Oct 1, 2017
@andrewrk andrewrk added this to the 0.2.0 milestone Oct 1, 2017
@andrewrk andrewrk modified the milestones: 0.2.0, 0.3.0 Jan 3, 2018
@andrewrk andrewrk modified the milestones: 0.3.0, 0.4.0 Feb 28, 2018
@andrewrk
Copy link
Member Author

@tiehuis

<tiehuis> has anyone done any c va_args implementation from within zig?
<tiehuis> that is, implementing a variadic function in zig
<tiehuis> i'll implement one otherwise shortly, since i need it to implement printf and friends in libc

I don't think anyone started work on this issue, if that's what you're asking.

@andrewrk andrewrk added proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. accepted This proposal is planned. and removed enhancement Solving this issue will likely involve adding new logic or components to the codebase. labels Oct 1, 2018
@daurnimator
Copy link
Contributor

Once this is complete then https://github.com/ziglang/zig/pull/1863/files#diff-0ee24f1c4ac5c34c9f63bfd3230c4008R144 can be fixed/uncommented.

@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Mar 20, 2019
shawnl added a commit to shawnl/zig that referenced this issue Mar 22, 2019
Does NOT look at the locale the way the C functions do.

       int isalnum(int c);
       int isalpha(int c);
       int iscntrl(int c);
       int isdigit(int c);
       int isgraph(int c);
       int islower(int c);
       int isprint(int c);
       int ispunct(int c);
       int isspace(int c);
       int isupper(int c);
       int isxdigit(int c);

       int isascii(int c);
       int isblank(int c);

       int toupper(int c);
       int tolower(int c);

Tested to match glibc (when using C locale) with this program:

const c = @cImport({
    // See ziglang#515
    @cdefine("_NO_CRT_STDIO_INLINE", "1");
    @Cinclude("stdio.h");
    @Cinclude("string.h");
    @Cinclude("ctype.h");
});

const std = @import("std");
const ascii = std.ascii;
const abort = std.os.abort;

export fn main(argc: c_int, argv: **u8) c_int {
    var i: u8 = undefined;
    i = 0;
    while (true) {
        if (ascii.isAlNum(i) != (c.isalnum(i) > 0)) { abort(); }
        if (ascii.isAlpha(i) != (c.isalpha(i) > 0)) { abort(); }
        if (ascii.isCtrl(i) != (c.iscntrl(i) > 0)) { abort(); }
        if (ascii.isDigit(i) != (c.isdigit(i) > 0)) { abort(); }
        if (ascii.isGraph(i) != (c.isgraph(i) > 0)) { abort(); }
        if (ascii.isLower(i) != (c.islower(i) > 0)) { abort(); }
        if (ascii.isPrint(i) != (c.isprint(i) > 0)) { abort(); }
        if (ascii.isPunct(i) != (c.ispunct(i) > 0)) { abort(); }
        if (ascii.isSpace(i) != (c.isspace(i) > 0)) { abort(); }
        if (ascii.isUpper(i) != (c.isupper(i) > 0)) { abort(); }
        if (ascii.isXDigit(i) != (c.isxdigit(i) > 0)) { abort(); }
        if (i == 255) { break; }
        i += 1;
    }

    _ = c.printf(c"Success!\n");
    return 0;
}
andrewrk pushed a commit that referenced this issue Mar 22, 2019
Does NOT look at the locale the way the C functions do.

       int isalnum(int c);
       int isalpha(int c);
       int iscntrl(int c);
       int isdigit(int c);
       int isgraph(int c);
       int islower(int c);
       int isprint(int c);
       int ispunct(int c);
       int isspace(int c);
       int isupper(int c);
       int isxdigit(int c);

       int isascii(int c);
       int isblank(int c);

       int toupper(int c);
       int tolower(int c);

Tested to match glibc (when using C locale) with this program:

const c = @cImport({
    // See #515
    @cdefine("_NO_CRT_STDIO_INLINE", "1");
    @Cinclude("stdio.h");
    @Cinclude("string.h");
    @Cinclude("ctype.h");
});

const std = @import("std");
const ascii = std.ascii;
const abort = std.os.abort;

export fn main(argc: c_int, argv: **u8) c_int {
    var i: u8 = undefined;
    i = 0;
    while (true) {
        if (ascii.isAlNum(i) != (c.isalnum(i) > 0)) { abort(); }
        if (ascii.isAlpha(i) != (c.isalpha(i) > 0)) { abort(); }
        if (ascii.isCtrl(i) != (c.iscntrl(i) > 0)) { abort(); }
        if (ascii.isDigit(i) != (c.isdigit(i) > 0)) { abort(); }
        if (ascii.isGraph(i) != (c.isgraph(i) > 0)) { abort(); }
        if (ascii.isLower(i) != (c.islower(i) > 0)) { abort(); }
        if (ascii.isPrint(i) != (c.isprint(i) > 0)) { abort(); }
        if (ascii.isPunct(i) != (c.ispunct(i) > 0)) { abort(); }
        if (ascii.isSpace(i) != (c.isspace(i) > 0)) { abort(); }
        if (ascii.isUpper(i) != (c.isupper(i) > 0)) { abort(); }
        if (ascii.isXDigit(i) != (c.isxdigit(i) > 0)) { abort(); }
        if (i == 255) { break; }
        i += 1;
    }

    _ = c.printf(c"Success!\n");
    return 0;
}
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 Aug 21, 2019
andrewrk added a commit that referenced this issue Jan 2, 2020
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Feb 10, 2020
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 9, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@skyfex
Copy link

skyfex commented Aug 20, 2021

This issue is related to implementing/exporting a C-style var args function. But is it possible to call a C-style var args function from Zig, or is there a task for that? Like, how would you call libc's printf from Zig?

@ifreund
Copy link
Member

ifreund commented Aug 20, 2021

This issue is related to implementing/exporting a C-style var args function. But is it possible to call a C-style var args function from Zig, or is there a task for that? Like, how would you call libc's printf from Zig?

This already works:

extern fn printf(s: [*:0]const u8, ...) void;
pub fn main() void {
    printf("hello %s\n", "world");
}

@skyfex
Copy link

skyfex commented Aug 20, 2021

@ifreund Thanks, I see that this is indirectly documented in the documentation. But can't find an explicit documentation for it. Should there be a task to add documentation maybe? Anyway, thought it was good to get an answer here since it comes up when you try to google for it.

@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 Nov 20, 2021
@andrewrk andrewrk modified the milestones: 0.10.0, 0.11.0 Apr 16, 2022
andrewrk added a commit that referenced this issue Dec 28, 2022
This reverts commit aca9c74, reversing
changes made to d93edad.

These changes were not tested with LLVM with assertions enabled. They
caused a regression in master branch, triggering LLVM assertions when
running behavior tests.

Reopens #515
andrewrk added a commit that referenced this issue Dec 28, 2022
This reverts commit aca9c74, reversing
changes made to d93edad.

These changes were not tested with LLVM with assertions enabled. They
caused a regression in master branch, triggering LLVM assertions when
running behavior tests.

Reopens #515
@Namek
Copy link

Namek commented Feb 3, 2023

@Vexu @andrewrk I noticed the PRs were reverted, maybe this issue should be reopened?

@Vexu
Copy link
Member

Vexu commented Feb 3, 2023

If you click on those revertion commits you can see that they never made it to the master branch.

@ifreund
Copy link
Member

ifreund commented Aug 25, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
6 participants