wx2stc() and stc2wx() moved to private.h in 2.9.x

40 views
Skip to first unread message

John Labenski

unread,
Oct 27, 2010, 5:49:54 PM10/27/10
to wx-...@lists.wxwidgets.org
I use wx2stc() and stc2wx() in C++ code to export the text to HTML,
RTF, etc and I notice that in 2.9 these functions have been moved to
include/wx/stc/private.h, which are the only two functions in it. I am
wondering why the change and if it would be possible to make them
public again by putting them back into stc.h? I would like to use them
for the same reason as the comment at the bottom of
src/src/PlatWX.cpp, they don't assert like the wxWidgets convert
functions (apparently?) do.

Regards,
John

Vadim Zeitlin

unread,
Oct 27, 2010, 6:16:32 PM10/27/10
to wx-...@googlegroups.com
On Wed, 27 Oct 2010 17:49:54 -0400 John Labenski <jlab...@gmail.com> wrote:

JL> I use wx2stc() and stc2wx() in C++ code to export the text to HTML,
JL> RTF, etc and I notice that in 2.9 these functions have been moved to
JL> include/wx/stc/private.h, which are the only two functions in it. I am
JL> wondering why the change and if it would be possible to make them
JL> public again by putting them back into stc.h? I would like to use them
JL> for the same reason as the comment at the bottom of
JL> src/src/PlatWX.cpp, they don't assert like the wxWidgets convert
JL> functions (apparently?) do.

I don't know anything about STC functions but wx conversion functions
don't assert and you should have no problem doing whatever you want with
them. OTOH I don't understand what does "more forgiving" mean in this
context, UTF-8 is either valid or not. And if it's not valid you need to
handle this somehow, in particular you can't just lose data silently.

Regards,
VZ

John Labenski

unread,
Oct 28, 2010, 4:16:30 PM10/28/10
to wx-...@googlegroups.com
On Wed, Oct 27, 2010 at 6:16 PM, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Wed, 27 Oct 2010 17:49:54 -0400 John Labenski <jlab...@gmail.com> wrote:
>
> JL> I use wx2stc() and stc2wx() in C++ code to export the text to HTML,
>
>  I don't know anything about STC functions but wx conversion functions
> don't assert and you should have no problem doing whatever you want with
> them. OTOH I don't understand what does "more forgiving" mean in this
> context, UTF-8 is either valid or not. And if it's not valid you need to
> handle this somehow, in particular you can't just lose data silently.

I know this has been covered a few times in the past, but I'm still a
little iffy about the best functions to use to convert from wxString
(ascii/unicode) to (const char*)/(std::string). The usage will be for
filenames and fopen(), where the wxString would be from a
wxFileSelector() in one case, but in the other cases the char string
should be 7 bit only.

Looking at the docs it seems like these are my options, I've ***ed the
ones that seem correct, is this true?

const char* (or wxCharBuffer) wxString::ToAscii() (which calls c_str()
and docs suggest that I use mb_char())
*** wxCharBuffer wxString::mb_char()

static wxString wxString::FromAscii(const char*) (which calls the
constructor below)
*** wxString(const char*) constructor

------------------------------------------------------------

Similarly, I used to use something like this, but simplified.

wxString s = bool ? wxString("hello").wx_str() : wxEmptyString;

I now get an error since wxString::wx_str() returns a
(wxStringCharType*) and wxEmptyString is (wxChar*). I can simply
remove the wx_str() and change wxEmptyString to wxString() to fix it,
but the message "conversion from 'const void*'" is odd since
wxStringCharType is either wchar_t or char and wxChar is
__WCHAR_TYPE__ which gcc 4.4.1 apparently defines, to void*? Is this
last part right?

error: conditional expression between distinct pointer types 'const
wxStringCharType*' and 'const wxChar*' lacks a cast
error: conversion from 'const void*' to 'wxString' is ambiguous
include/wx/string.h:1307: note: candidates are:
wxString::wxString(const wchar_t*) <near match>
include/wx/string.h:1294: note:
wxString::wxString(const unsigned char*) <near match>
include/wx/string.h:1281: note:
wxString::wxString(const char*) <near match>
include/wx/string.h:1275: note:
wxString::wxString(wchar_t, size_t) <near match>
include/wx/string.h:1271: note:
wxString::wxString(char, size_t) <near match>
include/wx/string.h:478: note: wxString::wxString(int)
<near match>

Regards,
John

Vadim Zeitlin

unread,
Oct 30, 2010, 3:24:53 PM10/30/10
to wx-...@googlegroups.com
On Thu, 28 Oct 2010 16:16:30 -0400 John Labenski <jlab...@gmail.com> wrote:

JL> I know this has been covered a few times in the past, but I'm still a
JL> little iffy about the best functions to use to convert from wxString
JL> (ascii/unicode) to (const char*)/(std::string). The usage will be for
JL> filenames and fopen()

This is a particularly ugly case because Windows uses UTF-16 for filenames
while modern Unix systems use UTF-8. So you actually don't have to convert
at all under Windows but need to use utf8_str() elsewhere. This is
abstracted by wxString::fn_str() function. Of course, you could also use
wx(F)File and similar wx classes and never use fopen() directly at all.
And I am pretty sure that STC functions don't help you at all here.

JL> where the wxString would be from a wxFileSelector() in one case, but in
JL> the other cases the char string should be 7 bit only.

It doesn't matter where does wxString come from.


JL> Looking at the docs it seems like these are my options, I've ***ed the
JL> ones that seem correct, is this true?

Sorry, I can't answer this. Options for what? For converting to file names
-- definitely not. What exactly are you trying to do?

JL> const char* (or wxCharBuffer) wxString::ToAscii() (which calls c_str()
JL> and docs suggest that I use mb_char())
JL> *** wxCharBuffer wxString::mb_char()

