PoChecker:

* don't skip formatting errors check even if translated string has no formatting arguments at all;
  * rewrite formatting arguments comparison function in order to make it more robust and detect invalid formatting arguments;
  * report formatting error even if arguments match, but some of them are invalid (only skip the case when original and translated strings exactly match, to not report e.g. '{%Region}' string);
  * regenerated translations, updated Russian translation.

git-svn-id: trunk@39771 -
This commit is contained in:
maxim 2013-01-05 17:15:40 +00:00
parent a4f6c3035e
commit 97a96b51f1
11 changed files with 81 additions and 59 deletions

View File

@ -1,7 +1,7 @@
# Arabic translation of Free Pascal Lazarus Project.
# Copyright (C) 2012 Lazarus Project
# This file is distributed under the same license as the Lazarus package.
# Khaled Shagrouni <shagrouni@gmail.com>, 2012.
Arabic translation of Free Pascal Lazarus Project.
Copyright (C) 2012 Lazarus Project
This file is distributed under the same license as the Lazarus package.
Khaled Shagrouni <shagrouni@gmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: Free Pascal Lazarus Project.\n"
@ -108,7 +108,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "المعرّف [%s] لم يتّم إيجاده في %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
#, fuzzy
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[السطر: %d] معطيات format() غير متوافقة ل:"
#: pocheckerconsts.slineinfilename
@ -207,4 +209,5 @@ msgstr "الترجمة"
#: pocheckerconsts.sunselectalltests
msgid "Unselect all tests"
msgstr "إزالة اختيار كل الإختبارات"
msgstr "إزالة اختيار كل الإختبارات"

View File

@ -101,7 +101,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "Identifikátor [%s] nenalezen v %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
#, fuzzy
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[Řádek %d] Nekompatibilní argumenty fce format() pro:"
#: pocheckerconsts.slineinfilename

View File

@ -91,7 +91,7 @@ msgid "Identifier [%s] not found in %s"
msgstr "Bezeichner [%s] nicht gefunden in %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr ""
#: pocheckerconsts.slineinfilename

View File

@ -63,7 +63,7 @@ msgstr "[Línea %d] %s"
#: pocheckerconsts.sduplicateoriginals
msgid "The (untranslated) value \"%s\" is used for more than 1 entry:"
msgstr "El valor (sin traducir) \"%s\ " se utiliza para más de 1 entrada:"
msgstr "El valor (sin traducir) \"%s \" se utiliza para más de 1 entrada:"
#: pocheckerconsts.serroroncleanup
msgid ""
@ -71,8 +71,8 @@ msgid ""
"%s\n"
"Please close the program\n"
msgstr ""
"A ocurrido\n un error irrecuperable"
"%s\n"
"A ocurrido\n"
" un error irrecuperable%s\n"
"Por favor, cierre la program\n"
#: pocheckerconsts.serroroncreate
@ -100,7 +100,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "Identificador [%s] no se encuentra en %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
#, fuzzy
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[Línea: %d] format() argumentos incompatibles para:"
#: pocheckerconsts.slineinfilename

View File

@ -1,4 +1,4 @@
# Valdas Jankunas <zmuogs@gmail.com>, 2012.
Valdas Jankunas <zmuogs@gmail.com>, 2012.
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
@ -9,8 +9,7 @@ msgstr ""
"Language: lt\n"
"Content-Transfer-Encoding: 8bit\n"
"MIME-Version: 1.0\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%"
"100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Lokalize 1.5\n"
#: pocheckerconsts.rspochecker
@ -104,7 +103,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "Ieškota identifikatoriaus [%s], tačiau %s jo neturi"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
#, fuzzy
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[Eilutė: %d] Nesuderinamų „format()“ argumentų turi:"
#: pocheckerconsts.slineinfilename
@ -205,4 +206,3 @@ msgstr "Vertimas"
msgid "Unselect all tests"
msgstr "Naikinti testavimų žymėjimą"

