← Back to team overview

kicad-developers team mailing list archive

Re: Bug: ThrowIOError with GetChars() formatting parameter

 

On 9 December 2015 at 17:18, Wayne Stambaugh <stambaughw@xxxxxxxxx> wrote:
> On 12/6/2015 8:34 PM, Henner Zeller wrote:
>> On 4 December 2015 at 07:17, jp charras <jp.charras@xxxxxxxxxx> wrote:
>>> Le 04/12/2015 14:54, Wayne Stambaugh a écrit :
>>>> Thanks Henner.  I'll take a look at it when I get a chance.  I'm sure
>>>> this isn't the only place this pattern is used.  If you have a patch,
>>>> please submit it.
>>>>
>>>> Thanks,
>>>>
>>>> Wayne
>>>>
>>>> On 12/3/2015 3:46 AM, Henner Zeller wrote:
>>>>> Hi,
>>>>> Playing with the spectra import/export, I encountered a bug: in that
>>>>> code are constructs such as
>>>>>
>>>>>    ThrowIOError( _("some formatting %s"), GetChars( someWxString ));
>>>>>
>>>>> They are ultimately dealt with wxString::PrintfV( fmt, args );
>>>>>
>>>>> The output, however, is not as expected. A someWxString with "REF**"
>>>>> was only displayed as "R". Changing the GetChars() to TO_UTF8() works.
>>>>>
>>>>> I suspect that whatever is returned by GetChars() is not properly
>>>>> passed through the var-args argument, while the simple const char* of
>>>>> TO_UTF8() does work. I am not sure though if that is the 'right'
>>>>> solution as this might be different on Windows ? So I'll leave this to
>>>>> someone more knowledgeable in wxString quirks on different platforms
>>>
>>> @Henner,
>>>
>>> GetChars is a macro (defined in macros.h)
>>> It returns a wxChar*, which is the right type here.
>>>
>>> (GetChars was written to be equivalent to GetData(), during the time
>>> GetData(), needed when using wxString::Print(), was removed from
>>> wxWidgets, in a few 2.9.x versions)
>>>
>>> - How to reproduce this issue (it can be different on Linux and on Windows)?
>>
>> I don't have access to a windows machine to test, but I created a
>> simplified code in
>>    https://gist.github.com/hzeller/e377cc8be916b191d499
>> so that it can be tested and re-produced by others.
>>
>> This is the output:
>> $ g++ -Wall -o format-test -isystem
>> /usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -isystem
>> /usr/include/wx-3.0 -D__WXGTK__ format-test.cpp
>> -L/usr/lib/x86_64-linux-gnu/ -lwx_baseu-3.0 && ./format-test
>> Input: format:'this is a test >%s<' and value:'SomeTest value'
>> sizeof(wxChar) = 4
>> wxstring::PrintfV(fmt, GetChars())  : 'this is a test >S<'
>> wxstring::PrintfV(fmt, value.GetData())  : 'this is a test >'
>> wxstring::PrintfV(fmt, TO_UTF8())   : 'this is a test >SomeTest value<'
>> wxstring::Printf(fmt, wxstring)     : 'this is a test >SomeTest value<'
>> wxstring::Printf(fmt, GetChars(...)): 'this is a test >SomeTest value<'
>> wxstring::Printf(fmt, TO_UTF8(..))  : 'this is a test >SomeTest value<'
>>
>> So findings
>>   - using the PrintfV() with TO_UTF8() works (on my machine).
>>   - GetChars() only prints the first character, then stops (I presume
>> because that points to a multi-byte string, which has \0 every other
>> character but then is interpreted as const char* ?)
>>   - GetData() is worse.
>>   - wxstring::Printf() seems to work with whatever is thrown at it.
>>
>>> - What happens if you replace GetChars( someWxString ) by
>>> someWxString.GetData()?
>>
>> Second output above: it totally messes up the output.
>>
>> (this is on debian testing with wx 3.0)
>>
>
> I cannot even get it to build on msys1/mingw32 (gcc 4.7.2).  I get the
> following error:
>
> format-test.cpp:39:85: error: cannot pass objects of
> non-trivially-copyable type 'const class wxCStrData' through '...'

I was surprised that that compiles as well :) Maybe it is due to the
newer compiler on debian testing that does something magic ?
On my ubuntu laptop with g++ 4.9.1, it doesn't compile that line
either. But commenting that out, it shows the same output than on the
other Linux machines.

>
> Here is the output using msys2/mingw32 wxWidgets 3.0.2:
>
> Input: format:'this is a test >%s<' and value:'SomeTest value'
> sizeof(wxChar) = zd
> wxstring::PrintfV(fmt, GetChars())  : 'this is a test >SomeTest value<'
> wxstring::PrintfV(fmt, value.GetData())  : 'this is a test >�(<'
> wxstring::PrintfV(fmt, TO_UTF8())   : 'this is a test >潓敭敔瑳瘠污敵<'
> wxstring::Printf(fmt, wxstring)     : 'this is a test >SomeTest value<'
> wxstring::Printf(fmt, GetChars(...)): 'this is a test >SomeTest value<'
> wxstring::Printf(fmt, TO_UTF8(..))  : 'this is a test >SomeTest value<'
>
> here is the output using msys2/mingw64 wxWidgets 3.0.2:
>
> Input: format:'this is a test >%s<' and value:'SomeTest value'
> sizeof(wxChar) = zd
> wxstring::PrintfV(fmt, GetChars())  : 'this is a test >SomeTest value<'
> wxstring::PrintfV(fmt, value.GetData())  : 'this is a test >ﲐ"<'
> wxstring::PrintfV(fmt, TO_UTF8())   : 'this is a test >潓敭敔瑳瘠污敵<'
> wxstring::Printf(fmt, wxstring)     : 'this is a test >SomeTest value<'
> wxstring::Printf(fmt, GetChars(...)): 'this is a test >SomeTest value<'
> wxstring::Printf(fmt, TO_UTF8(..))  : 'this is a test >SomeTest value<'
>
> TO_UTF8() doesn't look like the answer either.  Also, %z is not
> supported on windows.

Yes, I think the size_t formatting character is a libc extension.

>  I so I changed it to %lu and the character size
> is 2 on windows.  It appears we have an conundrum.  GetChars() works on
> windows and UTF8() works on linux.  Is there yet a third option for OSX?
>  The joys of cross platform development.

:/

Interestingly, the  wxstring::Printf() seems to work in all cases,
even with wxstring as parameter which is a non-trivial type, so we
have to figure out what makes that wx implementation different. I
think they internally certainly will delegate as well to their
PrintfV(), so we have to find out what happens differently within the
wxstring code to be able to mimick the same.
(or replace the calls to the io-exception with varag parameter with a
call to wxString::Format()).

-h

>
>> -h
>>>
>>> --
>>> Jean-Pierre CHARRAS
>>>
>>> _______________________________________________
>>> Mailing list: https://launchpad.net/~kicad-developers
>>> Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
>>> Unsubscribe : https://launchpad.net/~kicad-developers
>>> More help   : https://help.launchpad.net/ListHelp
>>
>> _______________________________________________
>> Mailing list: https://launchpad.net/~kicad-developers
>> Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
>> Unsubscribe : https://launchpad.net/~kicad-developers
>> More help   : https://help.launchpad.net/ListHelp
>>
>
> _______________________________________________
> Mailing list: https://launchpad.net/~kicad-developers
> Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help   : https://help.launchpad.net/ListHelp


Follow ups

References