From 5890d4f9fa55cde16a9a7c41c2193bbae198fc91 Mon Sep 17 00:00:00 2001 From: jesus Date: Tue, 11 Nov 2008 01:28:17 +0000 Subject: [PATCH] updatepofiles tool now uses translations unit, localize scripts process the original package list git-svn-id: trunk@17325 - --- .gitattributes | 1 + lcl/translations.pas | 76 +++++--- localize.bat | 67 ++++--- localize.sh | 29 +-- tools/updatepofiles.lpi | 57 ++++++ tools/updatepofiles.pas | 382 ++++++---------------------------------- 6 files changed, 217 insertions(+), 395 deletions(-) create mode 100644 tools/updatepofiles.lpi diff --git a/.gitattributes b/.gitattributes index 57ca0e367f..41630e998d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4361,6 +4361,7 @@ tools/snapshots/testmonitorcfg.pas svneol=native#text/plain tools/svn2revisioninc.lpi svneol=native#text/plain tools/svn2revisioninc.pas svneol=native#text/plain tools/update_pkgfileslcl_inc.sh svneol=native#text/plain +tools/updatepofiles.lpi svneol=native#text/plain tools/updatepofiles.pas svneol=native#text/pascal tools/xpm_to_png/convert.bat svneol=native#text/plain tools/xpm_to_png/xpm_to_png.lpi svneol=native#text/plain diff --git a/lcl/translations.pas b/lcl/translations.pas index 60f9cb5edb..b68d4b8aff 100644 --- a/lcl/translations.pas +++ b/lcl/translations.pas @@ -148,7 +148,6 @@ function UTF8ToSystemCharSet(const s: string): string; inline; function UpdatePoFile(Files: TStrings; const POFilename: string): boolean; - implementation function UTF8ToSystemCharSet(const s: string): string; inline; @@ -229,12 +228,58 @@ var BasePoFile, POFile: TPoFile; i: Integer; E: EPOFileError; + + procedure UpdatePoFilesTranslation; + var + j: Integer; + Lines: TStringList; + begin + // Update translated PO files + Lines := FindAllTranslatedPoFiles(POFilename); + try + for j:=0 to Lines.Count-1 do begin + POFile := TPOFile.Create(Lines[j], true); + try + POFile.Tag:=1; + POFile.UpdateTranslation(BasePOFile); + try + POFile.SaveToFile(Lines[j]); + except + on Ex: Exception do begin + E := EPOFileError.Create(Ex.Message); + E.ResFileName:=Lines[j]; + E.POFileName:=POFileName; + raise E; + end; + end; + finally + POFile.Free; + end; + end; + finally + Lines.Free; + end; + end; + begin Result := false; - - if (Files=nil) or (Files.Count=0) then + + if (Files=nil) or (Files.Count=0) then begin + + if FileExistsUTF8(POFilename) then begin + // just update translated po files + BasePOFile := TPOFile.Create(POFilename, true); + try + UpdatePoFilesTranslation; + finally + BasePOFile.Free; + end; + end; + exit; + end; + InputLines := TStringList.Create; try // Read base po items @@ -272,29 +317,8 @@ begin BasePOFile.SaveToFile(POFilename); Result := BasePOFile.Modified; - // Update translated PO files - InputLines.Free; - InputLines := FindAllTranslatedPoFiles(POFilename); - for i:=0 to InputLines.Count-1 do begin - POFile := TPOFile.Create(InputLines[i], true); - try - POFile.Tag:=1; - POFile.UpdateTranslation(BasePOFile); - try - POFile.SaveToFile(InputLines[i]); - except - on Ex: Exception do begin - E := EPOFileError.Create(Ex.Message); - E.ResFileName:=InputLines[i]; - E.POFileName:=POFileName; - raise E; - end; - end; - finally - POFile.Free; - end; - end; - + UpdatePOFilesTranslation; + finally InputLines.Free; BasePOFile.Free; diff --git a/localize.bat b/localize.bat index cb28def209..2155262b28 100644 --- a/localize.bat +++ b/localize.bat @@ -35,73 +35,84 @@ echo on @REM IDE @set IDE_RST=units\%ArchOS%\LazarusIDEStrConsts.rst -rstconv -c UTF-8 -i %IDE_RST% -o languages\lazaruside.po -tools\updatepofiles languages\lazaruside.po +tools\updatepofiles %IDE_RST% languages\lazaruside.po @REM IDEIntf @set ObjInsp_RST=ideintf\units\%ArchOS%\ObjInspStrConsts.rst -rstconv -c UTF-8 -i %ObjInsp_RST% -o ideintf\languages\objinspstrconsts.po -tools\updatepofiles ideintf\languages\objinspstrconsts.po +tools\updatepofiles %ObjInsp_RST% ideintf\languages\objinspstrconsts.po @REM INSTALLER @set Installer_RST=tools\install\win\installerstrconsts.rst if not exist %Installer_RST% goto SkipInstaller -rstconv -c UTF-8 -i %Installer_RST% -o languages\installerstrconsts.po -tools\updatepofiles languages\installerstrconsts.po +tools\updatepofiles %Installer_RST% languages\installerstrconsts.po :SkipInstaller @REM CodeTools @set CodeTools_RST=components\codetools\units\%ArchOS%\CodeToolsStrConsts.rst -rstconv -c UTF-8 -i %CodeTools_RST% -o components\codetools\languages\codetoolsstrconsts.po -tools\updatepofiles components\codetools\languages\codetoolsstrconsts.po +tools\updatepofiles %CodeTools_RST% components\codetools\languages\codetoolsstrconsts.po @REM SynEdit @set SynEdit_RST=components\synedit\units\%ArchOS%\SynEditStrConst.rst -rstconv -c UTF-8 -i %SynEdit_RST% -o components\synedit\languages\synedit.po -tools\updatepofiles components\synedit\languages\synedit.po +tools\updatepofiles %SynEdit_RST% components\synedit\languages\synedit.po @REM SynMacroRecorder @set SynMacroRec_RST=components\synedit\units\%ArchOS%\synmacrorecorder.rst -rstconv -c UTF-8 -i %SynMacroRec_RST% -o components\synedit\languages\synmacrorecorder.po -tools\updatepofiles components\synedit\languages\synmacrorecorder.po +tools\updatepofiles %SynMacroRec_RST% components\synedit\languages\synmacrorecorder.po @REM SynUniHighLighterShellScript @set SynUniHighLighterShellScript_RST=components\synedit\units\%ArchOS%\synhighlighterunixshellscript.rst -rstconv -c UTF-8 -i %SynUniHighLighterShellScript_RST% -o components\synedit\languages\synhighlighterunixshellscript.po -tools\updatepofiles components\synedit\languages\synhighlighterunixshellscript.po +tools\updatepofiles %SynUniHighLighterShellScript_RST% components\synedit\languages\synhighlighterunixshellscript.po @REM LCL @set LCL_RST=lcl\units\%ArchOS%\lclstrconsts.rst -rstconv -c UTF-8 -i %LCL_RST% -o lcl\languages\lclstrconsts.po -tools\updatepofiles lcl\languages\lclstrconsts.po +tools\updatepofiles %LCL_RST% lcl\languages\lclstrconsts.po @REM CGI @set CGI_RST=components\cgi\lib\%ArchOS%\cgimodules.rst -rstconv -c UTF-8 -i %CGI_RST% -o components\cgi\languages\cgimodules.po -tools\updatepofiles components\cgi\languages\cgimodules.po +tools\updatepofiles %CGI_RST% components\cgi\languages\cgimodules.po + +@REM LazReport +@set LazReport_RST=components\lazreport\source\lib\%ArchOS%\lr_const.rst +tools\updatepofiles %LazReport_RST% components\lazreport\source\languages\lr_const.po + +@REM MemDS +@set MemDS_RST=components\memds\lib\%ArchOS%\frmselectdataset.rst +tools\updatepofiles %MemDS_RST% components\memds\languages\frmselectdataset.po @REM Printers @set Printers_RST=components\printers\design\lib\%ArchOS%\ideprinting.rst -rstconv -c UTF-8 -i %Printers_RST% -o components\printers\design\languages\ideprinting.po -tools\updatepofiles components\printers\design\languages\ideprinting.po +tools\updatepofiles %Printers_RST% components\printers\design\languages\ideprinting.po @REM ProjectTemplates @set ProjectTemplates_RST=components\projecttemplates\lib\%ArchOS%\frmtemplatevariables.rst -rstconv -c UTF-8 -i %ProjectTemplates_RST% -o components\projecttemplates\languages\frmtemplatevariables.po -tools\updatepofiles components\projecttemplates\languages\frmtemplatevariables.po +tools\updatepofiles %ProjectTemplates_RST% components\projecttemplates\languages\frmtemplatevariables.po @set ProjectTemplates_RST=components\projecttemplates\lib\%ArchOS%\idetemplateproject.rst -rstconv -c UTF-8 -i %ProjectTemplates_RST% -o components\projecttemplates\languages\idetemplateproject.po -tools\updatepofiles components\projecttemplates\languages\idetemplateproject.po +tools\updatepofiles %ProjectTemplates_RST% components\projecttemplates\languages\idetemplateproject.po @set ProjectTemplates_RST=components\projecttemplates\lib\%ArchOS%\projecttemplates.rst -rstconv -c UTF-8 -i %ProjectTemplates_RST% -o components\projecttemplates\languages\projecttemplates.po -tools\updatepofiles components\projecttemplates\languages\projecttemplates.po +tools\updatepofiles %ProjectTemplates_RST% components\projecttemplates\languages\projecttemplates.po + +@REM TDBF +@set TDBF_RST=components\tdbf\lib\%ArchOS%\registerdbf.rst +tools\updatepofiles %TDBF_RST% components\tdbf\languages\registerdbf.po + +@REM TP_IPro +@set TP_IPro_RST=components\turbopower_ipro\units\%ArchOS%\ipconst.rst +tools\updatepofiles %TP_IPro_RST% components\turbopower_ipro\languages\ipconst.po + +@set TP_IPro_RST=components\turbopower_ipro\units\%ArchOS%\iputils.rst +tools\updatepofiles %TP_IPro_RST% components\turbopower_ipro\languages\iputils.po @REM MessageComposer @set MessageComposer_RST=components\messagecomposer\lib\%ArchOS%\messagecomposer.rst -rstconv -c UTF-8 -i %MessageComposer_RST% -o components\messagecomposer\languages\messagecomposer.po -tools\updatepofiles components\messagecomposer\languages\messagecomposer.po +tools\updatepofiles %MessageComposer_RST% components\messagecomposer\languages\messagecomposer.po + +@REM LazReport editor sample +@set LREditor_RST=components\lazreport\samples\editor\maincalleditor.rst +if not exist %LREditor_RST% goto SkipLREditor +tools\updatepofiles %LREditor_RST% components\lazreport\samples\editor\languages\calleditorwithpkg.po +:SkipLREditor @goto Exit diff --git a/localize.sh b/localize.sh index 2c69ecbe6e..14645267af 100755 --- a/localize.sh +++ b/localize.sh @@ -30,8 +30,21 @@ fi RSTFILES=( ". lazarusidestrconsts lazaruside" "ideintf objinspstrconsts" + "components/codetools codetoolsstrconsts" "components/synedit syneditstrconst synedit" "components/synedit synmacrorecorder" + "components/synedit synhighlighterunixshellscript" + "components/tdbf registerdbf" + "components/turbopower_ipro ipconst" + "components/turbopower_ipro iputils" + "components/cgi cgimodules" + "components/lazreport/samples/editor maincalleditor calleditorwithpkg" + "components/memds frmselectdataset" + "components/messagecomposer messagecomposer" + "components/printers/design ideprinting" + "components/projecttemplates projecttemplates" + "components/projecttemplates frmtemplatevariables" + "components/projecttemplates idetemplateproject" "lcl lclstrconsts" ) @@ -49,19 +62,9 @@ for idx in ${!RSTFILES[@]}; do if [ -n "$RST" ]; then POFileFull=$RSTDIR/languages/$POFILE.po - echo $POFileFull - - echo 'msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -' > $POFileFull - - rstconv -i $RST -o $POFileFull.tmp - cat $POFileFull.tmp >> $POFileFull - rm $POFileFull.tmp - ./tools/updatepofiles $POFileFull + + ./tools/updatepofiles $RST $POFileFull + fi fi done diff --git a/tools/updatepofiles.lpi b/tools/updatepofiles.lpi new file mode 100644 index 0000000000..efacfdce85 --- /dev/null +++ b/tools/updatepofiles.lpi @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/updatepofiles.pas b/tools/updatepofiles.pas index 4f1c7077da..60d660f9a1 100644 --- a/tools/updatepofiles.pas +++ b/tools/updatepofiles.pas @@ -37,79 +37,31 @@ program UpdatePoFiles; {$mode objfpc}{$H+} uses - Classes, SysUtils, FileUtil, AvL_Tree; + Classes, SysUtils, FileUtil, Translations; -type - TMsgItem = record - Comment: string; - ID: string; - Str: string; - end; - PMsgItem = ^TMsgItem; - -function CompareMsgItems(Data1, Data2: pointer): integer; -var - MsgItem1: PMsgItem; - MsgItem2: PMsgItem; -begin - MsgItem1:=PMsgItem(Data1); - MsgItem2:=PMsgItem(Data2); - Result:=CompareStr(MsgItem1^.ID,MsgItem2^.ID); -end; - -procedure DisposeMsgTree(var Tree: TAVLTree); -var - Node: TAVLTreeNode; - MsgItem: PMsgItem; -begin - Node:=Tree.FindLowest; - while Node<>nil do begin - MsgItem:=PMsgItem(Node.Data); - Dispose(MsgItem); - Node:=Tree.FindSuccessor(Node); - end; - Tree.Free; - Tree:=nil; -end; - -type - TPoFile = class - public - Tree: TAVLTree; - Header: TStringList; - UTF8Header: string; - constructor Create; - destructor Destroy; override; - end; - -{ TPoFile } - -constructor TPoFile.Create; -begin - Tree:=TAVLTree.Create(@CompareMsgItems); - Header:=TStringList.Create; -end; - -destructor TPoFile.Destroy; -begin - DisposeMsgTree(Tree); - Header.Free; - inherited Destroy; -end; - -//============================================================================== var Files: TStringList; Prefix: string; + ResFiles: array of TStringList; -procedure IncPrefix; +procedure AddResFile(const PoIndex:Integer; const AResFile:string); begin - Prefix:=Prefix+' '; + if PoIndex>(Length(ResFiles)-1) then + SetLength(ResFiles, PoIndex+1); + + if ResFiles[PoIndex]=nil then + ResFiles[PoIndex] := TStringList.Create; + + ResFiles[PoIndex].Add(AResFile); end; -procedure DecPrefix; +procedure ClearResFiles; +var + i: Integer; begin - Prefix:=LeftStr(Prefix,length(Prefix)-2); + for i:=0 to Length(ResFiles)-1 do + if ResFiles[i]<>nil then + ResFiles[i].Free; end; function ParamsValid: boolean; @@ -118,300 +70,74 @@ var Filename: String; Ext: String; Name: string; + PoIndex: Integer; begin Result:=false; - if ParamCount<1 then exit; + PoIndex:=0; + + if ParamCount<1 then + exit; + for i:=1 to ParamCount do begin - Filename:=ParamStrUTF8(1); + + Filename:=ParamStrUTF8(i); + + Ext:=ExtractFileExt(Filename); + if not FileExistsUTF8(Filename) then begin + + if (Ext='.rst') or (Ext='.lrt') then + continue; // ignore resource files + writeln('ERROR: file not found: ',FileName); exit; end; - Ext:=ExtractFileExt(Filename); - if (Ext<>'.po') then begin + + if (Ext<>'.po') and (Ext<>'.rst') and (Ext<>'.lrt') then begin writeln('ERROR: invalid extension: ',Filename); exit; end; + Name:=ExtractFileName(Filename); Name:=LeftStr(Name,length(Name)-length(Ext)); if Pos('.',Name)>0 then begin writeln('ERROR: invalid unitname: ',Name); exit; end; - if Files=nil then Files:=TStringList.Create; - Files.Add(Filename); + + if Ext='.po' then begin + if Files=nil then + Files:=TStringList.Create; + Files.Add(Filename); + inc(PoIndex); + SetLength(ResFiles, Files.Count); // make sure Files and ResFiles are in sync + end else + AddResFile(PoIndex, FileName); end; Result:=true; end; -function ReadMessageItem(SrcFile: TStringList; var Line: integer): PMsgItem; -var - s: string; -begin - New(Result); - while Line'') and (s[1]='#') then begin - Result^.Comment:=Result^.Comment+copy(s,2,length(s)); - end - else if (LeftStr(s,7)='msgid "') then begin - // read ID - Result^.ID:=copy(s,8,length(s)-8); - inc(Line); - while Line'') and (s[1]='"') then begin - Result^.ID:=Result^.ID+#10+copy(s,2,length(s)-2); - inc(Line); - end else - break; - end; - // read Str - if Line'') and (s[1]='"') then begin - Result^.Str:=Result^.Str+#10+copy(s,2,length(s)-2); - inc(Line); - end else - break; - end; - end; - end; - exit; - end; - inc(Line); - end; -end; - -procedure WriteMessageItem(MsgItem: PMsgItem; DestFile: TStringList); - - procedure WriteItem(const Prefix: string; Str: string); - var - s: String; - p: Integer; - begin - s:=Prefix+' "'; - p:=1; - while (p<=length(Str)) do begin - if Str[p]=#10 then begin - // a new line - s:=s+copy(Str,1,p-1)+'"'; - DestFile.Add(s); - Str:=copy(Str,p+1,length(Str)); - p:=1; - // start new line - s:='"'; - end else - inc(p); - end; - if (Str<>'') or (s<>'"') then begin - s:=s+Str+'"'; - DestFile.Add(s); - end; - end; - -begin - if MsgItem^.Comment<>'' then - DestFile.Add('#'+MsgItem^.Comment); - WriteItem('msgid',MsgItem^.ID); - WriteItem('msgstr',MsgItem^.Str); - DestFile.Add(''); -end; - -function ReadPoFile(const Filename: string): TPoFile; -var - SrcFile: TStringList; - MsgItem: PMsgItem; - Line: Integer; -begin - Result:=TPoFile.Create; - - // read source .po file - //writeln(Prefix,'Loading ',Filename,' ...'); - SrcFile:=TStringList.Create; - SrcFile.LoadFromFile(UTF8ToSys(Filename)); - - if (SrcFile.Count>0) and (copy(SrcFile[0],1,3)=UTF8FileHeader) then begin - Result.UTF8Header:=copy(SrcFile[0],1,3); - SrcFile[0]:=copy(SrcFile[0],4,length(SrcFile[0])); - end; - - Line:=0; - while Linenil) then begin - Dispose(MsgItem); - continue; - end; - // add message - Result.Tree.Add(MsgItem); - end; - end; - - SrcFile.Free; -end; - -procedure WritePoFile(PoFile: TPoFile; const Filename: string); -var - DestFile: TStringList; - Node: TAVLTreeNode; - MsgItem: PMsgItem; - Save: Boolean; - OldDestFile: TStringList; -begin - //writeln(Prefix,'Saving ',Filename,' ...'); - DestFile:=TStringList.Create; - if (PoFile.Header.Count>0) then begin - DestFile.Add('msgid ""'); - DestFile.Add('msgstr ""'); - DestFile.AddStrings(PoFile.Header); - DestFile.Add(''); - end; - Node:=PoFile.Tree.FindLowest; - while Node<>nil do begin - MsgItem:=PMsgItem(Node.Data); - WriteMessageItem(MsgItem,DestFile); - Node:=PoFile.Tree.FindSuccessor(Node); - end; - if (PoFile.UTF8Header<>'') and (DestFile.Count>0) then - DestFile[0]:=PoFile.UTF8Header+DestFile[0]; - Save:=true; - if FileExistsUTF8(Filename) then begin - OldDestFile:=TStringList.Create; - OldDestFile.LoadFromFile(UTF8ToSys(Filename)); - if OldDestFile.Text=DestFile.Text then Save:=false; - OldDestFile.Free; - end; - if Save then - DestFile.SaveToFile(UTF8ToSys(Filename)); - DestFile.Free; -end; - -function FindAllTranslatedPoFiles(const Filename: string): TStringList; -var - Path: String; - Name: String; - NameOnly: String; - Ext: String; - FileInfo: TSearchRec; - CurExt: String; -begin - Result:=TStringList.Create; - Path:=ExtractFilePath(Filename); - Name:=ExtractFilename(Filename); - Ext:=ExtractFileExt(Filename); - NameOnly:=LeftStr(Name,length(Name)-length(Ext)); - if FindFirstUTF8(Path+GetAllFilesMask,faAnyFile,FileInfo)=0 then begin - repeat - if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') - or (CompareFilenames(FileInfo.Name,Name)=0) then continue; - CurExt:=ExtractFileExt(FileInfo.Name); - if (CompareFilenames(CurExt,'.po')<>0) - or (CompareFilenames(LeftStr(FileInfo.Name,length(NameOnly)),NameOnly)<>0) - then - continue; - Result.Add(Path+FileInfo.Name); - until FindNextUTF8(FileInfo)<>0; - end; - FindCloseUTF8(FileInfo); -end; - -procedure MergePoTrees(SrcTree, DestTree: TAVLTree); -var - SrcNode, DestNode: TAVLTreeNode; - SrcMsgItem, DestMsgItem: PMsgItem; - OldNode: TAVLTreeNode; -begin - // add all message items from SrcTree into DestTree - SrcNode:=SrcTree.FindLowest; - while SrcNode<>nil do begin - SrcMsgItem:=PMsgItem(SrcNode.Data); - DestNode:=DestTree.FindKey(SrcMsgItem,@CompareMsgItems); - if DestNode<>nil then begin - // ID already exists -> update comment - DestMsgItem:=PMsgItem(DestNode.Data); - DestMsgItem^.Comment:=SrcMsgItem^.Comment; - end else begin - // new ID -> add new message item to DestTree - New(DestMsgItem); - DestMsgItem^.Comment:=SrcMsgItem^.Comment; - DestMsgItem^.ID:=SrcMsgItem^.ID; - DestMsgItem^.Str:=SrcMsgItem^.Str; - DestTree.Add(DestMsgItem); - end; - SrcNode:=SrcTree.FindSuccessor(SrcNode); - end; - // remove all old messages in DestTree - DestNode:=DestTree.FindLowest; - while DestNode<>nil do begin - DestMsgItem:=PMsgItem(DestNode.Data); - OldNode:=DestNode; - DestNode:=DestTree.FindSuccessor(DestNode); - if (DestMsgItem^.ID<>'') - and (SrcTree.FindKey(DestMsgItem,@CompareMsgItems)=nil) then begin - // unused message -> delete it - writeln('Deleting unused message "',DestMsgItem^.ID,'"'); - Dispose(DestMsgItem); - DestTree.Delete(OldNode); - end; - end; -end; - -procedure UpdatePoFile(const Filename: string); -var - SrcFile, DestFile: TPoFile; - DestFiles: TStringList; - i: Integer; -begin - writeln('Loading ',Filename,' ...'); - SrcFile:=ReadPoFile(Filename); - DestFiles:=FindAllTranslatedPoFiles(Filename); - IncPrefix; - for i:=0 to DestFiles.Count-1 do begin - writeln(Prefix,'Updating ',DestFiles[i]); - IncPrefix; - DestFile:=ReadPoFile(DestFiles[i]); - MergePoTrees(SrcFile.Tree,DestFile.Tree); - WritePoFile(DestFile,DestFiles[i]); - DestFile.Free; - DecPrefix; - end; - DecPrefix; - DestFiles.Free; - SrcFile.Free; -end; - procedure UpdateAllPoFiles; var i: Integer; begin - for i:=0 to Files.Count-1 do begin - UpdatePoFile(Files[i]); - end; + for i:=0 to Files.Count-1 do + UpdatePoFile(ResFiles[i], Files[i]); end; begin Prefix:=''; Files:=nil; - if not ParamsValid then begin + + if not ParamsValid then writeln('Usage: ',ExtractFileName(ParamStrUTF8(0)) - ,' filename1.po [filename2.po ... filenameN.po]'); - exit; - end else begin + ,' filename1.po [filename2.po ... filenameN.po]') + else UpdateAllPoFiles; - end; - Files.Free; + + if Files<>nil then + Files.Free; + + ClearResFiles; end.