BoolToStr() with correct locale output

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

BoolToStr() with correct locale output

Graeme Geldenhuys-4
Hi,

I'm busy translating our projects. fpGUI Toolkit uses it's own
translation via .po files (similar to Lazarus projects). But now there
are some output that is not being translated because it is output from
the RTL. One such case is the output of BoolToStr().

How am I supposed to translate that, or must I implement my own
fpgBoolToStr() to fpGUI project?

My default locale is en_ZA.UTF-8.  Normally if I change the LANG
environment variable, my fpGUI based projects look for those language
translation .po files and if none is found, it reverts to the default
compiled locale (normally English, but other languages can be selected
as default)


========  Console output ==================
$ ./project1
True
False

$ export LANG=af_ZA

$ ./project1
True
False

$ locale
LANG=af_ZA
LC_CTYPE="af_ZA"
LC_NUMERIC="af_ZA"
LC_TIME=en_DK.UTF-8
LC_COLLATE="af_ZA"
LC_MONETARY="af_ZA"
LC_MESSAGES="af_ZA"
LC_PAPER="af_ZA"
LC_NAME="af_ZA"
LC_ADDRESS="af_ZA"
LC_TELEPHONE="af_ZA"
LC_MEASUREMENT="af_ZA"
LC_IDENTIFICATION="af_ZA"
LC_ALL=

==========================



=============  project1.pas  ===============
program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, Sysutils;

var
  b: Boolean;
begin
  b := True;
  writeln(BoolToStr(b, True));
  b := False;
  writeln(BoolToStr(b, True));
end.
============================================


Regards,
  - Graeme -

_______________________________________________________
fpGUI - a cross-platform GUI toolkit using Free Pascal
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Michael Van Canneyt


On Fri, 26 Jun 2009, Graeme Geldenhuys wrote:

> Hi,
>
> I'm busy translating our projects. fpGUI Toolkit uses it's own
> translation via .po files (similar to Lazarus projects). But now there
> are some output that is not being translated because it is output from
> the RTL. One such case is the output of BoolToStr().
>
> How am I supposed to translate that, or must I implement my own
> fpgBoolToStr() to fpGUI project?

No. The Boolean strings are exposed in from the sysutils unit,
see TrueBoolStr, FalseBoolStr. The first string in those arrays
is used. If there are no elements in those arrays, they are
initialized with 'True' and 'False'.

So all you need to do is initialize them with the localized versions
prior to the first call of BoolToStr().

Michael.

>
> My default locale is en_ZA.UTF-8.  Normally if I change the LANG
> environment variable, my fpGUI based projects look for those language
> translation .po files and if none is found, it reverts to the default
> compiled locale (normally English, but other languages can be selected
> as default)
>
>
> ========  Console output ==================
> $ ./project1
> True
> False
>
> $ export LANG=af_ZA
>
> $ ./project1
> True
> False
>
> $ locale
> LANG=af_ZA
> LC_CTYPE="af_ZA"
> LC_NUMERIC="af_ZA"
> LC_TIME=en_DK.UTF-8
> LC_COLLATE="af_ZA"
> LC_MONETARY="af_ZA"
> LC_MESSAGES="af_ZA"
> LC_PAPER="af_ZA"
> LC_NAME="af_ZA"
> LC_ADDRESS="af_ZA"
> LC_TELEPHONE="af_ZA"
> LC_MEASUREMENT="af_ZA"
> LC_IDENTIFICATION="af_ZA"
> LC_ALL=
>
> ==========================
>
>
>
> =============  project1.pas  ===============
> program project1;
>
> {$mode objfpc}{$H+}
>
> uses
>  {$IFDEF UNIX}{$IFDEF UseCThreads}
>  cthreads,
>  {$ENDIF}{$ENDIF}
>  Classes, Sysutils;
>
> var
>  b: Boolean;
> begin
>  b := True;
>  writeln(BoolToStr(b, True));
>  b := False;
>  writeln(BoolToStr(b, True));
> end.
> ============================================
>
>
> Regards,
>  - Graeme -
>
> _______________________________________________________
> fpGUI - a cross-platform GUI toolkit using Free Pascal
> http://opensoft.homeip.net/fpgui/
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
Michael Van Canneyt wrote:
>
> So all you need to do is initialize them with the localized versions
> prior to the first call of BoolToStr().