mb_char() doesn't even exist... You have mb_str(). But ToAscii() is not at
all equivalent to calling mb_str() because ToAscii() requires that the
string contains only 7 bit ASCII characters while mb_str() works with any
contents and converts it to "char*" string in the current locale encoding,
e.g. CP1252 under Windows or UTF-8 under Unix.

JL> static wxString wxString::FromAscii(const char*) (which calls the
JL> constructor below)
JL> *** wxString(const char*) constructor

FromAscii() doesn't use this ctor. FromAscii() requires 7 bit input. This
ctor uses the current locale encoding by default.


JL> Similarly, I used to use something like this, but simplified.
JL>
JL> wxString s = bool ? wxString("hello").wx_str() : wxEmptyString;

This is just too strange, why do you do this? What's wrong with

wxString s;
if ( bool )
s = "hello";

? Or, if you really want to use the ternary operator,

wxString s = bool ? wxString("hello") : wxString();

Regards,
VZ

John Labenski

unread,
Nov 2, 2010, 12:31:56 AM11/2/10
to wx-...@googlegroups.com
On Sat, Oct 30, 2010 at 3:24 PM, Vadim Zeitlin <va...@wxwidgets.org> wrote:
> On Thu, 28 Oct 2010 16:16:30 -0400 John Labenski <jlab...@gmail.com> wrote:
>
> abstracted by wxString::fn_str() function. Of course, you could also use
> wx(F)File and similar wx classes and never use fopen() directly at all.
> And I am pretty sure that STC functions don't help you at all here.

Ok, I will switch to the wx(F)File classes.

>  Sorry, I can't answer this. Options for what? For converting to file names
> -- definitely not. What exactly are you trying to do?

Trying to reuse code that uses only char* strings and C file
functions, but in my case the strings start as wxStrings.

> JL> const char* (or wxCharBuffer) wxString::ToAscii() (which calls c_str()
> JL> and docs suggest that I use mb_char())
> JL> *** wxCharBuffer wxString::mb_char()
>
>  mb_char() doesn't even exist... You have mb_str(). But ToAscii() is not at
> all equivalent to calling mb_str() because ToAscii() requires that the
> string contains only 7 bit ASCII characters while mb_str() works with any
> contents and converts it to "char*" string in the current locale encoding,
> e.g. CP1252 under Windows or UTF-8 under Unix.

My head will explode! I can try to wxize everything possible to avoid
as many conversions as possible.

> JL> Similarly, I used to use something like this, but simplified.
> JL>
> JL> wxString s = bool ? wxString("hello").wx_str() : wxEmptyString;
>
>  This is just too strange, why do you do this? What's wrong with

Because the wxString("hello") comes from somewhere else and already
exists as a wxString, I will switch the wxEmptyString to wxString().
If I remember correctly, I added wx_str() to fix a similar error from
some change between 2.2.->4->6->8?

Thanks,
John

Vadim Zeitlin

unread,
Nov 2, 2010, 6:22:42 AM11/2/10
to wx-...@googlegroups.com
On Tue, 2 Nov 2010 00:31:56 -0400 John Labenski <jlab...@gmail.com> wrote:

JL> >  Sorry, I can't answer this. Options for what? For converting to file names
JL> > -- definitely not. What exactly are you trying to do?
JL>
JL> Trying to reuse code that uses only char* strings and C file
JL> functions, but in my case the strings start as wxStrings.

The problem is that it's not enough to say "char* strings". This misses an
important piece of information: what encoding do they use? In theory, it
could be anything at all. In practice, it will always be either the current
locale encoding or UTF-8 (of course, the current locale may also happen to
use UTF-8 on a particular system but it won't always be UTF-8).

Also notice that you need to change this code if you want to work Unicode
files under Windows (and you do, because the programs that can't open a
file just because you named it in your own language really enrage the
users).

JL> > JL> const char* (or wxCharBuffer) wxString::ToAscii() (which calls c_str()
JL> > JL> and docs suggest that I use mb_char())
JL> > JL> *** wxCharBuffer wxString::mb_char()
JL> >
JL> >  mb_char() doesn't even exist... You have mb_str(). But ToAscii() is not at
JL> > all equivalent to calling mb_str() because ToAscii() requires that the
JL> > string contains only 7 bit ASCII characters while mb_str() works with any
JL> > contents and converts it to "char*" string in the current locale encoding,
JL> > e.g. CP1252 under Windows or UTF-8 under Unix.
JL>
JL> My head will explode! I can try to wxize everything possible to avoid
JL> as many conversions as possible.

I think it's really pretty simple, I must be bad at explaining it. You
just need to realize that you have different kinds of strings:

1. UTF-32 strings: These are strings using wchar_t under (typical) Unix.
2. UTF-16 strings: wchar_t strings under Windows.
3. UTF-8 strings: char* strings.
4. Strings in current locale encoding: char* strings too.

So you see that if you have a wchar_t string you know its encoding (knowing
your platform too). But if you have a char string you can't deduce its
encoding from just its type, you need to have some additional information.
Basically you need to know where does the string come from.

JL> > JL> Similarly, I used to use something like this, but simplified.


JL> > JL>
JL> > JL> wxString s = bool ? wxString("hello").wx_str() : wxEmptyString;

JL> >
JL> >  This is just too strange, why do you do this? What's wrong with
JL>
JL> Because the wxString("hello") comes from somewhere else and already
JL> exists as a wxString, I will switch the wxEmptyString to wxString().
JL> If I remember correctly, I added wx_str() to fix a similar error from
JL> some change between 2.2.->4->6->8?

No, wx_str() was only added in 2.9 (and backported to 2.8.10 I think).

Regards,
VZ

Reply all
Reply to author
Forward
0 new messages