Re: How to escape control characters?
On Tuesday, 23 August 2022 at 13:09:01 UTC, Steven Schveighoffer wrote: Without allocations. This took me longer than I had hoped it would. It needs the 1-char buffer to avoid sending the surrounding quotes. Surely what Steve does is better. But for some reason I like simple and useful things. I sometimes use custom string wrapping. Maybe it will be useful for you, for example: ```d struct String { string str; alias str this; import std.format, std.string; void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)const { auto arr = str.lineSplitter; if(fmt.spec == 'n') { sink.formattedWrite("%-(%s\\n%)", arr); } else sink.formattedWrite("%s", str); } } unittest { import std.stdio; auto str = `this is a string`; String Str; // simple constructor Str = str; // direct assign Str.writefln!"%n"; // "this\n is a\n string" Str.writefln!"%s"; /* this is a string */ } ``` The nice thing here is that you can change the format specifiers as you wish. Thank you all... SDB@79
Re: what's this error: allocatestack.c:384: advise_stack_range: Assertion `freesize < size' failed.
On Tuesday, 23 August 2022 at 18:50:14 UTC, mw wrote: Hi, I got an error message when my program exits (the main functionality is done, I guess the error happened during D runtime's cleanup) : allocatestack.c:384: advise_stack_range: Assertion `freesize < size' failed. I suspect it somehow related to I pass some (object) pointers to foreign languages containers (C and Rust). But my main program seems behave correctly (I keep those pointers on the D side to prevent them from being GC-ed), this error only happens when the program exits. Anyone can give me some hint where I should look at? (and where is the allocatestack.c?) Thanks. allocatestack.c is some thing of GLIBC, the line seems to match [1] but I don't think that will help you much. You will need to get a trace where the function is called. [1] https://code.woboq.org/userspace/glibc/nptl/allocatestack.c.html
what's this error: allocatestack.c:384: advise_stack_range: Assertion `freesize < size' failed.
Hi, I got an error message when my program exits (the main functionality is done, I guess the error happened during D runtime's cleanup) : allocatestack.c:384: advise_stack_range: Assertion `freesize < size' failed. I suspect it somehow related to I pass some (object) pointers to foreign languages containers (C and Rust). But my main program seems behave correctly (I keep those pointers on the D side to prevent them from being GC-ed), this error only happens when the program exits. Anyone can give me some hint where I should look at? (and where is the allocatestack.c?) Thanks.
Re: How to escape control characters?
On 8/23/22 6:09 AM, Bastiaan Veelo wrote: On Thursday, 31 March 2016 at 03:15:49 UTC, cy wrote: This might be a dumb question. How do I format a string so that all the newlines print as \n and all the tabs as \t and such? The easiest is this: ```d import std.conv; string str = `Hello "World" line 2`; writeln([str].text[2..$-2]); // Hello \"World\"\nline 2 ``` I know this is an old post, but I felt this trick needed to be shared. This takes advantage of the fact that `std.format` escapes the characters in an array of strings. So we create an array where `str` is the only element, and convert that to text. Without the `[2..$-2]` slicing the output would be `["Hello \"World\"\nline 2"]`. A slightly more efficient implementation is ```d string escape(string s) { import std.array : appender; import std.format : FormatSpec, formatValue; FormatSpec!char f; auto w = appender!string; w.reserve(s.length); formatValue(w, [s], f); return w[][2 .. $ - 2]; } ``` Without allocations. This took me longer than I had hoped it would. It needs the 1-char buffer to avoid sending the surrounding quotes. ```d struct EscapedString { string[1] str; this(string str) @nogc pure nothrow @safe { this.str[0] = str; } void toString(Out)(auto ref Out output) { import std.format; import std.range; char buf; // 0xff => empty, 0x0, empty, but not first void putter(const(char)[] data) { if(!data.length) return; if(buf != 0xff) { if(buf) put(output, buf); } else // skip first " data = data[1 .. $]; if(!data.length){ buf = 0; return; } put(output, data[0 .. $-1]); buf = data[$-1]; } scope x = formattedWrite(x, "%(%s%)", str[]); } } ``` It would be nice to expose the escaping functionality from format so this kind of trickery isn't necessary. -Steve
Re: How to escape control characters?
On Thursday, 31 March 2016 at 03:15:49 UTC, cy wrote: This might be a dumb question. How do I format a string so that all the newlines print as \n and all the tabs as \t and such? The easiest is this: ```d import std.conv; string str = `Hello "World" line 2`; writeln([str].text[2..$-2]); // Hello \"World\"\nline 2 ``` I know this is an old post, but I felt this trick needed to be shared. This takes advantage of the fact that `std.format` escapes the characters in an array of strings. So we create an array where `str` is the only element, and convert that to text. Without the `[2..$-2]` slicing the output would be `["Hello \"World\"\nline 2"]`. A slightly more efficient implementation is ```d string escape(string s) { import std.array : appender; import std.format : FormatSpec, formatValue; FormatSpec!char f; auto w = appender!string; w.reserve(s.length); formatValue(w, [s], f); return w[][2 .. $ - 2]; } ``` And the inverse: ```d string unescape(string s) { import std.format : FormatSpec, unformatValue; FormatSpec!char f; string str = `["` ~ s ~ `"]`; return unformatValue!(string[])(str, f)[0]; } ``` Perhaps `escape()` and `unescape()` should be part of `std.format` so that they can be refactored to use `std.format.internal.write.formatElement` directly, eliminating the conversion to array. -- Bastiaan.