On Saturday, 24 May 2025 at 12:53:21 UTC, realhet wrote:
On Friday, 23 May 2025 at 13:10:47 UTC, Dennis wrote:
Now I reached a point it's quite stable.
I had 2 problems to solve:

1. glslc.exe (the external compiler) sometimes freezed at the exit. Solution: Use a modified version of executeShell(). In this version, the stdout, stderr streams are fetched using a separate thread. I don't know what was the cause, it seemed like a race condition between that 'exhausting stdout part' and waiting for the PID to exit. So now I wait first, then join the stdout readed thread. No problems since. 2. line numbers are shifting. glslc.exe's error reports are pointing at the 'wrong' lines It happens when the IES expressions and their values are containing different number of new line characters. Solution: Serialize the complete IES contents including expressions and their values, and adjust the reported line index information accordingly.

So here's the current version:
```
struct LOCATION_t { string location; string toString() const => location; } enum _LOCATION_(string FILE=__FILE__, size_t LINE=__LINE__) = LOCATION_t(FILE~'('~LINE.text~",1)");

template 碼(LOCATION_t LOCATION, Args...)
{
        size_t ctfeWriteIES(Args...)(Args args, size_t h)
        {
                static size_t doit(A)(A a, size_t h)
                {
                        import core.interpolation; alias T = typeof(a);
                        void wr(string s) { __ctfeWrite(s); h = s.hashOf(h); }
                        static if(is(T==InterpolationHeader))   { wr("\1"); }
                        else static if(is(T==InterpolationFooter))      { 
wr("\2"); }
else static if(is(T==InterpolatedLiteral !lit , string lit )) { wr("\3"); wr(lit); } else static if(is(T==InterpolatedExpression!expr, string expr)) { wr("\4"); wr(expr); }
                        else    { wr("\5"); wr(a.text); }
                        return h;
                }
                static foreach(a; args) h = doit(a, h); return h;
        }
        
        string ctfeTransmitIES(LOCATION_t LOCATION, Args...)(Args args)
        {
                __ctfeWrite("$DIDE_TEXTBLOCK_BEGIN$\n");
const hash = ctfeWriteIES(args, "DIDE_EXTERNAL_CODE".hashOf).to!string(26); __ctfeWrite("\n");
                __ctfeWrite("$DIDE_TEXTBLOCK_END$\n");
__ctfeWrite(i"$(LOCATION): $DIDE_EXTERNAL_COMPILATION_REQUEST: $(hash.quoted)\n".text);
                /+
The TEXTBLOCK will be attached to the end of the compilation request message
                        as a string literal inside DIDE.
                +/
                return hash;
        }
        
        enum hash = ctfeTransmitIES!LOCATION(Args);
        enum 碼 = (cast(immutable(ubyte)[])(import(hash)));
        static if(碼.startsWith(cast(ubyte[])("ERROR:")))
        {
pragma(msg, (cast(string)(碼)).splitter('\n').drop(1).join('\n')); static assert(false, "$DIDE_EXTERNAL_COMPILATION_"~(cast(string)(碼)).splitter('\n').front);
        }
}
```
At the end I had to use pragma(msg,...) because of the import() but I believe using __ctfeWrite() for the rest on unmodified strings make it more faster and closer to stderr.


Usage:
```
enum someConstant = 129,
     binary = 碼!(_LOCATION_!(),iq{glslc -O},iq{
        #version 430
        #define someConstant = $(someConstant)
        //GLSL source code here
     });
```


Some observations:
- Both pragma(msg,...) and __ctfeWrite() using this transformation on the received strings:
`s.split('\n').join("\r\n")` (on LDC2 1.40 WIN)
So in order to have matching CRCs at both sides, the input must contain only "\r\n" and the output should replace("\r\r", "\r"). Not a bug, it's indistinguishable for humans. - Error messages using the form: file.d(row,col):... The column information is the 1 based byte index in the UTF8 stream. When using the compiler arg: --verrors-context it can be adjusted to character index without having to peek inside source text.

Reply via email to