View File

@ -83,7 +83,7 @@ msgid "Identifier [%s] not found in %s"
msgstr ""
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr ""
#: pocheckerconsts.slineinfilename

View File

@ -19,7 +19,7 @@ msgid ""
"%s\n"
"for selected file\n"
"%s\n"
msgstr "Impossível localizar o arquivo po mestre:\n"
msgstr "Impossível localizar o arquivo po mestre:"
#: pocheckerconsts.scheckforduplicateuntranslatedvalues
msgid "Check for duplicate untranslated values"
@ -66,13 +66,13 @@ msgid ""
"An unrecoverable error occurred\n"
"%s\n"
"Please close the program\n"
msgstr "Ocorreu um erro irrecuperável\n"
msgstr "Ocorreu um erro irrecuperável"
#: pocheckerconsts.serroroncreate
msgid ""
"Error creating an instance of TPoFamily:\n"
"%s\n"
msgstr "Erro ao criar uma instância de TPoFamily:\n"
msgstr "Erro ao criar uma instância de TPoFamily:"
#: pocheckerconsts.serrorsbytest
msgid "Errors / warnings reported by %s for:"
@ -91,7 +91,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "Identificador [%s] não encontrado em %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
#, fuzzy
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[Linha: %d] formato() incompatível de argumentos para:"
#: pocheckerconsts.slineinfilename

View File

@ -100,8 +100,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "Идентификатор [%s] не найден в %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
msgstr "[Строка: %d] Несовместимые аргументы для Format() в:"
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[Строка: %d] Несовместимые и/или неверные аргументы для Format() в:"
#: pocheckerconsts.slineinfilename
msgid "[Line %d] in %s:"

View File

@ -1,4 +1,4 @@
# Igor Paliychuk <mansonigor@gmail.com>, 2012.
Igor Paliychuk <mansonigor@gmail.com>, 2012.
msgid ""
msgstr ""
"PO-Revision-Date: 2012-04-23 11:40+0300\n"
@ -6,8 +6,7 @@ msgstr ""
"Language: uk\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Virtaal 0.7.1\n"
#: pocheckerconsts.rspochecker
@ -24,7 +23,7 @@ msgstr ""
"Не можу знайти основний po файл:\n"
"%s\n"
"для вибраного файлу\n"
"%s"
"%s\n"
#: pocheckerconsts.scheckforduplicateuntranslatedvalues
msgid "Check for duplicate untranslated values"
@ -101,7 +100,9 @@ msgid "Identifier [%s] not found in %s"
msgstr "Ідентифікатор [%s] не знайдений в %s"
#: pocheckerconsts.sincompatibleformatargs
msgid "[Line: %d] Incompatible format() arguments for:"
#, fuzzy
#| msgid "[Line: %d] Incompatible format() arguments for:"
msgid "[Line: %d] Incompatible and/or invalid format() arguments for:"
msgstr "[Рядок: %d] Несумісні аргументи format() для:"
#: pocheckerconsts.slineinfilename
@ -201,3 +202,4 @@ msgstr "Переклад"
#: pocheckerconsts.sunselectalltests
msgid "Unselect all tests"
msgstr "Зняти вибір з всіх тестів"

View File

@ -44,7 +44,7 @@ resourcestring
sCheckForDuplicateUntranslatedValues = 'Check for duplicate untranslated '
+'values';
sFindAllTranslatedPoFiles = 'Find all translated po-files';
sIncompatibleFormatArgs = '[Line: %d] Incompatible format() arguments for:' ;
sIncompatibleFormatArgs = '[Line: %d] Incompatible and/or invalid format() arguments for:' ;
sNrErrorsFound = 'Found %d errors.';
sNrWarningsFound = 'Found %d warnings.';

View File

