On 23/03/2026 8:13 PM, Ada wrote:
On Monday, 23 March 2026 at 05:46:15 UTC, Richard (Rikki) Andrew Cattermole wrote:
On 23/03/2026 6:36 PM, Ada wrote:
On Monday, 23 March 2026 at 05:33:05 UTC, Richard (Rikki) Andrew Cattermole wrote:
On 23/03/2026 6:29 PM, Ada wrote:
On Sunday, 22 March 2026 at 22:49:24 UTC, Richard (Rikki) Andrew Cattermole wrote:
[...]

I clearly said compile-time. maybe you misspoke.
It's a bit of a nuisance because the function call then doesn't resemble C that much anymore. (it's called betterc)

The only way to do it at CT, is either with the pragma with a string literal for the format, or the format must be provided via a template parameter.

You cannot do this, with a function parameter at CT.

In that case, how would you do it with the pragma or the template parameter?

Start with the pragma, I linked the docs for it.

Parsing out the format spec by itself isn't a fun job and is libc dependent.

Hmm, just to be clear. The pragma just says that the function marked with it will follow the C99 Standard 7.19.6.1. Does that standard specify that custom format specifiers can be defined by any chance?

No.

Because that's essentially what I am trying to achieve.

Yeah you are a tad on your own on this one.

Here is one way to do it with recursive functions.

I had to create a indexOf util function as std.algorithm appears that it might've had a regression (WONTFIX) for betterC.

```d
size_t indexOf(string haystack, char needle) {
    foreach(i, c; haystack) {
        if (c == needle)
            return i;
    }

    return haystack.length;
}

void myPrint(string Format, Args...)(auto ref Args args) {
    import core.stdc.stdio : printf;

    size_t parseFormat(string text, size_t offset) {
        if (text[offset + 1] == 's' || text[offset + 1] == 'c')
            return 1;
        else
            assert(0, "invalid format");
    }

    void before(string text) {
        printf("%.*s", cast(int)text.length, text.ptr);
    }

    void actual(string Format3, T)(auto ref T value) {
        static if (is(T == string) && Format3[1] == 's') {
            printf("%.*s", cast(int)value.length, value.ptr);
        } else {
            printf(Format3.ptr, value);
        }
    }

    void handle(string Format2, size_t Arg)() {
        enum Offset = Format2.indexOf('%');
        enum Length = Format2.length > Offset ?
            (parseFormat(Format2, Offset) + 1) : 0;

        static if (Offset <= Format2.length) {
            if (Offset > 0)
                before(Format2[0 .. Offset]);

            static if (Arg < Args.length)
                actual!(Format2[Offset .. Offset + Length])(args[Arg]);

            static if (Format2.length > Offset + Length)
                static if (Arg + 1 <= Args.length)
                    handle!(Format2[Offset + Length .. $], Arg + 1);
        } else {
            // no format???
            static assert(0, "Missing format for argument");
        }
    }

    handle!(Format, 0);
}

extern(C) {
    void main() {
        import core.stdc.stdio : printf;
        myPrint!"b%s%ce\n"("Hellorld", '!');
        printf("done\n");
    }
}
```

  • Compile time for... Ada via Digitalmars-d-learn
    • Re: Compile... Ada via Digitalmars-d-learn
    • Re: Compile... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
      • Re: Com... Ada via Digitalmars-d-learn
        • Re:... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
          • ... Ada via Digitalmars-d-learn
            • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
              • ... Ada via Digitalmars-d-learn
                • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

Reply via email to