[fpc-devel] Unix internationalization patch
petr.kristan at epos.cz
petr.kristan at epos.cz
Tue Apr 8 15:54:15 CEST 2008
Hi.
Today i wrote code for filling formating variables in unix. I tested it
only on Linux. I'm not sure with integration into unix/sysutils.pp and using
libc. Patch is in the attachment.
Petr
--
Ing. Petr Kristan
.
EPOS PRO s.r.o., Bozeny Nemcove 2625, 530 02 Pardubice
tel: +420 466335223 Czech Republic (Eastern Europe)
fax: +420 466510709
-------------- next part --------------
Index: unix/sysutils.pp
===================================================================
--- unix/sysutils.pp (revision 10611)
+++ unix/sysutils.pp (working copy)
@@ -793,7 +793,201 @@
end ;
{$endif}
+Const
+ clib = 'c';
+ __LC_CTYPE = 0;
+ __LC_NUMERIC = 1;
+ __LC_TIME = 2;
+ __LC_COLLATE = 3;
+ __LC_MONETARY = 4;
+ __LC_MESSAGES = 5;
+ __LC_ALL = 6;
+
+
+ ABDAY_1 = (__LC_TIME shl 16);
+ DAY_1 = (ABDAY_1)+7;
+ ABMON_1 = (ABDAY_1)+14;
+ MON_1 = (ABDAY_1)+26;
+ AM_STR = (ABDAY_1)+38;
+ PM_STR = (ABDAY_1)+39;
+ D_T_FMT = (ABDAY_1)+40;
+ D_FMT = (ABDAY_1)+41;
+ T_FMT = (ABDAY_1)+42;
+ T_FMT_AMPM = (ABDAY_1)+43;
+
+ __DECIMAL_POINT = (__LC_NUMERIC shl 16);
+ RADIXCHAR = __DECIMAL_POINT;
+ __THOUSANDS_SEP = (__DECIMAL_POINT)+1;
+
+ __INT_CURR_SYMBOL = (__LC_MONETARY shl 16);
+ __CURRENCY_SYMBOL = (__INT_CURR_SYMBOL)+1;
+ __MON_DECIMAL_POINT = (__INT_CURR_SYMBOL)+2;
+ __MON_THOUSANDS_SEP = (__INT_CURR_SYMBOL)+3;
+ __MON_GROUPING = (__INT_CURR_SYMBOL)+4;
+ __POSITIVE_SIGN = (__INT_CURR_SYMBOL)+5;
+ __NEGATIVE_SIGN = (__INT_CURR_SYMBOL)+6;
+ __INT_FRAC_DIGITS = (__INT_CURR_SYMBOL)+7;
+ __FRAC_DIGITS = (__INT_CURR_SYMBOL)+8;
+ __P_CS_PRECEDES = (__INT_CURR_SYMBOL)+9;
+ __P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+10;
+ __N_CS_PRECEDES = (__INT_CURR_SYMBOL)+11;
+ __N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+12;
+ __P_SIGN_POSN = (__INT_CURR_SYMBOL)+13;
+ __N_SIGN_POSN = (__INT_CURR_SYMBOL)+14;
+ _NL_MONETARY_CRNCYSTR = (__INT_CURR_SYMBOL)+15;
+
+function setlocale(category: cint; locale: pchar): pchar; cdecl; external clib name 'setlocale';
+function nl_langinfo(__item: cint):Pchar;cdecl;external clib name 'nl_langinfo';
+
+procedure GetFormatSettings;
+
+ function GetLocaleStr(item: cint): string;
+ begin
+ GetLocaleStr := AnsiString(nl_langinfo(item));
+ end;
+
+ function GetLocaleChar(item: cint): char;
+ begin
+ GetLocaleChar := nl_langinfo(item)^;
+ end;
+
+ function FindSeparator(const s: string; Def: char): char;
+ var
+ i, l: integer;
+ begin
+ FindSeparator := Def;
+ i := Pos('%', s);
+ if i=0 then
+ Exit;
+ l := Length(s);
+ inc(i);
+ if (i<=l) and (s[i] in ['E', 'O']) then //possible modifier
+ inc(i);
+ inc(i);
+ if i<=l then
+ FindSeparator := s[i];
+ end;
+
+ function TransformFormatStr(const s: string): string;
+ var
+ i, l: integer;
+ begin
+ TransformFormatStr := '';
+ i := 1;
+ l := Length(s);
+ while i<=l do begin
+ if s[i]='%' then begin
+ inc(i);
+ if (i<=l) and (s[i] in ['E', 'O']) then //ignore modifier
+ inc(i);
+ if i>l then
+ Exit;
+ case s[i] of
+ 'a': TransformFormatStr := TransformFormatStr + 'ddd';
+ 'A': TransformFormatStr := TransformFormatStr + 'dddd';
+ 'b': TransformFormatStr := TransformFormatStr + 'mmm';
+ 'B': TransformFormatStr := TransformFormatStr + 'mmmm';
+ 'c': TransformFormatStr := TransformFormatStr + 'c';
+ //'C':
+ 'd': TransformFormatStr := TransformFormatStr + 'dd';
+ 'D': TransformFormatStr := TransformFormatStr + 'mm"/"dd"/"yy';
+ 'e': TransformFormatStr := TransformFormatStr + 'd';
+ 'F': TransformFormatStr := TransformFormatStr + 'yyyy-mm-dd';
+ 'g': TransformFormatStr := TransformFormatStr + 'yy';
+ 'G': TransformFormatStr := TransformFormatStr + 'yyyy';
+ 'h': TransformFormatStr := TransformFormatStr + 'mmm';
+ 'H': TransformFormatStr := TransformFormatStr + 'hh';
+ 'I': TransformFormatStr := TransformFormatStr + 'hhampm';
+ //'j':
+ 'k': TransformFormatStr := TransformFormatStr + 'h';
+ 'l': TransformFormatStr := TransformFormatStr + 'hampm';
+ 'm': TransformFormatStr := TransformFormatStr + 'mm';
+ 'M': TransformFormatStr := TransformFormatStr + 'nn';
+ 'n': TransformFormatStr := TransformFormatStr + sLineBreak;
+ 'p': TransformFormatStr := TransformFormatStr + 'ampm';
+ 'P': TransformFormatStr := TransformFormatStr + 'ampm';
+ 'r': TransformFormatStr := TransformFormatStr + 'hhampm:nn:ss';
+ 'R': TransformFormatStr := TransformFormatStr + 'hh:nn';
+ //'s':
+ 'S': TransformFormatStr := TransformFormatStr + 'ss';
+ 't': TransformFormatStr := TransformFormatStr + #9;
+ 'T': TransformFormatStr := TransformFormatStr + 'hh:nn:ss';
+ //'u':
+ //'U':
+ //'V':
+ //'w':
+ //'W':
+ 'x': TransformFormatStr := TransformFormatStr + 'ddddd';
+ 'X': TransformFormatStr := TransformFormatStr + 't';
+ 'y': TransformFormatStr := TransformFormatStr + 'yy';
+ 'Y': TransformFormatStr := TransformFormatStr + 'yyyy';
+ //'z':
+ //'Z':
+ '%': TransformFormatStr := TransformFormatStr + '%';
+ end;
+ end else
+ TransformFormatStr := TransformFormatStr + s[i];
+ inc(i);
+ end;
+ end;
+
+const
+ // sign prec sep
+ NegFormatsTable: array [0..4, 0..1, 0..1] of byte = (
+ ( (4, 15), (0, 14) ), //Parentheses surround the quantity and currency_symbol
+ ( (5, 8), (1, 9) ), //The sign string precedes the quantity and currency_symbol
+ ( (7, 10), (3, 11) ), //The sign string follows the quantity and currency_symbol
+ ( (6, 13), (1, 9) ), //The sign string immediately precedes the currency_symbol
+ ( (7, 10), (2, 12) ) //The sign string immediately follows the currency_symbol
+ );
+var
+ i: integer;
+ prec, sep, signp: byte;
+begin
+ setlocale(__LC_ALL,'');
+ for i := 1 to 12 do
+ begin
+ ShortMonthNames[i]:=GetLocaleStr(ABMON_1+i-1);
+ LongMonthNames[i]:=GetLocaleStr(MON_1+i-1);
+ end;
+ for i := 1 to 7 do
+ begin
+ ShortDayNames[i]:=GetLocaleStr(ABDAY_1+i-1);
+ LongDayNames[i]:=GetLocaleStr(DAY_1+i-1);
+ end;
+ //Date stuff
+ ShortDateFormat := GetLocaleStr(D_FMT);
+ DateSeparator := FindSeparator(ShortDateFormat, DateSeparator);
+ ShortDateFormat := TransformFormatStr(ShortDateFormat);
+ LongDateFormat := GetLocaleStr(D_T_FMT);
+ LongDateFormat := TransformFormatStr(LongDateFormat);
+ //Time stuff
+ TimeAMString := GetLocaleStr(AM_STR);
+ TimePMString := GetLocaleStr(PM_STR);
+ ShortTimeFormat := GetLocaleStr(T_FMT);
+ TimeSeparator := FindSeparator(ShortTimeFormat, TimeSeparator);
+ ShortTimeFormat := TransformFormatStr(ShortTimeFormat);
+ LongTimeFormat := GetLocaleStr(T_FMT_AMPM);
+ LongTimeFormat := TransformFormatStr(LongTimeFormat);
+ //Currency stuff
+ CurrencyString := GetLocaleStr(_NL_MONETARY_CRNCYSTR);
+ CurrencyString := Copy(CurrencyString, 2, Length(CurrencyString));
+ CurrencyDecimals := StrToIntDef(GetLocaleStr(__FRAC_DIGITS), CurrencyDecimals);
+ prec := byte(GetLocaleChar(__P_CS_PRECEDES));
+ sep := byte(GetLocaleChar(__P_SEP_BY_SPACE));
+ if (prec<=1) and (sep<=1) then
+ CurrencyFormat := byte(not boolean(prec)) + sep shl 1;
+ prec := byte(GetLocaleChar(__N_CS_PRECEDES));
+ sep := byte(GetLocaleChar(__N_SEP_BY_SPACE));
+ signp := byte(GetLocaleChar(__N_SIGN_POSN));
+ if (signp in [0..4]) and (prec in [0, 1]) and (sep in [0, 1]) then
+ NegCurrFormat := NegFormatsTable[signp, prec, sep];
+ //Number stuff
+ ThousandSeparator:=GetLocaleChar(__THOUSANDS_SEP);
+ DecimalSeparator:=GetLocaleChar(RADIXCHAR);
+end;
+
Procedure InitAnsi;
Var
i : longint;
@@ -821,6 +1015,7 @@
begin
InitInternationalGeneric;
InitAnsi;
+ GetFormatSettings;
end;
function SysErrorMessage(ErrorCode: Integer): String;
More information about the fpc-devel
mailing list