Thanks Michael.  Now the other obvious question, why is TrueBoolStrs and
FalseBoolStrs array types?  Why not simply of type String?


  SetLength(TrueBoolStrs,1);
  TrueBoolStrs[0] := 'Waar';

  SetLength(FalseBoolStrs,1);
  FalseBoolStrs[0] := 'Onwaar';


Looking at the implementation of BoolToStr(), it only ever uses the
first element. Reading the fpdoc help on BoolToStr and FalseBoolStrs it
doesn't mention anything about why the are defined as arrays and what
the other elements (if more than one) is used for.


Regards,
  - Graeme -

_______________________________________________________
fpGUI - a cross-platform GUI toolkit using Free Pascal
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Michael Van Canneyt


On Fri, 26 Jun 2009, Graeme Geldenhuys wrote:

> Michael Van Canneyt wrote:
>>
>> So all you need to do is initialize them with the localized versions
>> prior to the first call of BoolToStr().
>
> Thanks Michael.  Now the other obvious question, why is TrueBoolStrs and
> FalseBoolStrs array types?  Why not simply of type String?
>
>
>  SetLength(TrueBoolStrs,1);
>  TrueBoolStrs[0] := 'Waar';
>
>  SetLength(FalseBoolStrs,1);
>  FalseBoolStrs[0] := 'Onwaar';
>
>
> Looking at the implementation of BoolToStr(), it only ever uses the
> first element. Reading the fpdoc help on BoolToStr and FalseBoolStrs it
> doesn't mention anything about why the are defined as arrays and what
> the other elements (if more than one) is used for.

StrToBool should use all elements ?

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
Michael Van Canneyt wrote:
>
> StrToBool should use all elements ?

In FPC 2.2.5 it does not.

============ implementation  =====================
begin
 if UseBoolStrs Then
  begin
    CheckStrs;
    if B then
      Result:=TrueBoolStrs[0]
    else
      Result:=FalseBoolStrs[0];
  end
 else
  If B then
    Result:='-1'
  else
    Result:='0';
end;
======================================


Regards,
  - Graeme -

_______________________________________________________
fpGUI - a cross-platform GUI toolkit using Free Pascal
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
In reply to this post by Michael Van Canneyt
Michael Van Canneyt wrote:
>
> StrToBool should use all elements ?

In FPC 2.3.x (latest trunk) in also doesn't. Looks indentical to 2.2.5


Regards,
  - Graeme -

_______________________________________________________
fpGUI - a cross-platform GUI toolkit using Free Pascal
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Vincent Snijders-2
In reply to this post by Graeme Geldenhuys-4
Graeme Geldenhuys schreef:

> Michael Van Canneyt wrote:
>> StrToBool should use all elements ?
>
> In FPC 2.2.5 it does not.
>
> ============ implementation  =====================
> begin
>  if UseBoolStrs Then
>   begin
>     CheckStrs;
>     if B then
>       Result:=TrueBoolStrs[0]
>     else
>       Result:=FalseBoolStrs[0];
>   end
>  else
>   If B then
>     Result:='-1'
>   else
>     Result:='0';
> end;
> ======================================

Please add the declaration, to make sure it is StrToBool

Vincent
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
Vincent Snijders wrote:
>
> Please add the declaration, to make sure it is StrToBool

I'm not that blind. :-)  And the function in question in BoolToStr().
But now that you mention StrToBool(), that is even worse, it hard-codes
the 'FALSE' and 'TRUE' and doesn't even use the arrays.

