Pragma msg goes out of memory when supplied with large data.

realhet real_het at hotmail.com
Sat May 31 06:36:28 UTC 2025


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.


More information about the Digitalmars-d-learn mailing list