diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3866373334..69fe78f3c1 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,16 @@ past entries belonging to these authors: Viktor Szakats. */ +2009-05-05 00:25 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/rtl/hbi18n2.prg + + added new Harbour internal i18n functions: + __I18N_POTARRAYTRANS() and __I18N_HASHJOIN() + + * harbour/utils/hbi18n/hbi18n.prg + + added new switch to hb18n tool: + -a add automatic translations to 1-st .pot file using + translations from other .pot or .hbl files + 2009-05-04 18:16 UTC+0200 Viktor Szakats (harbour.01 syenar hu) * contrib/hbole/tests/testole.prg + Readded CDO and OO open examples (working). diff --git a/harbour/source/rtl/hbi18n2.prg b/harbour/source/rtl/hbi18n2.prg index 4b93d7a423..f09f8c7705 100644 --- a/harbour/source/rtl/hbi18n2.prg +++ b/harbour/source/rtl/hbi18n2.prg @@ -379,8 +379,10 @@ FUNCTION __I18N_POTARRAYTOHASH( aTrans, lEmpty, hI18N ) hContext := hTrans[ cContext ] ENDIF IF Empty( aItem[ _I18N_MSGSTR, 1 ] ) - hContext[ aItem[ _I18N_MSGID, 1 ] ] := IIF( aItem[ _I18N_PLURAL ], ; - AClone( aItem[ _I18N_MSGID ] ), aItem[ _I18N_MSGID, 1 ] ) + IF ! aItem[ _I18N_MSGID, 1 ] $ hContext + hContext[ aItem[ _I18N_MSGID, 1 ] ] := IIF( aItem[ _I18N_PLURAL ], ; + AClone( aItem[ _I18N_MSGID ] ), aItem[ _I18N_MSGID, 1 ] ) + ENDIF ELSE hContext[ aItem[ _I18N_MSGID, 1 ] ] := IIF( aItem[ _I18N_PLURAL ], ; AClone( aItem[ _I18N_MSGSTR ] ), aItem[ _I18N_MSGSTR, 1 ] ) @@ -391,6 +393,61 @@ FUNCTION __I18N_POTARRAYTOHASH( aTrans, lEmpty, hI18N ) RETURN hI18N +FUNCTION __I18N_POTARRAYTRANS( aTrans, hI18N ) + LOCAL aItem + LOCAL hContext + LOCAL cContext + LOCAL hTrans + LOCAL xTrans + + hTrans := hI18N[ "CONTEXT" ] + + FOR EACH aItem IN aTrans + cContext := aItem[ _I18N_CONTEXT ] + IF cContext $ hTrans + hContext := hTrans[ cContext ] + IF Empty( aItem[ _I18N_MSGSTR, 1 ] ) + IF aItem[ _I18N_MSGID, 1 ] $ hContext + xTrans := hContext[ aItem[ _I18N_MSGID, 1 ] ] + IF aItem[ _I18N_PLURAL ] + aItem[ _I18N_MSGSTR ] := IIF( HB_ISARRAY( xTrans ), ; + AClone( xTrans ), { xTrans } ) + ELSE + aItem[ _I18N_MSGSTR ] := IIF( HB_ISARRAY( xTrans ), ; + { xTrans[ 1 ] }, { xTrans } ) + ENDIF + ENDIF + ENDIF + ENDIF + NEXT + + RETURN aTrans + + +FUNCTION __I18N_HASHJOIN( hTrans, hTrans2 ) + LOCAL hContext, hCtx, hDstCtx + LOCAL xTrans + + hContext := hTrans[ "CONTEXT" ] + FOR EACH hCtx in hTrans2[ "CONTEXT" ] + IF ! hCtx:__enumKey() $ hContext + hContext[ hCtx:__enumKey() ] := hb_hClone( hCtx ) + ELSE + hDstCtx := hContext[ hCtx:__enumKey() ] + FOR EACH xTrans IN hCtx + IF !Empty( xTrans ) .AND. ; + ( ! xTrans:__enumKey() $ hDstCtx .OR. ; + Empty( hDstCtx[ xTrans:__enumKey() ] ) ) + hDstCtx[ xTrans:__enumKey() ] := IIF( HB_ISARRAY( xTrans ), ; + AClone( xTrans ), xTrans ) + ENDIF + NEXT + ENDIF + NEXT + + RETURN hTrans + + FUNCTION __I18N_POTARRAYJOIN( aTrans, aTrans2 ) LOCAL aItem, aDest, aSrc LOCAL hIndex diff --git a/harbour/utils/hbi18n/hbi18n.prg b/harbour/utils/hbi18n/hbi18n.prg index e622e1989e..55c26ad004 100644 --- a/harbour/utils/hbi18n/hbi18n.prg +++ b/harbour/utils/hbi18n/hbi18n.prg @@ -54,10 +54,11 @@ #define _HB_I18N_MERGE 1 #define _HB_I18N_GENHBL 2 +#define _HB_I18N_TRANS 3 PROCEDURE Main( ... ) LOCAL aParams, aFiles - LOCAL cFileOut + LOCAL cFileOut, cFileIn, cExt LOCAL lError, lEmpty, lQuiet LOCAL nMode, n LOCAL param @@ -85,6 +86,12 @@ PROCEDURE Main( ... ) ELSE nMode := _HB_I18N_GENHBL ENDIF + ELSEIF param == "a" + IF nMode != 0 + lError := .T. + ELSE + nMode := _HB_I18N_TRANS + ENDIF ELSEIF param = "o" IF !Empty( param := SubStr( param, 2 ) ) cFileOut := param @@ -108,7 +115,19 @@ PROCEDURE Main( ... ) ENDIF NEXT - IF nMode == 0 .OR. Empty( aFiles ) + IF nMode == _HB_I18N_TRANS + FOR n := 1 TO Len( aFiles ) + hb_FNameSplit( aFiles[ n ],,, @cExt ) + IF !Lower( cExt ) == ".hbl" + cFileIn := aFiles[ n ] + HB_ADel( aFiles, n, .T. ) + EXIT + ENDIF + NEXT + ENDIF + + IF nMode == 0 .OR. Empty( aFiles ) .OR. ; + ( nMode == _HB_I18N_TRANS .AND. Empty( cFileIn ) ) Syntax() ENDIF @@ -120,6 +139,8 @@ PROCEDURE Main( ... ) Merge( aFiles, cFileOut ) ELSEIF nMode == _HB_I18N_GENHBL GenHbl( aFiles, cFileOut, lEmpty ) + ELSEIF nMode == _HB_I18N_TRANS + AutoTrans( cFileIn, aFiles, cFileOut ) ENDIF RETURN @@ -140,10 +161,12 @@ STATIC PROCEDURE Logo() STATIC PROCEDURE Syntax() Logo() - OutStd( "Syntax: hbi18n -m | -g [-o] [-e] [-q] " + HB_OSNewLine() + ; + OutStd( "Syntax: hbi18n -m | -g | -a [-o] [-e] [-q] " + HB_OSNewLine() + ; HB_OSNewLine() + ; " -m merge given .pot files" + HB_OSNewLine() + ; " -g generate .hbl file from given .pot files" + HB_OSNewLine() + ; + " -a add automatic translations to 1-st .pot file using" + HB_OSNewLine() + ; + " translations from other .pot or .hbl files" + HB_OSNewLine() + ; " -o output file name" + HB_OSNewLine() + ; " default is first .pot file name with" + HB_OSNewLine() + ; " .po_ (merge) or .hbl extension" + HB_OSNewLine() + ; @@ -200,6 +223,37 @@ STATIC FUNCTION LoadFiles( aFiles ) RETURN aTrans + +STATIC FUNCTION LoadFilesAsHash( aFiles ) + LOCAL cTrans, cExt, cErrorMsg + LOCAL hTrans + LOCAL aTrans + LOCAL n + + FOR n := 1 TO Len( aFiles ) + hb_FNameSplit( aFiles[ n ],,, @cExt ) + IF Lower( cExt ) == ".hbl" + cTrans := hb_memoRead( aFiles[ n ] ) + IF !HB_I18N_Check( cTrans ) + ErrorMsg( "Wrong file format: " + aFiles[ n ] ) + ENDIF + IF hTrans == NIL + hTrans := __I18N_hashTable( HB_I18N_RestoreTable( cTrans ) ) + ELSE + __I18N_hashJoin( hTrans, __I18N_hashTable( HB_I18N_RestoreTable( cTrans ) ) ) + ENDIF + ELSE + aTrans := __I18N_potArrayLoad( aFiles[ n ], @cErrorMsg ) + IF aTrans == NIL + ErrorMsg( cErrorMsg ) + ENDIF + hTrans := __I18N_potArrayToHash( aTrans,, hTrans ) + ENDIF + NEXT + + RETURN hTrans + + STATIC PROCEDURE Merge( aFiles, cFileOut ) LOCAL cErrorMsg @@ -234,3 +288,21 @@ STATIC PROCEDURE GenHbl( aFiles, cFileOut, lEmpty ) ENDIF RETURN + + +STATIC PROCEDURE AutoTrans( cFileIn, aFiles, cFileOut ) + LOCAL cErrorMsg + + IF Empty( cFileOut ) + cFileOut := FileExt( cFileIn, ".pot", .T. ) + ELSE + cFileOut := FileExt( cFileOut, ".pot", .F. ) + ENDIF + + IF !__I18N_potArraySave( cFileOut, ; + __I18N_potArrayTrans( LoadFiles( { cFileIn } ), ; + LoadFilesAsHash( aFiles ) ), @cErrorMsg ) + ErrorMsg( cErrorMsg ) + ENDIF + + RETURN