← Back to team overview

kicad-developers team mailing list archive

Re: Bug: ThrowIOError with GetChars() formatting parameter

 

I now replaced the calls with wxString::Format() which is proven to
work reliably.
(see separate mail 'Patch: fix string formatting in ThrowIOError')

On 9 December 2015 at 09:15, Henner Zeller <h.zeller@xxxxxxx> wrote:
> 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


References