How come nobody ever noticed this? Does everybody only write English
programs. :-)

==================================
function BoolToStr(B: Boolean;UseBoolStrs:Boolean=False): string;

procedure CheckStrs;
begin
    If Length(TrueBoolStrs)=0 then
      begin
        SetLength(TrueBoolStrs,1);
        TrueBoolStrs[0]:='True';
      end;
    If Length(FalseBoolStrs)=0 then
      begin
        SetLength(FalseBoolStrs,1);
        FalseBoolStrs[0]:='False';
      end;
end;

begin
 if UseBoolStrs Then
  begin
    CheckStrs;
    if B then
      Result:=TrueBoolStrs[0]
    else
      Result:=FalseBoolStrs[0];
  end
 else
  If B then
    Result:='-1'
  else
    Result:='0';
end;


==================================

function TryStrToBool(const S: string; out Value: Boolean): Boolean;
Var
  Temp : String;
  D : Double;
  Code: word;
begin
  Temp:=upcase(S);
  Val(temp,D,code);
  Result:=true;
  If Code=0 then
    Value:=(D<>0.0)
  else If Temp='TRUE' then
    Value:=true
  else if Temp='FALSE' then
    Value:=false
  else
    Result:=false;
end;

==================================



Regards,
  - Graeme -

_______________________________________________________
fpGUI - a cross-platform GUI toolkit using Free Pascal
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Vincent Snijders-2
Graeme Geldenhuys schreef:
> Vincent Snijders wrote:
>> Please add the declaration, to make sure it is StrToBool
>
> I'm not that blind. :-)  And the function in question in BoolToStr().
> But now that you mention StrToBool(), that is even worse, it hard-codes

I did not mention StrToBool first, Michael did, and you seemed to ignore
that.

Vincent
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Henry Vermaak
In reply to this post by Graeme Geldenhuys-4
2009/6/26 Graeme Geldenhuys <[hidden email]>:
>
> How come nobody ever noticed this? Does everybody only write English
> programs. :-)

Because it's so simple/trivial that everyone rolls their own for user
interfaces?  I know I do.

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Vincent Snijders-2
In reply to this post by Graeme Geldenhuys-4
Graeme Geldenhuys schreef:

> How come nobody ever noticed this? Does everybody only write English
> programs. :-)
>

Because I always thought these function were not for users, but for
systems, for example to store a boolean in a xml file or to create an
adhoc dynamic SQL query. You would not want to have those strings
translated (unless it an MS-Access system of last century).

Vincent
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Henry Vermaak
2009/6/26 Vincent Snijders <[hidden email]>:

> Graeme Geldenhuys schreef:
>
>> How come nobody ever noticed this? Does everybody only write English
>> programs. :-)
>>
>
> Because I always thought these function were not for users, but for systems,
> for example to store a boolean in a xml file or to create an adhoc dynamic
> SQL query. You would not want to have those strings translated (unless it an
> MS-Access system of last century).

I think even for config/system files they are useless, since it's a
lot more friendly to support yes/no, true/false and on/off, not just
true/false.  I presume these functions are there for Delphi
compatibility?

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
In reply to this post by Vincent Snijders-2
Vincent Snijders wrote:
>
> I did not mention StrToBool first, Michael did, and you seemed to ignore
> that.

Sorry, that one slipped by me unnoticed....


 
Regards,
 - Graeme -

________________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
In reply to this post by Vincent Snijders-2
Vincent Snijders wrote:
>
> Because I always thought these function were not for users, but for
> systems, for example to store a boolean in a xml file or to create an

Your example is a good one and I agree there, but I do think it's for users to. For example, the whole reason I noticed the translation issue, was in my TStringGrid mediator. I displayed records (actually objects) that have a IsActive boolean property. The display mediator I use translates booleans to strings, displays TDateTime in the user specific format, displays TDateTime = 0 (ridiculous 1899-12-30 date) into something more user understandable, displays currencies as the users specified etc... Anyway, all worked except for the English True/False strings (from TTaxRate.IsActive property) return by BoolToStr() which should have been in Afrikaans. Or at least I expected it to be in Afrikaans or whatever other locale was active.

 
Regards,
 - Graeme -