@ -78,7 +78,7 @@ Type
property OnTestEnd: TTestEndEvent read FOnTestEnd write FOnTestEnd;
end;
function ExtractFormatArgs(S: String): String;
function ExtractFormatArgs(S: String; out ArgumentError: boolean): String;
function IsMasterPoName(const Fn: String): Boolean;
function ExtractMasterNameFromChildName(const AChildName: String): String;
function FindAllTranslatedPoFiles(const Filename: string): TStringList;
@ -114,42 +114,42 @@ const
//Helper functions
function ExtractFormatArgs(S: String): String;
function ExtractFormatArgs(S: String; out ArgumentError: boolean): String;
const
FormatSpecs = ['D','E','F','G','M','N','P','S','U','X'];
FormatArgs = 'DEFGMNPSUX';
FormatChar = '%';
FormatSpecs = ':-.0123456789';
var
i,p: Integer;
InFormat: Boolean;
NewStr: String;
c: Char;
p: PtrInt;
NewStr, Symb: String;
begin
SetLength(NewStr, Length(S));
InFormat := False;
p := 0;
for i := 1 to length(S) do
NewStr := '';
ArgumentError := false;
p := UTF8Pos(FormatChar, S);
while (Length(S)>0) and (p>0) do
begin
c := S[i];
if (c = '%') then InFormat := not InFormat;
//debugln('i = ',dbgs(i),' c = ',c,' InFormat = ',dbgs(informat));
if InFormat and (UpCase(c) in (FormatSpecs+['%'])) then
UTF8Delete(S, 1, p);
if Length(S)>0 then
begin
Symb := UTF8UpperCase(UTF8Copy(S, 1, 1));
while (Length(S)>1) and (UTF8Pos(Symb, FormatSpecs)>0) do
begin
Inc(p);
NewStr[p] := c;
//weak syntax check for formatting options, skip them if found
UTF8Delete(S, 1, 1);
Symb := UTF8UpperCase(UTF8Copy(S, 1, 1));
end;
end
else
begin
if (c = '%') and (i > 1) and (S[i-1] = '%') and (p > 0) and (NewStr[p] = '%') then
begin//2 consecutive % means a literal % and is not a format specifier
//debugln('p = ',dbgs(p), 'i = ',dbgs(i));
NewStr[p] := '#';
Dec(p);
if Symb <> FormatChar then
begin
NewStr := NewStr+Symb;
if UTF8Pos(Symb, FormatArgs)=0 then
ArgumentError := true;
end;
end;
if InFormat and (Upcase(c) in FormatSpecs) then InFormat := False;
//removing processed symbol
UTF8Delete(S, 1, 1);
//searching for next argument
p := UTF8Pos(FormatChar, S);
end;
SetLength(NewStr, p);
Result := NewStr;
end;
@ -226,8 +226,18 @@ end;
function CompareFormatArgs(S1, S2: String): Boolean;
var
ArgErr1, ArgErr2: boolean;
begin
Result := CompareText(ExtractFormatArgs(S1), ExtractFormatArgs(S2)) = 0;
Result := true;
//do not check arguments if strings are equal to save time and avoid some
//false positives, e.g. for '{%Region}' string in lazarusidestrconsts
if S1 <> S2 then
begin
Result := CompareText(ExtractFormatArgs(S1, ArgErr1), ExtractFormatArgs(S2, ArgErr2)) = 0;
//setting result to false if invalid arguments were found even if the match
Result := Result and not ArgErr1 and not ArgErr2;
end;
end;
{ TPoFamily }
@ -347,7 +357,7 @@ begin
//CPoItem := FChild.FindPoItem(MPoItem.Identifier);
if Assigned(CPoItem) then
begin
if (Pos('%', CPoItem.Translation) > 0) and not CompareFormatArgs(CPoItem.Original, CPoItem.Translation) then
if CompareFormatArgs(CPoItem.Original, CPoItem.Translation) = false then
begin
if (ErrorCount = 0) then
begin