mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 21:59:14 +02:00
LazUtils, Translations unit: factored out locale name parsing code to a separate function GetLanguageIDFromLocaleName
This commit is contained in:
parent
1cab990a9d
commit
f2ce2e18e3
@ -188,6 +188,7 @@ var
|
|||||||
// if you don't use UTF-8, install a proper widestring manager and set this
|
// if you don't use UTF-8, install a proper widestring manager and set this
|
||||||
// to false.
|
// to false.
|
||||||
|
|
||||||
|
function GetLanguageIDFromLocaleName(LocaleName: string): TLanguageID;
|
||||||
function GetLanguageID: TLanguageID;
|
function GetLanguageID: TLanguageID;
|
||||||
|
|
||||||
function GetPOFilenameParts(const Filename: string; out AUnitName, Language: string): boolean;
|
function GetPOFilenameParts(const Filename: string; out AUnitName, Language: string): boolean;
|
||||||
@ -440,6 +441,61 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure NormalizeLanguageID(var LangID: TLanguageID);
|
||||||
|
begin
|
||||||
|
// Normalization rules:
|
||||||
|
// 1. LanguageCode cannot be empty. In this case fill ID with default value (en_US).
|
||||||
|
// 2. CountryCode can be empty if LanguageCode is not empty.
|
||||||
|
// 3. LangID is a combination of LanguageCode and non-empty CountryCode.
|
||||||
|
if LangID.LanguageCode = '' then
|
||||||
|
begin
|
||||||
|
LangID.LanguageCode := 'en';
|
||||||
|
LangID.CountryCode := 'US';
|
||||||
|
end;
|
||||||
|
LangID.LanguageID := LangID.LanguageCode;
|
||||||
|
if LangID.CountryCode <> '' then
|
||||||
|
LangID.LanguageID := LangID.LanguageID + '_' + LangID.CountryCode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetLanguageIDFromLocaleName(LocaleName: string): TLanguageID;
|
||||||
|
var
|
||||||
|
i, CurItemStart, CurItemLength: SizeInt;
|
||||||
|
FinishedParsing, IsDelimiter: boolean;
|
||||||
|
CurItemType: string;
|
||||||
|
begin
|
||||||
|
//Parse locale identifier. For reference its full syntax:
|
||||||
|
//Current: `language[_territory[.codeset]][@modifier]`
|
||||||
|
//Possible in future: `language[_territory][.codeset][@modifier]`
|
||||||
|
Result := Default(TLanguageID);
|
||||||
|
i := 1;
|
||||||
|
CurItemStart := 1;
|
||||||
|
CurItemType := 'L'; // Language is the first item in locale identifier
|
||||||
|
FinishedParsing := false;
|
||||||
|
while (i <= Length(LocaleName)) and (not FinishedParsing) do
|
||||||
|
begin
|
||||||
|
IsDelimiter := LocaleName[i] in ['_', '.', '@'];
|
||||||
|
if IsDelimiter or (i = Length(LocaleName)) then
|
||||||
|
begin
|
||||||
|
CurItemLength := i - CurItemStart;
|
||||||
|
// If the last string char is not delimiter, it belongs to current item, so adjust its length
|
||||||
|
if not IsDelimiter then
|
||||||
|
inc(CurItemLength);
|
||||||
|
case CurItemType of
|
||||||
|
'L': Result.LanguageCode := Copy(LocaleName, CurItemStart, CurItemLength);
|
||||||
|
'_': Result.CountryCode := Copy(LocaleName, CurItemStart, CurItemLength);
|
||||||
|
'.': ; // We don't need codeset currently
|
||||||
|
end;
|
||||||
|
CurItemType := LocaleName[i];
|
||||||
|
// We don't use modifier currently, but know that it is the last in locale identifier
|
||||||
|
if CurItemType = '@' then
|
||||||
|
FinishedParsing := true;
|
||||||
|
CurItemStart := i + 1;
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
NormalizeLanguageID(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
function GetLanguageID: TLanguageID;
|
function GetLanguageID: TLanguageID;
|
||||||
{$IFDEF Windows}
|
{$IFDEF Windows}
|
||||||
procedure GetLanguage;
|
procedure GetLanguage;
|
||||||
@ -467,13 +523,13 @@ function GetLanguageID: TLanguageID;
|
|||||||
|
|
||||||
RetrieveLocaleInfo(LOCALE_SISO639LANGNAME, Result.LanguageCode);
|
RetrieveLocaleInfo(LOCALE_SISO639LANGNAME, Result.LanguageCode);
|
||||||
RetrieveLocaleInfo(LOCALE_SISO3166CTRYNAME, Result.CountryCode);
|
RetrieveLocaleInfo(LOCALE_SISO3166CTRYNAME, Result.CountryCode);
|
||||||
|
|
||||||
|
NormalizeLanguageID(Result);
|
||||||
end;
|
end;
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
procedure GetLanguage;
|
procedure GetLanguage;
|
||||||
var
|
var
|
||||||
i, CurItemStart, CurItemLength: SizeInt;
|
EnvVarContents: string;
|
||||||
FinishedParsing, IsDelimiter: boolean;
|
|
||||||
CurItemType, EnvVarContents: string;
|
|
||||||
begin
|
begin
|
||||||
EnvVarContents := GetEnvironmentVariable('LC_ALL');
|
EnvVarContents := GetEnvironmentVariable('LC_ALL');
|
||||||
if Length(EnvVarContents) = 0 then
|
if Length(EnvVarContents) = 0 then
|
||||||
@ -486,51 +542,13 @@ function GetLanguageID: TLanguageID;
|
|||||||
exit; // no language defined via environment variables
|
exit; // no language defined via environment variables
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Result := GetLanguageIDFromLocaleName(EnvVarContents);
|
||||||
//Parse locale identifier. For reference its full syntax:
|
|
||||||
//Current: `language[_territory[.codeset]][@modifier]`
|
|
||||||
//Possible in future: `language[_territory][.codeset][@modifier]`
|
|
||||||
i := 1;
|
|
||||||
CurItemStart := 1;
|
|
||||||
CurItemType := 'L'; // Language is the first item in locale identifier
|
|
||||||
FinishedParsing := false;
|
|
||||||
while (i <= Length(EnvVarContents)) and (not FinishedParsing) do
|
|
||||||
begin
|
|
||||||
IsDelimiter := EnvVarContents[i] in ['_', '.', '@'];
|
|
||||||
if IsDelimiter or (i = Length(EnvVarContents)) then
|
|
||||||
begin
|
|
||||||
CurItemLength := i - CurItemStart;
|
|
||||||
// If the last string char is not delimiter, it belongs to current item, so adjust its length
|
|
||||||
if not IsDelimiter then
|
|
||||||
inc(CurItemLength);
|
|
||||||
case CurItemType of
|
|
||||||
'L': Result.LanguageCode := Copy(EnvVarContents, CurItemStart, CurItemLength);
|
|
||||||
'_': Result.CountryCode := Copy(EnvVarContents, CurItemStart, CurItemLength);
|
|
||||||
'.': ; // We don't need codeset currently
|
|
||||||
end;
|
|
||||||
CurItemType := EnvVarContents[i];
|
|
||||||
// We don't use modifier currently, but know that it is the last in locale identifier
|
|
||||||
if CurItemType = '@' then
|
|
||||||
FinishedParsing := true;
|
|
||||||
CurItemStart := i + 1;
|
|
||||||
end;
|
|
||||||
inc(i);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := Default(TLanguageID);
|
Result := Default(TLanguageID);
|
||||||
GetLanguage;
|
GetLanguage;
|
||||||
|
|
||||||
if Result.LanguageCode = '' then
|
|
||||||
begin
|
|
||||||
Result.LanguageCode := 'en';
|
|
||||||
Result.CountryCode := 'US';
|
|
||||||
end;
|
|
||||||
Result.LanguageID := Result.LanguageCode;
|
|
||||||
if Result.CountryCode <> '' then
|
|
||||||
Result.LanguageID := Result.LanguageID + '_' + Result.CountryCode;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetPOFilenameParts(const Filename: string; out AUnitName, Language: string): boolean;
|
function GetPOFilenameParts(const Filename: string; out AUnitName, Language: string): boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user