[m-users.] string_writer / stream and writing strings with %s in them

Sean Charles (emacstheviking) objitsu at gmail.com
Sun Feb 13 20:49:39 AEDT 2022


I spoke to soon...my problem resurfaced and I have spent a good while tracking it down, finally, applying the Rule of Sherlock Holmes, it turned out to be here, this is what I had

wr_text(Text, !S) :-
    stream.string_writer.format(
        string.builder.handle, Text, [], !S).

it seems that I somehow decided I would use the text argument AS the format string, I have no idea what possessed me to do this, too many late nights hacking at this beast I guess. This is what I changed it to and it's perfect now:

wr_text(Text, !S) :-
    stream.string_writer.format(
        string.builder.handle, "%s", [s(Text)], !S).

and it's all wonderful again, I always have great faith in the compiler and trust it to do the right thing. This is a good start to the day for me, my test C program is now rendering once again,

WHEN I release this product and the millions come rolling in, there is going to be a great big party somewhere!

Thanks again Zoltan,
Sean.


> On 12 Feb 2022, at 22:07, Sean Charles (emacstheviking) <objitsu at gmail.com> wrote:
> 
> Yes.
> 
> I had a good old rethink about how I was going about it and it seems to be back on track now.
> Thanks again Zoltan.
> 
> 
>> On 12 Feb 2022, at 16:20, Sean Charles (emacstheviking) <objitsu at gmail.com <mailto:objitsu at gmail.com>> wrote:
>> 
>> I am looking for some insights / advice on the best way to handle what has temporarily become something of a recusrsive horror story this afternoon! In my transpiler, there may or may not be strings containing C style printf() format controls. This caught me out
>> 
>> Uncaught Mercury exception:
>> Software Error: string.format: The first conversion specifier, which uses specifier character `s', is missing its input.
>> 
>> once so I implemented:
>> 
>>     % C_String :: Escapes any % with %% in the string.
>>     %
>> :- func c_string(ps::in) = (string::out).
>> 
>> c_string(ps(_,X)) = string.format("""%s""", [s(c_string_(X))]).
>> 
>>     % TODO: is this a typeclasss ie.  things to be escaped ??
>> :- func c_string_(string::in) = (string::out).
>> 
>> 
>> 
>> Which works but....as I tested my way through, the problem is compounded by the recursive nature of the rendering stage, resulting in strings like this:
>> 
>>    printf("Hello %%%%%s", "World");
>> 
>> caused by each successive handler making sure it escapes strings before returning up the stack. 
>> When I print the code out I am using string.format() and of course that blew up mightily until I started using %%s in --my-- strings of source code.
>> 
>> I currently use stream.string_writer.format() for generating the final output.
>> 
>> I wondered what strategy the Mercury compiler uses as it must have addressed the same issue at some point? I've tried reading the code to no avail!  I am rethinking through my approach, so far it has all worked great but then.. strings with %s and any other string escape for the C grade is going to have the same issues.
>> 
>> Thanks,
>> Sean.
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20220213/2630e6df/attachment.html>


More information about the users mailing list