Re: How to escape control characters?

2022-08-23 Thread Salih Dincer via Digitalmars-d-learn
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.

2022-08-23 Thread frame via Digitalmars-d-learn

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.

2022-08-23 Thread mw via Digitalmars-d-learn

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?

2022-08-23 Thread Steven Schveighoffer via Digitalmars-d-learn

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?

2022-08-23 Thread Bastiaan Veelo via Digitalmars-d-learn

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.