________________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Graeme Geldenhuys-4
In reply to this post by Henry Vermaak
Henry Vermaak wrote:
>
> I think even for config/system files they are useless, since it's a
> lot more friendly to support yes/no, true/false and on/off, not just
> true/false.

Maybe that was the idea behind the TrueBoolStrs array. Element 0 is true/false, element 1 maybe yes/no, element 3 maybe on/off....?  Either way, I did not find any documentation why there is an array used or what should actually be in it. The implementation of BoolToStr and StrToBool does give any clues either, because they always use element 0 or a hardcoded string value in English.

So I take it you agree with Vincent, that I should basically never user BoolToStr or StrToBool for user displayed values and rather duplicate the code in my own application which supports translated values?  And then use the SysUtils version for config files or database stored value?
Again, nothing like this is hinted at in the documentation. I'll double check on Monday what the Kylix 3 help says regarding BoolToStr and StrToBool and localization and when it should actually be used.
 
Regards,
 - Graeme -

________________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

John Coppens
In reply to this post by Henry Vermaak
On Fri, 26 Jun 2009 15:54:55 +0100
Henry Vermaak <[hidden email]> wrote:

> > How come nobody ever noticed this? Does everybody only write English
> > programs. :-)

I _hate_ to think of the consequences of localization of those strings.
Have we had enough of the . and , problem? I don't think we need another
cause for incompatibilities in data files. Localization should be done by
the application program which assigns a meaning to the variable, not by
Pascal.

Boolean values tend to represent too many things, apart from TRUE and
FALSE. Like FULL and EMPTY, FAST and SLOW, and so on. To me it makes
sense that booleans are stored as bits, and, if _really_ necessary, shown
as TRUE or FALSE, mainly for debugging purposes. Wirth's Pascal definition
specifies the use of TRUE and FALSE.

Just my $.02

John
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Giuliano Colla
In reply to this post by Graeme Geldenhuys-4
Graeme Geldenhuys ha scritto:
> Again, nothing like this is hinted at in the documentation. I'll double
> check on Monday what the Kylix 3 help says regarding BoolToStr and
> StrToBool and localization and when it should actually be used.
>
Kylix 3 help on TrueBoolStrs variable specifies:
<quote>
When using the BoolToString function, true values are converted to the
first string of the list. When using the StrToBool function, any string
in the list is converted to true.
</quote>
The same for FalseBoolStrs variable, of course.

Apparently the mechanism is intended to convert from human
understandable or localized strings to standardized TRUE/FALSE strings.
The opposite of what you needed. No wonder it fails for you.

--
Giuliano Colla

Whenever people agree with me, I always feel I must be wrong (O. Wilde)
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: BoolToStr() with correct locale output

Michael Van Canneyt


On Fri, 26 Jun 2009, Giuliano Colla wrote:

> Graeme Geldenhuys ha scritto:
>> Again, nothing like this is hinted at in the documentation. I'll double
>> check on Monday what the Kylix 3 help says regarding BoolToStr and
>> StrToBool and localization and when it should actually be used.
>>
> Kylix 3 help on TrueBoolStrs variable specifies:
> <quote>
> When using the BoolToString function, true values are converted to the first
> string of the list. When using the StrToBool function, any string in the list
> is converted to true.
> </quote>
> The same for FalseBoolStrs variable, of course.
>
> Apparently the mechanism is intended to convert from human understandable or
> localized strings to standardized TRUE/FALSE strings. The opposite of what
> you needed. No wonder it fails for you.

But there is a bug in strtobool: it does not check all elements in the list.
(in fact, none) So that must be fixed.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal