diff options
Diffstat (limited to 'transex3')
114 files changed, 28507 insertions, 0 deletions
diff --git a/transex3/inc/cfgmerge.hxx b/transex3/inc/cfgmerge.hxx new file mode 100644 index 000000000000..9f1c97f05af5 --- /dev/null +++ b/transex3/inc/cfgmerge.hxx @@ -0,0 +1,208 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: cfgmerge.hxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CFG_MERGE_HXX +#define _CFG_MERGE_HXX + +#include <tools/string.hxx> +#include <tools/list.hxx> +#include <hash_map> + +typedef std::hash_map<ByteString , ByteString , hashByteString,equalByteString> + ByteStringHashMap; + + +// +// class CfgStackData +// + +class CfgStackData +{ +friend class CfgParser; +friend class CfgExport; +friend class CfgMerge; +private: + ByteString sTagType; + ByteString sIdentifier; + + ByteString sResTyp; + + ByteString sTextTag; + ByteString sEndTextTag; + + ByteStringHashMap sText; +public: + CfgStackData( const ByteString &rTag, const ByteString &rId ) + : sTagType( rTag ), sIdentifier( rId ) {}; + + ByteString &GetTagType() { return sTagType; } + ByteString &GetIdentifier() { return sIdentifier; } + +}; + +// +// class CfgStack +// + +DECLARE_LIST( CfgStackList, CfgStackData * ) + +class CfgStack : public CfgStackList +{ +public: + CfgStack() : CfgStackList( 10, 10 ) {} + ~CfgStack(); + + ULONG Push( CfgStackData *pStackData ); + CfgStackData *Push( const ByteString &rTag, const ByteString &rId ); + CfgStackData *Pop() { return Remove( Count() - 1 ); } + + CfgStackData *GetStackData( ULONG nPos = LIST_APPEND ); + + ByteString GetAccessPath( ULONG nPos = LIST_APPEND ); +}; + +// +// class CfgParser +// + +class CfgParser +{ +protected: + ByteString sCurrentResTyp; + ByteString sCurrentIsoLang; + ByteString sCurrentText; + + ByteString sLastWhitespace; + + CfgStack aStack; + CfgStackData *pStackData; + + BOOL bLocalize; + + virtual void WorkOnText( + ByteString &rText, + const ByteString &nLangIndex )=0; + + virtual void WorkOnRessourceEnd()=0; + + virtual void Output( const ByteString& rOutput )=0; + + void Error( const ByteString &rError ); + +private: + int ExecuteAnalyzedToken( int nToken, char *pToken ); + std::vector<ByteString> aLanguages; + void AddText( + ByteString &rText, + const ByteString &rIsoLang, + const ByteString &rResTyp ); + +BOOL IsTokenClosed( const ByteString &rToken ); + +public: + CfgParser(); + virtual ~CfgParser(); + + int Execute( int nToken, char * pToken ); +}; + +// +// class CfgOutputParser +// + +class CfgOutputParser : public CfgParser +{ +protected: + SvFileStream *pOutputStream; +public: + CfgOutputParser ( const ByteString &rOutputFile ); + virtual ~CfgOutputParser(); +}; + +// +// class CfgExport +// + +class CfgExport : public CfgOutputParser +{ +private: + ByteString sPrj; + ByteString sPath; + std::vector<ByteString> aLanguages; +protected: + void WorkOnText( + ByteString &rText, + const ByteString &rIsoLang + ); + + void WorkOnRessourceEnd(); + void Output( const ByteString& rOutput ); +public: + CfgExport( + const ByteString &rOutputFile, + const ByteString &rProject, + const ByteString &rFilePath + ); + ~CfgExport(); +}; + +// +// class CfgMerge +// + +class CfgMerge : public CfgOutputParser +{ +private: + MergeDataFile *pMergeDataFile; + std::vector<ByteString> aLanguages; + ResData *pResData; + + BOOL bGerman; + ByteString sFilename; + BOOL bEnglish; + +protected: + void WorkOnText( + ByteString &rText, + const ByteString &nLangIndex ); + + void WorkOnRessourceEnd(); + + void Output( const ByteString& rOutput ); +public: + CfgMerge( + const ByteString &rMergeSource, + const ByteString &rOutputFile, + ByteString &rFilename + ); + ~CfgMerge(); +}; + +#endif diff --git a/transex3/inc/export.hxx b/transex3/inc/export.hxx new file mode 100644 index 000000000000..89c1cf548947 --- /dev/null +++ b/transex3/inc/export.hxx @@ -0,0 +1,582 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: export.hxx,v $ + * $Revision: 1.27 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _EXPORT_HXX +#define _EXPORT_HXX + +#ifndef TRANSEX_DIRECTORY_HXX +#define TRANSEX_DIRECTORY_HXX +#include <transex3/directory.hxx> +#endif + + +// #define MERGE_SOURCE_LANGUAGES <- To merge en-US and de resource + +#include <tools/string.hxx> +#include <tools/list.hxx> +#include <tools/stream.hxx> +#include <tools/fsys.hxx> +#include <osl/file.hxx> +#include <osl/file.h> + +#include <hash_map> /* std::hashmap*/ +#include <iterator> /* std::iterator*/ +#include <set> /* std::set*/ +#include <vector> /* std::vector*/ +#include <queue> + +#define NO_TRANSLATE_ISO "x-no-translate" + +#define JAPANESE_ISO "ja" + + +struct eqstr{ + BOOL operator()(const char* s1, const char* s2) const{ + return strcmp(s1,s2)==0; + } +}; + +struct equalByteString{ + bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { + return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL; + } +}; +struct lessByteString{ + bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { + return rKey1.CompareTo( rKey2 )==COMPARE_LESS; + } +}; + +struct hashByteString{ + size_t operator()( const ByteString& rName ) const{ + std::hash< const char* > myHash; + return myHash( rName.GetBuffer() ); + } +}; + +class PFormEntrys; +class MergeData; +typedef std::set<ByteString , lessByteString > ByteStringSet; + +typedef std::hash_map<ByteString , ByteString , hashByteString,equalByteString> + ByteStringHashMap; + +typedef std::hash_map<ByteString , bool , hashByteString,equalByteString> + ByteStringBoolHashMap; + +typedef std::hash_map<ByteString , PFormEntrys* , hashByteString,equalByteString> + PFormEntrysHashMap; + +typedef std::hash_map<ByteString , MergeData* , hashByteString,equalByteString> + MergeDataHashMap; + +#define SOURCE_LANGUAGE ByteString("en-US") +#define LIST_REFID "LIST_REFID" + +typedef ByteStringHashMap ExportListEntry; + +DECLARE_LIST( ExportListBase, ExportListEntry * ) + +// +// class ExportList +// + +class ExportList : public ExportListBase +{ +private: + ULONG nSourceLanguageListEntryCount; + +public: + ExportList() : ExportListBase() { nSourceLanguageListEntryCount = 0; } + ULONG GetSourceLanguageListEntryCount() { return nSourceLanguageListEntryCount; } + void NewSourceLanguageListEntry() { nSourceLanguageListEntryCount++; } +}; + +#define REFID_NONE 0xFFFF + +// +// struct ResData +// + +/****************************************************************************** +* Purpose: holds mandatory data to export a single res (used with ResStack) +******************************************************************************/ + +#define ID_LEVEL_NULL 0x0000 +#define ID_LEVEL_AUTOID 0x0001 +#define ID_LEVEL_TEXT 0x0002 +#define ID_LEVEL_FIELDNAME 0x0003 +#define ID_LEVEL_ACCESSPATH 0x0004 +#define ID_LEVEL_IDENTIFIER 0x0005 +#define ID_LEVEL_LISTINDEX 0x0006 + +class ResData +{ +public: + ~ResData(); + BOOL SetId( const ByteString &rId, USHORT nLevel ); + + USHORT nWidth; + USHORT nChildIndex; + USHORT nIdLevel; + BOOL bChild; + BOOL bChildWithText; + + BOOL bText; + BOOL bHelpText; + BOOL bQuickHelpText; + BOOL bTitle; + BOOL bList; + + BOOL bRestMerged; + + ByteString sResTyp; + ByteString sId; + ByteString sGId; + ByteString sHelpId; + ByteString sFilename; + + ByteStringHashMap sText; + USHORT nTextRefId; + + ByteStringHashMap sHelpText; + USHORT nHelpTextRefId; + + ByteStringHashMap sQuickHelpText; + USHORT nQuickHelpTextRefId; + + ByteStringHashMap sTitle; + USHORT nTitleRefId; + + ByteString sTextTyp; + ByteStringHashMap aFallbackData; + ByteStringHashMap aMergedLanguages; + + ExportList *pStringList; + ExportList *pUIEntries; + ExportList *pItemList; + ExportList *pFilterList; + ExportList *pPairedList; + + ByteString sPForm; + + void Dump(); + void addFallbackData( ByteString& sId , const ByteString& sText ); + bool getFallbackData( ByteString& sId , ByteString& sText); + + void addMergedLanguage( ByteString& sLang ); + bool isMerged( ByteString& sLang ); + ResData( const ByteString &rPF, const ByteString &rGId ) + : + nWidth( 0 ), + nChildIndex( 0 ), + nIdLevel( ID_LEVEL_NULL ), + bChild( FALSE ), + bChildWithText( FALSE ), + bText( FALSE ), + bHelpText( FALSE ), + bQuickHelpText( FALSE ), + bTitle( FALSE ), + bList( FALSE ), + bRestMerged( FALSE ), + sGId( rGId ), + nTextRefId( REFID_NONE ), + nHelpTextRefId( REFID_NONE ), + nQuickHelpTextRefId( REFID_NONE ), + nTitleRefId( REFID_NONE ), + sTextTyp( "Text" ), + pStringList( NULL ), + pUIEntries( NULL ), + pItemList( NULL ), + pFilterList( NULL ), + pPairedList( NULL ), + sPForm( rPF ) + { + sGId.EraseAllChars( '\r' ); + sPForm.EraseAllChars( '\r' ); + }; + ResData( const ByteString &rPF, const ByteString &rGId , const ByteString &rFilename ) + : + nChildIndex( 0 ), + nIdLevel( ID_LEVEL_NULL ), + bChild( FALSE ), + bChildWithText( FALSE ), + bText( FALSE ), + bHelpText( FALSE ), + bQuickHelpText( FALSE ), + bTitle( FALSE ), + bList( FALSE ), + bRestMerged( FALSE ), + sGId( rGId ), + sFilename( rFilename ), + nTextRefId( REFID_NONE ), + nHelpTextRefId( REFID_NONE ), + nQuickHelpTextRefId( REFID_NONE ), + nTitleRefId( REFID_NONE ), + sTextTyp( "Text" ), + pStringList( NULL ), + pUIEntries( NULL ), + pItemList( NULL ), + pFilterList( NULL ), + pPairedList( NULL ), + sPForm( rPF ) + + { + sGId.EraseAllChars( '\r' ); + sPForm.EraseAllChars( '\r' ); + }; + + +}; + + +// +// class Export +// + +/****************************************************************************** +* Purpose: syntax check and export of *.src, called from lexer +******************************************************************************/ + +#define LIST_NON 0x0000 +#define LIST_STRING 0x0001 +#define LIST_FILTER 0x0002 +#define LIST_ITEM 0x0004 +#define LIST_PAIRED 0x0005 +#define LIST_UIENTRIES 0x0008 +#define STRING_TYP_TEXT 0x0010 +#define STRING_TYP_HELPTEXT 0x0020 +#define STRING_TYP_QUICKHELPTEXT 0x0040 +#define STRING_TYP_TITLE 0x0080 + +#define MERGE_MODE_NORMAL 0x0000 +#define MERGE_MODE_LIST 0x0001 + +DECLARE_LIST( ResStack, ResData * ) +// forwards +class WordTransformer; +class ParserQueue; + +class Export +{ +private: + WordTransformer *pWordTransformer; + + CharSet aCharSet; // used charset in src + + SvFileStream aOutput; + + ResStack aResStack; // stack for parsing recursive + + ByteString sActPForm; // hold cur. system + + BOOL bDefine; // cur. res. in a define? + BOOL bNextMustBeDefineEOL; // define but no \ at lineend + ULONG nLevel; // res. recursiv? how deep? + USHORT nList; // cur. res. is String- or FilterList + ByteString nListLang; + ULONG nListIndex; + ULONG nListLevel; + bool bSkipFile; + ByteString sProject; + ByteString sRoot; + BOOL bEnableExport; + BOOL bMergeMode; + ByteString sMergeSrc; + ByteString sLastListLine; + BOOL bError; // any errors while export? + BOOL bReadOver; + BOOL bDontWriteOutput; + ByteString sLastTextTyp; + static bool isInitialized; + ByteString sFilename; + + +public: + ParserQueue* pParseQueue; // public ? + static ByteString sLanguages; // public ? + static ByteString sForcedLanguages; // public ? + + + static bool skipProject( ByteString sPrj ) ; + static ByteString sIsoCode99; + static void InitLanguages( bool bMergeMode = false ); + static void InitForcedLanguages( bool bMergeMode = false ); + static std::vector<ByteString> GetLanguages(); + static std::vector<ByteString> GetForcedLanguages(); + + static void SetLanguages( std::vector<ByteString> val ); + static void RemoveUTF8ByteOrderMarker( ByteString &rString ); + static bool hasUTF8ByteOrderMarker( const ByteString &rString ); + static void RemoveUTF8ByteOrderMarkerFromFile( const ByteString &rFilename ); + static bool fileHasUTF8ByteOrderMarker( const ByteString &rString ); + static ByteString GetIsoLangByIndex( USHORT nIndex ); + static void QuotHTML( ByteString &rString ); + static bool CopyFile( const ByteString& source , const ByteString& dest ); + + static void QuotHTMLXRM( ByteString &rString ); + static void UnquotHTML( ByteString &rString ); + + static const char* GetEnv( const char *pVar ); + static int getCurrentDirectory( rtl::OUString& base_fqurl , rtl::OUString& base ); + + static bool isSourceLanguage( const ByteString &sLanguage ); + static bool isAllowed( const ByteString &sLanguage ); + //static bool isMergingGermanAllowed( const ByteString& rPrj ); + + static bool LanguageAllowed( const ByteString &nLanguage ); + static void Languages( std::vector<ByteString>::const_iterator& begin , std::vector<ByteString>::const_iterator& end ); + static void getRandomName( const ByteString& sPrefix , ByteString& sRandStr , const ByteString& sPostfix ); + static void getRandomName( ByteString& sRandStr ); + + static void replaceEncoding( ByteString& rString ); + + static ByteString GetFallbackLanguage( const ByteString nLanguage ); + static void FillInFallbacks( ResData *pResData ); + static void FillInListFallbacks( ExportList *pList, const ByteString &nSource, const ByteString &nFallback ); + static ByteString GetTimeStamp(); + static BOOL ConvertLineEnds( ByteString sSource, ByteString sDestination ); + static ByteString GetNativeFile( ByteString sSource ); + static DirEntry GetTempFile(); + + static void DumpExportList( ByteString& sListName , ExportList& aList ); + static ByteString DumpMap( ByteString& sMapName , ByteStringHashMap& aMap ); + +private: + static std::vector<ByteString> aLanguages; + static std::vector<ByteString> aForcedLanguages; + + BOOL ListExists( ResData *pResData, USHORT nLst ); + + BOOL WriteData( ResData *pResData, BOOL bCreateNew = FALSE );// called befor dest. cur ResData + BOOL WriteExportList( ResData *pResData, ExportList *pExportList, + const ByteString &rTyp, BOOL bCreateNew = FALSE ); + + ByteString MergePairedList( ByteString& sLine , ByteString& sText ); + + ByteString FullId(); // creates cur. GID + + bool PairedListFallback( ByteString& sText , ResData& aResData ); + + ByteString GetPairedListID ( const ByteString& sText ); + ByteString GetPairedListString ( const ByteString& sText ); + ByteString StripList ( const ByteString& sText ); + + void UnmergeUTF8( ByteString& sOrig ); + void InsertListEntry( const ByteString &rText, const ByteString &rLine ); + void CleanValue( ByteString &rValue ); + ByteString GetText( const ByteString &rSource, int nToken ); + + BOOL PrepareTextToMerge( ByteString &rText, USHORT nTyp, + ByteString &nLangIndex, ResData *pResData ); + + void MergeRest( ResData *pResData, USHORT nMode = MERGE_MODE_NORMAL ); + void ConvertMergeContent( ByteString &rText ); + + void WriteToMerged( const ByteString &rText , bool bSDFContent ); + void SetChildWithText(); + + void CutComment( ByteString &rText ); + +public: + Export( const ByteString &rOutput, BOOL bWrite, + const ByteString &rPrj, const ByteString &rPrjRoot , const ByteString& rFile ); + Export( const ByteString &rOutput, BOOL bWrite, + const ByteString &rPrj, const ByteString &rPrjRoot, + const ByteString &rMergeSource , const ByteString& rFile ); + ~Export(); + + void Init(); + int Execute( int nToken, const char * pToken ); // called from lexer + void SetError() { bError = TRUE; } + BOOL GetError() { return bError; } +}; + + +// +// class PFormEntrys +// + +/****************************************************************************** +* Purpose: holds information of data to merge (one pform) +******************************************************************************/ + +class PFormEntrys : public ByteString +{ +friend class MergeDataFile; +private: + ByteString sHelpText; // empty string + ByteStringHashMap sText; + ByteStringBoolHashMap bTextFirst; + ByteStringHashMap sQuickHelpText; + ByteStringBoolHashMap bQuickHelpTextFirst; + ByteStringHashMap sTitle; + ByteStringBoolHashMap bTitleFirst; + +public: + PFormEntrys( const ByteString &rPForm ) : ByteString( rPForm ) {}; + ByteString Dump(); + void InsertEntry( + const ByteString &nId , + const ByteString &rText, + const ByteString &rQuickHelpText, + const ByteString &rTitle + ) + { + + sText[ nId ] = rText; + bTextFirst[ nId ] = true; + sQuickHelpText[ nId ] = rQuickHelpText; + bQuickHelpTextFirst[ nId ] = true; + sTitle[ nId ] = rTitle; + bTitleFirst[ nId ] = true; + } + BOOL GetText( ByteString &rReturn, USHORT nTyp, const ByteString &nLangIndex, BOOL bDel = FALSE ); +}; + +// +// class MergeData +// + +/****************************************************************************** +* Purpose: holds information of data to merge (one ressource) +******************************************************************************/ + +class MergeDataFile; + +class MergeData +{ +friend class MergeDataFile; +private: + ByteString sTyp; + ByteString sGID; + ByteString sLID; + ByteString sFilename; + PFormEntrysHashMap aMap; +public: + MergeData( const ByteString &rTyp, const ByteString &rGID, const ByteString &rLID , const ByteString &rFilename ) + : sTyp( rTyp ), sGID( rGID ), sLID( rLID ) , sFilename( rFilename ) {}; + ~MergeData(); + PFormEntrys* InsertEntry( const ByteString &rPForm ); + PFormEntrys* GetPFormEntrys( ResData *pResData ); + + void Insert( const ByteString& rPFO , PFormEntrys* pfEntrys ); + PFormEntrys* GetPFObject( const ByteString& rPFO ); + + ByteString Dump(); + BOOL operator==( ResData *pData ); +}; + +// +// class MergeDataFile +// + +/****************************************************************************** +* Purpose: holds information of data to merge +******************************************************************************/ + +class MergeDataFile +{ +private: + BOOL bErrorLog; + ByteString sErrorLog; + SvFileStream aErrLog; + ByteStringSet aLanguageSet; + MergeDataHashMap aMap; + std::vector<ByteString> aLanguages; + + +public: + MergeDataFile( const ByteString &rFileName, const ByteString& rFile , BOOL bErrLog, CharSet aCharSet, bool bCaseSensitive = false ); +// MergeDataFile( const ByteString &rFileName, const ByteString& rFile , BOOL bErrLog, CharSet aCharSet +// ); + ~MergeDataFile(); + + + std::vector<ByteString> GetLanguages(); + MergeData *GetMergeData( ResData *pResData , bool bCaseSensitve = false ); + + PFormEntrys *GetPFormEntrys( ResData *pResData ); + PFormEntrys *GetPFormEntrysCaseSensitive( ResData *pResData ); + + void InsertEntry( const ByteString &rTYP, const ByteString &rGID, const ByteString &rLID, + const ByteString &rPFO, + const ByteString &nLang , const ByteString &rTEXT, + const ByteString &rQHTEXT, const ByteString &rTITLE , + const ByteString &sFilename , bool bCaseSensitive + ); + static USHORT GetLangIndex( USHORT nId ); + static ByteString CreateKey( const ByteString& rTYP , const ByteString& rGID , const ByteString& rLID , const ByteString& rFilename , bool bCaseSensitive = false ); + + ByteString Dump(); +// void WriteErrorLog( const ByteString &rFileName ); + void WriteError( const ByteString &rLine ); +}; + + +class QueueEntry +{ +public: + QueueEntry( int nTypVal , ByteString sLineVal ): nTyp( nTypVal ) , sLine( sLineVal ){}; + int nTyp; + ByteString sLine; +}; + +class ParserQueue +{ +public: + + ParserQueue( Export& aExportObj ); + ~ParserQueue(); + + inline void Push( const QueueEntry& aEntry ); + bool bCurrentIsM; // public ? + bool bNextIsM; // public ? + bool bLastWasM; // public ? + bool bMflag; // public ? + + void Close(); +private: + // Future / Next + std::queue<QueueEntry>* aQueueNext; + // Current + std::queue<QueueEntry>* aQueueCur; + // Ref + std::queue<QueueEntry>* aQref; + + Export& aExport; + bool bStart; + bool bStartNext; + + inline void Pop( std::queue<QueueEntry>& aQueue ); + +}; +#endif + diff --git a/transex3/inc/helpmerge.hxx b/transex3/inc/helpmerge.hxx new file mode 100644 index 000000000000..0ebfa7ed62a9 --- /dev/null +++ b/transex3/inc/helpmerge.hxx @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: helpmerge.hxx,v $ + * $Revision: 1.12 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// local includes +#include "export.hxx" +#include "xmlparse.hxx" +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> +#include <memory> /* auto_ptr */ +#include "tools/isofallback.hxx" + +#define MOVEFILE_REPLACE_EXISTING 0x01 + +/// This Class is responsible for extracting/merging OpenOffice XML Helpfiles +class HelpParser +{ +private: + ByteString sHelpFile; + bool bUTF8; + bool bHasInputList; + +/// Copy fallback language String (ENUS,DE) into position of the numeric language iso code +/// @PRECOND 0 < langIdx_in < MAX_IDX + static void FillInFallbacks( LangHashMap& rElem_out, ByteString sLangIdx_in ); + +/// Debugmethod, prints the content of the map to stdout + static void Dump( LangHashMap* rElem_in , const ByteString sKey_in ); + +/// Debugmethod, prints the content of the map to stdout + static void Dump( XMLHashMap* rElem_in ) ; + + + +public: + HelpParser( const ByteString &rHelpFile, bool bUTF8 , bool bHasInputList ); + ~HelpParser(){}; + +/// Method creates/append a SDF file with the content of a parsed XML file +/// @PRECOND rHelpFile is valid + static bool CreateSDF( const ByteString &rSDFFile_in, const ByteString &rPrj_in, const ByteString &rRoot_in, + const ByteString &sHelpFile, XMLFile *pXmlFile, const ByteString &rGsi1 ); + + static void parse_languages( std::vector<ByteString>& aLanguages , MergeDataFile& aMergeDataFile ); + +/// Method merges the String from the SDFfile into XMLfile. Both Strings must +/// point to existing files. + bool Merge( const ByteString &rSDFFile_in, const ByteString &rDestinationFile_in , ByteString& sLanguage , MergeDataFile& aMergeDataFile ); + bool Merge( const ByteString &rSDFFile, const ByteString &rPathX , const ByteString &rPathY , bool bISO + , const std::vector<ByteString>& aLanguages , MergeDataFile& aMergeDataFile , bool bCreateDir ); + +private: + static ByteString makeAbsolutePath( const ByteString& sHelpFile , const ByteString& rRoot_in ); + + ByteString GetOutpath( const ByteString& rPathX , const ByteString& sCur , const ByteString& rPathY ); + bool MergeSingleFile( XMLFile* file , MergeDataFile& aMergeDataFile , const ByteString& sLanguage , ByteString sPath ); + + void Process( LangHashMap* aLangHM , const ByteString& sCur , ResData *pResData , MergeDataFile& aMergeDataFile ); + void ProcessHelp( LangHashMap* aLangHM , const ByteString& sCur , ResData *pResData , MergeDataFile& aMergeDataFile ); + void MakeDir( const ByteString& sPath ); +}; diff --git a/transex3/inc/lngmerge.hxx b/transex3/inc/lngmerge.hxx new file mode 100644 index 000000000000..502889b27aa9 --- /dev/null +++ b/transex3/inc/lngmerge.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lngmerge.hxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// local includes +#include "export.hxx" + +DECLARE_LIST( LngLineList, ByteString * ) + +#define LNG_OK 0x0000 +#define LNG_FILE_NOTFOUND 0x0001 +#define LNG_COULD_NOT_OPEN 0x0002 +#define SDF_OK 0x0003 +#define SDF_FILE_NOTFOUND 0x0004 +#define SDF_COULD_NOT_OPEN 0x0005 + +// +// class LngParser +// + +class LngParser +{ +private: + USHORT nError; + LngLineList *pLines; + ByteString sSource; + BOOL bDBIsUTF8; + BOOL bULF; + bool bQuiet; + std::vector<ByteString> aLanguages; + + void FillInFallbacks( ByteStringHashMap Text ); + bool isNextGroup( ByteString &sGroup_out , ByteString &sLine_in); + void ReadLine( const ByteString &sLine_in , ByteStringHashMap &rText_inout ); + void WriteSDF( SvFileStream &aSDFStream , ByteStringHashMap &rText_inout , + const ByteString &rPrj , + const ByteString &rRoot , const ByteString &sActFileName , const ByteString &sID ); +public: + LngParser( const ByteString &rLngFile, BOOL bUTF8, BOOL bULFFormat, bool bQuiet_in ); + ~LngParser(); + + BOOL CreateSDF( const ByteString &rSDFFile, const ByteString &rPrj, const ByteString &rRoot ); + BOOL Merge( const ByteString &rSDFFile, const ByteString &rDestinationFile , const ByteString &rPrj ); +}; diff --git a/transex3/inc/makefile.mk b/transex3/inc/makefile.mk new file mode 100644 index 000000000000..00caed43733a --- /dev/null +++ b/transex3/inc/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=.. + +PRJNAME=transex3 +TARGET=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/transex3/inc/pch/precompiled_transex3.cxx b/transex3/inc/pch/precompiled_transex3.cxx new file mode 100644 index 000000000000..5b69c9f2f204 --- /dev/null +++ b/transex3/inc/pch/precompiled_transex3.cxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: precompiled_transex3.cxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_transex3.hxx" + diff --git a/transex3/inc/pch/precompiled_transex3.hxx b/transex3/inc/pch/precompiled_transex3.hxx new file mode 100644 index 000000000000..2ed3c72ad4ee --- /dev/null +++ b/transex3/inc/pch/precompiled_transex3.hxx @@ -0,0 +1,35 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: precompiled_transex3.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:15.326479 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/transex3/inc/srciter.hxx b/transex3/inc/srciter.hxx new file mode 100644 index 000000000000..bcbdf5eb542b --- /dev/null +++ b/transex3/inc/srciter.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: srciter.hxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef TRANSEX_DIRECTORY_HXX +#define TRANSEX_DIRECTORY_HXX +#include <transex3/directory.hxx> +#endif + +// class SourceTreeIterator +// + +class SourceTreeIterator +{ +private: + transex::Directory aRootDirectory; + bool bInExecute; + + void ExecuteDirectory( transex::Directory& pDirectory ); + +protected: + bool bLocal; + bool bSkipLinks; + +public: + SourceTreeIterator( const ByteString &rRootDirectory, const ByteString &rVersion , bool bLocal_in = false); + virtual ~SourceTreeIterator(); + + BOOL StartExecute(); + void EndExecute(); + + virtual void OnExecuteDirectory( const rtl::OUString &rDirectory ); +}; + + diff --git a/transex3/inc/tagtest.hxx b/transex3/inc/tagtest.hxx new file mode 100644 index 000000000000..811c4bf0e164 --- /dev/null +++ b/transex3/inc/tagtest.hxx @@ -0,0 +1,399 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tagtest.hxx,v $ + * $Revision: 1.12 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TAGTEST_HXX_ +#define _TAGTEST_HXX_ + +#include <tools/string.hxx> +#include <tools/list.hxx> +#include <hash_map> /* std::hashmap*/ + +class GSILine; + +typedef USHORT TokenId; + +#define TOK_INVALIDPOS USHORT( 0xFFFF ) + +class ParserMessage; + +DECLARE_LIST( Impl_ParserMessageList, ParserMessage* ) +class ParserMessageList; + + +struct equalByteString{ + bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { + return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL; + } +}; +struct lessByteString{ + bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { + return rKey1.CompareTo( rKey2 )==COMPARE_LESS; + } +}; + +struct hashByteString{ + size_t operator()( const ByteString& rName ) const{ + std::hash< const char* > myHash; + return myHash( rName.GetBuffer() ); + } +}; + + + +typedef std::hash_map<ByteString , String , hashByteString,equalByteString> + StringHashMap; + +class TokenInfo +{ +private: + void SplitTag( ParserMessageList &rErrorList ); + + String aTagName; + StringHashMap aProperties; + BOOL bClosed; // tag is closed <sdnf/> + BOOL bCloseTag; // tag is close Tag </sdnf> + + + BOOL bIsBroken; + BOOL bHasBeenFixed; + BOOL bDone; + +public: + + String aTokenString; + TokenId nId; + USHORT nPos; // Position in String + + TokenInfo():bClosed(FALSE),bCloseTag(FALSE),bIsBroken(FALSE),bHasBeenFixed(FALSE),bDone(FALSE),nId( 0 ){;} +explicit TokenInfo( TokenId pnId, USHORT nP ):bClosed(FALSE),bCloseTag(FALSE),bIsBroken(FALSE),bHasBeenFixed(FALSE),bDone(FALSE),nId( pnId ),nPos(nP){;} +explicit TokenInfo( TokenId pnId, USHORT nP, String paStr ):bClosed(FALSE),bCloseTag(FALSE),bIsBroken(FALSE),bHasBeenFixed(FALSE),bDone(FALSE),aTokenString( paStr ),nId( pnId ),nPos(nP) {;} +explicit TokenInfo( TokenId pnId, USHORT nP, String paStr, ParserMessageList &rErrorList ); + + String GetTagName() const; + + String MakeTag() const; + + /** + Is the property to be ignored or does it have the default value anyways + **/ + BOOL IsPropertyRelevant( const ByteString &aName, const String &aValue ) const; + BOOL IsPropertyValueValid( const ByteString &aName, const String &aValue ) const; + /** + Does the property contain the same value for all languages + e.g.: the href in a link tag + **/ + BOOL IsPropertyInvariant( const ByteString &aName, const String &aValue ) const; + /** + a subset of IsPropertyInvariant but containing only those that are fixable + we dont wat to fix e.g.: ahelp :: visibility + **/ + BOOL IsPropertyFixable( const ByteString &aName ) const; + BOOL MatchesTranslation( TokenInfo& rInfo, BOOL bGenErrors, ParserMessageList &rErrorList, BOOL bFixTags = FALSE ) const; + + BOOL IsDone() const { return bDone; } + void SetDone( BOOL bNew = TRUE ) { bDone = bNew; } + + BOOL HasBeenFixed() const { return bHasBeenFixed; } + void SetHasBeenFixed( BOOL bNew = TRUE ) { bHasBeenFixed = bNew; } +}; + + +class ParserMessageList : public Impl_ParserMessageList +{ +public: + void AddError( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag ); + void AddWarning( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag ); + + BOOL HasErrors(); +}; + + +#define TAG_GROUPMASK 0xF000 +#define TAG_GROUPSHIFT 12 + +#define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT ) +#define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT + +#define TAG_NOMORETAGS 0x0 + +#define TAG_GROUP_FORMAT 0x1 +#define TAG_ON 0x100 +#define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 ) +#define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 ) +#define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 ) +#define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 ) +#define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 ) +#define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 ) + +#define TAG_GROUP_NOTALLOWED 0x2 +#define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 ) +#define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 ) +#define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 ) + +#define TAG_GROUP_STRUCTURE 0x3 +#define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 ) +#define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 ) +#define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 ) +#define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 ) + +#define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 ) +#define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 ) +#define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 ) + +#define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 ) + +#define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 ) +#define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 ) + +#define TAG_GROUP_SYSSWITCH 0x4 +#define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 ) +#define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 ) +#define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 ) +#define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 ) + +#define TAG_GROUP_PROGSWITCH 0x5 +#define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 ) +#define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 ) +#define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 ) +#define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 ) +#define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 ) +#define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 ) +#define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 ) +#define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 ) +#define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 ) + + +#define TAG_GROUP_META 0x6 +#define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 ) +#define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 ) +#define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 ) +#define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 ) +#define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 ) +#define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 ) +#define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 ) +#define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 ) +#define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 ) + + +#define TAG_GROUP_SINGLE 0x7 +#define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 ) + + +#define TAG_GROUP_MULTI 0x8 +#define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 ) +#define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 ) +#define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 ) +#define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 ) +#define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 ) + +#define TAG_GROUP_MISC 0x9 +#define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 ) +#define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 ) + +#define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 ) + +DECLARE_LIST( TokenListImpl, TokenInfo* ) + +class TokenList : private TokenListImpl +{ +private: + + TokenList& operator =( const TokenList& rList ); +// { TokenListImpl::operator =( rList ); return *this; } + + +public: + using TokenListImpl::Count; + + + TokenList() : TokenListImpl(){}; + ~TokenList(){ Clear(); }; + + void Clear() + { + for ( ULONG i = 0 ; i < Count() ; i++ ) + delete TokenListImpl::GetObject( i ); + TokenListImpl::Clear(); + } + void Insert( TokenInfo p, ULONG nIndex = LIST_APPEND ) + { TokenListImpl::Insert( new TokenInfo(p), nIndex ); } +/* TokenInfo Remove( ULONG nIndex ) + { + TokenInfo aT = GetObject( nIndex ); + delete TokenListImpl::GetObject( nIndex ); + TokenListImpl::Remove( nIndex ); + return aT; + }*/ +// TokenInfo Remove( TokenInfo p ){ return Remove( GetPos( p ) ); } +// TokenInfo GetCurObject() const { return *TokenListImpl::GetCurObject(); } + TokenInfo& GetObject( ULONG nIndex ) const + { +// if ( TokenListImpl::GetObject(nIndex) ) + return *TokenListImpl::GetObject(nIndex); +// else +// return TokenInfo(); + } +/* ULONG GetPos( const TokenInfo p ) const + { + for ( ULONG i = 0 ; i < Count() ; i++ ) + if ( p == GetObject( i ) ) + return i; + return LIST_ENTRY_NOTFOUND; + }*/ + + TokenList( const TokenList& rList ); +/* { + for ( ULONG i = 0 ; i < rList.Count() ; i++ ) + { + Insert( rList.GetObject( i ), LIST_APPEND ); + } + }*/ +}; + +class ParserMessage +{ + USHORT nErrorNr; + ByteString aErrorText; + USHORT nTagBegin,nTagLength; + +protected: + ParserMessage( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ); +public: + + USHORT GetErrorNr() { return nErrorNr; } + ByteString GetErrorText() { return aErrorText; } + + USHORT GetTagBegin() { return nTagBegin; } + USHORT GetTagLength() { return nTagLength; } + + virtual ~ParserMessage() {} + virtual BOOL IsError() =0; + virtual ByteString Prefix() =0; +}; + +class ParserError : public ParserMessage +{ +public: + ParserError( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ); + + virtual BOOL IsError() {return TRUE;}; + virtual ByteString Prefix() {return "Error:"; }; +}; + +class ParserWarning : public ParserMessage +{ +public: + ParserWarning( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ); + + virtual BOOL IsError() {return FALSE;}; + virtual ByteString Prefix() {return "Warning:"; }; +}; + +class SimpleParser +{ +private: + USHORT nPos; + String aSource; + String aLastToken; + TokenList aTokenList; + + TokenInfo aNextTag; // to store closetag in case of combined tags like <br/> + + String GetNextTokenString( ParserMessageList &rErrorList, USHORT &rTokeStartPos ); + +public: + SimpleParser(); + void Parse( String PaSource ); + TokenInfo GetNextToken( ParserMessageList &rErrorList ); + static String GetLexem( TokenInfo const &aToken ); + TokenList& GetTokenList(){ return aTokenList; } +}; + +class TokenParser +{ + BOOL match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken ); + BOOL match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken ); + void ParseError( USHORT nErrNr, ByteString aErrMsg, const TokenInfo &rTag ); + void Paragraph(); + void PfCase(); + void PfCaseBegin(); + void AppCase(); + void AppCaseBegin(); + void CaseEnd(); + void SimpleTag(); + void TagPair(); + void TagRef(); + + SimpleParser aParser; + TokenInfo aTag; + + TokenId nPfCaseOptions; + TokenId nAppCaseOptions; + BOOL bPfCaseActive ,bAppCaseActive; + + TokenId nActiveRefTypes; + + ParserMessageList *pErrorList; + +public: + TokenParser(); + void Parse( const String &aCode, ParserMessageList* pList ); +// ParserMessageList& GetErrors(){ return aErrorList; } +// BOOL HasErrors(){ return ( aErrorList.Count() > 0 ); } + TokenList& GetTokenList(){ return aParser.GetTokenList(); } +}; + +class LingTest +{ +private: + TokenParser aReferenceParser; + TokenParser aTesteeParser; + ParserMessageList aCompareWarningList; + void CheckTags( TokenList &aReference, TokenList &aTestee, BOOL bFixTags ); + BOOL IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens ); + String aFixedTestee; +public: + void CheckReference( GSILine *aReference ); + void CheckTestee( GSILine *aTestee, BOOL bHasSourceLine, BOOL bFixTags ); + +// ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); } +// BOOL HasReferenceErrors(){ return aReferenceParser.HasErrors(); } + +// ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); } +// BOOL HasTesteeErrors(){ return aTesteeParser.HasErrors(); } + + ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; } + BOOL HasCompareWarnings(){ return ( aCompareWarningList.Count() > 0 ); } + + String GetFixedTestee(){ return aFixedTestee; } +}; + +#endif + diff --git a/transex3/inc/tokens.h b/transex3/inc/tokens.h new file mode 100644 index 000000000000..ef285f4c6361 --- /dev/null +++ b/transex3/inc/tokens.h @@ -0,0 +1,112 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokens.h,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TOKENS_H +#define _TOKENS_H + +/*------------------------------------------------------ */ +/*------------------------------------------------------ */ +/* Tokens for parsing src files */ +/*------------------------------------------------------ */ +/*------------------------------------------------------ */ +#define IGNOREDTOKENS 400 /* #include | #pragma | //... | ... */ +#define COMMEND 401 /*... */ +#define DEFINEDRES 402 /* Text = { */ +#define ANYTOKEN 404 /* XYZ */ +#define UNKNOWNTOKEN 405 /* XYZ[ \t]$ */ +#define UNKNOWNCONSTRUCTION 406 /* XYZ ( xxx, yyy, zzz ) */ +#define UNKNOWNCHAR 407 /* . */ +/*------------------------------------------------------ */ +/* prev. tokens will not be executed */ +#define FILTER_LEVEL 500 +/* following tokens will be executed */ +/*------------------------------------------------------ */ +#define CONDITION 501 /* #if... | #endif ... | ... */ +#define EMPTYLINE 502 /* */ +#define RESSOURCE 503 /* Menu MID_TEST */ +#define RESSOURCEEXPR 504 /* Menu ( MID_TEST + .. ) */ +#define SMALRESSOURCE 505 /* PageItem { */ +#define TEXTLINE 506 /* TEXT = "hhh" */ +#define LONGTEXTLINE 507 /* TEXT = "hhh" TEST "HHH" ... */ +#define TEXT 508 /* "Something like this" */ +#define LEVELUP 509 /* { */ +#define LEVELDOWN 510 /* }; */ +#define APPFONTMAPPING 511 /* MAP_APPFONT(10,10) */ +#define ASSIGNMENT 512 /* Somathing = Anything */ +#define LISTASSIGNMENT 513 /* ...List [xyz]=... */ +#define LISTTEXT 514 /* < "Text" ... > */ +#define RSCDEFINE 515 /* #define MY_TEXT */ +#define RSCDEFINELEND 516 /* */ +#define NEWTEXTINRES 517 /* ### Achtung : Ne... */ +#define UIENTRIES 518 /* UIEntries = { */ +#define PRAGMA 519 /* #pragma ... */ +#define _LISTTEXT 521 /* { "Text" ... } */ +#define TEXTREFID 522 /* Text = 12345 */ +#define LISTRESID 523 /* < 12345; ... > */ +#define _LISTRESID 523 /* { 12345; ... } */ +#define NORMDEFINE 524 /* #define ... */ +/*------------------------------------------------------ */ +/*------------------------------------------------------ */ +/* Tokens for parsing cfg files */ +/*------------------------------------------------------ */ +/*------------------------------------------------------ */ +#define CFG_TAG 501 +#define CFG_TEXT_START 505 +#define CFG_TEXT_END 506 +#define CFG_TEXTCHAR 507 +#define CFG_CLOSETAG 508 +#define CFG_UNKNOWNTAG 509 +#define CFG_TOKEN_PACKAGE 600 +#define CFG_TOKEN_COMPONENT 601 +#define CFG_TOKEN_CONFIGNAME 602 +#define CFG_TOKEN_TEMPLATE 603 +#define CFG_TOKEN_OORNAME 604 +#define CFG_TOKEN_OORVALUE 605 +#define CFG_TOKEN_NO_TRANSLATE 606 + +/*------------------------------------------------------ */ +/*------------------------------------------------------ */ +/* Tokens for parsing xrm files */ +/*------------------------------------------------------ */ +/*------------------------------------------------------ */ +#define XRM_README_START 501 +#define XRM_README_END 502 +#define XRM_SECTION_START 503 +#define XRM_SECTION_END 504 +#define XRM_PARAGRAPH_START 505 +#define XRM_PARAGRAPH_END 506 +#define XRM_TEXT_START 507 +#define XRM_TEXT_END 508 +#define XRM_LIST_START 509 +#define XRM_LIST_END 510 +#define XML_TEXTCHAR 600 + + +#endif diff --git a/transex3/inc/transex3/directory.hxx b/transex3/inc/transex3/directory.hxx new file mode 100644 index 000000000000..6e507961d3bb --- /dev/null +++ b/transex3/inc/transex3/directory.hxx @@ -0,0 +1,54 @@ +#include <vector> +#include <algorithm> +#include <rtl/ustring.hxx> +#include <tools/string.hxx> + +#ifdef WNT +#else +#include <dirent.h> +#include <unistd.h> +#include <sys/stat.h> +#endif + +#include <stdio.h> + +#ifndef TRANSEX_FILE_HXX +#define TRANSEX_FILE_HXX +#include <transex3/file.hxx> +#endif + +namespace transex{ + +class Directory +{ + private: + rtl::OUString sDirectoryName; + rtl::OUString sFullName; + bool bSkipLinks; + + std::vector<Directory> aDirVec; + std::vector<File> aFileVec; + + public: + std::vector<Directory> getSubDirectories() { return aDirVec; } + std::vector<File> getFiles() { return aFileVec; } + + void readDirectory(); + void readDirectory( const rtl::OUString& sFullpath ); + void scanSubDir( int nLevels = 0 ); + + rtl::OUString getDirectoryName() { return sDirectoryName; } + rtl::OUString getFullName() { return sFullName ; } + void setSkipLinks( bool is_skipped ); + + void dump(); + Directory(){}; + + Directory( const rtl::OUString sFullPath ); + Directory( const rtl::OUString sFullPath , const rtl::OUString sEntry ) ; + Directory( const ByteString sFullPath ); + + static bool lessDir ( const Directory& rKey1, const Directory& rKey2 ) ; +}; + +} diff --git a/transex3/inc/transex3/file.hxx b/transex3/inc/transex3/file.hxx new file mode 100644 index 000000000000..e3a1a46b4ee8 --- /dev/null +++ b/transex3/inc/transex3/file.hxx @@ -0,0 +1,23 @@ +#include "rtl/ustring.hxx" + +namespace transex +{ + +class File +{ + private: + rtl::OUString sFileName; + rtl::OUString sFullName; + + public: + rtl::OUString getFileName(){ return sFileName; } + rtl::OUString getFullName(){ return sFullName; } + + File( const rtl::OUString sFile ); + File( const rtl::OUString sFullName , const rtl::OUString sFile ); + + static bool lessFile ( const File& rKey1, const File& rKey2 ); + +}; + +} diff --git a/transex3/inc/transex3/vosapp.hxx b/transex3/inc/transex3/vosapp.hxx new file mode 100644 index 000000000000..49e10e15e3d4 --- /dev/null +++ b/transex3/inc/transex3/vosapp.hxx @@ -0,0 +1,33 @@ +#ifndef VOSAPP_HXX +#define VOSAPP_HXX + +#include <sal/main.h> +#include <tools/solar.h> +#include <tools/string.hxx> +#include <vos/process.hxx> + +// Mininmal vcl/svapp compatibility without vcl dependence +class Application +{ +public: + USHORT GetCommandLineParamCount(); + XubString GetCommandLineParam( USHORT nParam ); + virtual void Main() = 0; +}; + +// Urg: Cut & Paste from svapp.cxx: we don't want to depend on vcl +USHORT Application::GetCommandLineParamCount() +{ + vos::OStartupInfo aStartInfo; + return (USHORT)aStartInfo.getCommandArgCount(); +} + +XubString Application::GetCommandLineParam( USHORT nParam ) +{ + vos::OStartupInfo aStartInfo; + rtl::OUString aParam; + aStartInfo.getCommandArg( nParam, aParam ); + return XubString( aParam ); +} + +#endif /* VOSAPP_HXX */ diff --git a/transex3/inc/utf8conv.hxx b/transex3/inc/utf8conv.hxx new file mode 100644 index 000000000000..32e506edbda8 --- /dev/null +++ b/transex3/inc/utf8conv.hxx @@ -0,0 +1,47 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: utf8conv.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// global includes +#include <rtl/textcvt.h> +#include <tools/string.hxx> + +// +// class UTF8Converter +// + +class UTF8Converter +{ +private: + static void Convert( ByteString &rBuffer, rtl_TextEncoding nSourceENC, rtl_TextEncoding nDestENC ); + +public: + static ByteString ConvertToUTF8( const ByteString &rASCII, rtl_TextEncoding nEncoding ); + static ByteString ConvertFromUTF8( const ByteString &rUTF8, rtl_TextEncoding nEncoding ); +}; diff --git a/transex3/inc/wrdtrans.hxx b/transex3/inc/wrdtrans.hxx new file mode 100644 index 000000000000..efcb663204a6 --- /dev/null +++ b/transex3/inc/wrdtrans.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wrdtrans.hxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + +// OBSOLETE // + +#ifndef TX3_WRDTRANS_HXX +#define TX3_WRDTRANS_HXX + +// USED + // Base Classes + // Components +class WordTransTree; +class WordTrans_ErrorList; + // Parameters +#include <tools/string.hxx> + +class WordTransformer +{ + public: + enum E_Error + { + OK = 0, + ERROR_NO_WORDLIST, + ERROR_HOTKEY, + ERROR_OUTPUTSTRING_TOO_LONG, + OTHER_ERROR + }; + + // LIFECYCLE + WordTransformer(); + ~WordTransformer(); + BOOL LoadWordlist( /// @return False, if file could not be read, or there is already a wordlist loaded. + const ByteString & i_sWordlist_Filepath, + CharSet i_nWorkingCharSet = RTL_TEXTENCODING_MS_1252, + CharSet i_nFileCharSet = RTL_TEXTENCODING_MS_1252 ); + + // OPERATIONS + USHORT Transform( /// @return The number of errors during transforming. + ByteString & io_sText); + + // INQUIRY + USHORT NrOfErrors() const; + E_Error GetError( + USHORT i_nNr, /// [0 .. NrOfErrors()-1], other values return an empty error. + ByteString * o_pErrorText = 0) const; /// If o_pErrorText != 0, the String is filled with the description of the error. + + private: + // SERVICE FUNCTION + void CreateError(); + + // DATA + WordTransTree * dpTransformer; + WordTrans_ErrorList * + dpErrors; +}; + + + +#endif + + +*/ diff --git a/transex3/inc/wtranode.hxx b/transex3/inc/wtranode.hxx new file mode 100644 index 000000000000..4d71fc160fff --- /dev/null +++ b/transex3/inc/wtranode.hxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wtranode.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef TX3_WTRANODE_HXX +#define TX3_WTRANODE_HXX + +// USED + // Base Classes + // Components + // Parameters +#include <tools/string.hxx> + + +typedef UINT8 BRANCH_T; + + + +const BRANCH_T C_BR_ALPHABASE = 4; +const BRANCH_T C_NR_OF_BRANCHES = 34; + + + + +/** @task + This is a node of the parsing-tree which implements the fuctionality of + class WordTransTree. + WordTransTree is dependant of this class, but NOT the other way! +**/ +class WTT_Node // WordTransTree-Node +{ + public: + enum E_TokenType + { +// no_token = 0, + token_to_keep, + token_to_replace + }; + + // LIFECYCLE + WTT_Node( + UINT8 i_nValue, // Own branch-value. + WTT_Node * i_pDefaultBranch, + WTT_Node * i_pDefaultBranchForAlphas ); + void SetBranch( + UINT8 i_cBranch, + WTT_Node * i_pNode ); + void SetAsTokenToReplace( + const ByteString & i_sReplaceString ); + ~WTT_Node(); + + // OPERATIONS + WTT_Node * GetNextNode( + UINT8 i_cBranch ); /// [0 .. C_NR_OF_BRANCHES-1], sonst GPF !!! + + // INQUIRY + E_TokenType TokenType() const; + UINT8 Value() const; + BOOL IsOnDeleting() const; + const ByteString & ReplaceString() const; + + private: + // DATA + UINT8 nValue; + E_TokenType eType; + ByteString sReplaceString; + WTT_Node * aBranches[C_NR_OF_BRANCHES]; // Mostly DYN pointers. + char bIsOnDeleting; +}; + + +inline WTT_Node * +WTT_Node::GetNextNode(UINT8 i_cBranch) + { return aBranches[i_cBranch]; } +inline WTT_Node::E_TokenType +WTT_Node::TokenType() const + { return eType; } +inline UINT8 +WTT_Node::Value() const + { return nValue; } +inline BOOL +WTT_Node::IsOnDeleting() const + { return bIsOnDeleting; } +inline const ByteString & +WTT_Node::ReplaceString() const + { return sReplaceString; } + + + + +#endif + + + diff --git a/transex3/inc/wtratree.hxx b/transex3/inc/wtratree.hxx new file mode 100644 index 000000000000..67d63280449f --- /dev/null +++ b/transex3/inc/wtratree.hxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wtratree.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef TX3_WTRATREE_HXX +#define TX3_WTRATREE_HXX + +// USED + // Base Classes + // Components + // Parameters +#include <tools/string.hxx> + +const INT16 C_NR_OF_WTT_RESULTS = 5; +const INT16 C_NR_OF_POSSIBLE_CHARS = 256; + + +typedef unsigned char u_char; +typedef const char * constr; + + +class WTT_Node; + + +/** @task + This class implements the functionality, that class WordTransformer + offers. + WordTransformer is dependant of this class, but NOT the other way! +**/ +class WordTransTree +{ + public: + enum E_Result + { + OK = 0, + HOTKEY_LOST, + OUTPUT_OVERFLOW + }; + + + // LIFECYCLE + WordTransTree( + CharSet i_nWorkingCharSet = RTL_TEXTENCODING_MS_1252); + void SetCharSet( + CharSet i_nWorkingCharSet); + ~WordTransTree(); + + void AddWordPair( + const ByteString & i_sOldString, + const ByteString & i_sReplaceString ); + + // OPERATIONS + void InitTransformation( + const char * i_sInput, /// [!=0], a range of i_nInputLength must be valid memory for read. + UINT32 i_nInputLength, + UINT32 i_nOutputMaxLength = STRING_MAXLEN - 12 ); + E_Result TransformNextToken(); + + // INQUIRY + BOOL TextEndReached() const; + const char * Output() const; + + // These 3 functions are valid between two calls of + // TransformNextToken(): + E_Result CurResult() const; + ByteString CurReplacedString() const; + ByteString CurReplacingString() const; + char CurHotkey() const; + + private: + // SERVICE FUNCTONS + UINT8 CalculateBranch( + u_char i_cInputChar ) const; + + void Handle_Hotkey(); + void Handle_TokenToKeep(); + void Handle_TokenToTransform(); + + // DATA + // Fixed data + const u_char * sInput; + UINT32 nInputLength; + const u_char * pInputEnd; + + u_char * sOutput; // DYN + UINT32 nOutputMaxLength; + + WTT_Node * dpParsingTreeTop; // DYN + WTT_Node * pUnknownAlpha; + u_char cChar2Branch[C_NR_OF_POSSIBLE_CHARS]; + u_char c_AE, c_OE, c_UE, c_ae, c_oe, c_ue; + + // Working data + const u_char * pInputCurTokenStart; + const u_char * pInputPosition; + u_char * pOutputPosition; + WTT_Node * pCurParseNode; + + // Data which are valid only after a completed call to TransformNextToken() + E_Result eCurResult; + u_char cCurHotkey; // Letter wich is used as hotkey + u_char cCurHotkeySign; // Letter which is used to assign hotkey ('~'or '&') . +}; + + + + + + + +inline BOOL +WordTransTree::TextEndReached() const + { return pInputPosition == pInputEnd; } +inline const char * +WordTransTree::Output() const + { return TextEndReached() ? (constr) sOutput : ""; } +inline WordTransTree::E_Result +WordTransTree::CurResult() const + { return eCurResult; } +inline ByteString +WordTransTree::CurReplacedString() const + { return ByteString((constr) pInputCurTokenStart,pInputPosition-pInputCurTokenStart); } +inline char +WordTransTree::CurHotkey() const + { return cCurHotkey; } +inline UINT8 +WordTransTree::CalculateBranch(u_char i_cInputChar) const + { return cChar2Branch[i_cInputChar]; } + + + +#endif + + + diff --git a/transex3/inc/xmlparse.hxx b/transex3/inc/xmlparse.hxx new file mode 100644 index 000000000000..a497355d6201 --- /dev/null +++ b/transex3/inc/xmlparse.hxx @@ -0,0 +1,557 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xmlparse.hxx,v $ + * $Revision: 1.15 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef BOOTSTRP_XMLPARSE_HXX +#define BOOTSTRP_XMLPARSE_HXX + +#include <signal.h> +#ifdef SYSTEM_EXPAT +#include <expat.h> +#else +#include <external/expat/xmlparse.h> +#endif +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include "tools/string.hxx" +#include "tools/list.hxx" +#define ENABLE_BYTESTRING_STREAM_OPERATORS +#include "tools/stream.hxx" +#include "tools/isofallback.hxx" +#include "export.hxx" +#include "xmlutil.hxx" + +#include <fstream> +#include <iostream> + +class XMLParentNode; +class XMLElement; + + +using namespace ::rtl; +using namespace std; + +#include <hash_map> /* std::hashmap*/ +#include <deque> /* std::deque*/ +#include <iterator> /* std::iterator*/ +#include <list> /* std::list*/ +#include <vector> /* std::vector*/ +#define XML_NODE_TYPE_FILE 0x001 +#define XML_NODE_TYPE_ELEMENT 0x002 +#define XML_NODE_TYPE_DATA 0x003 +#define XML_NODE_TYPE_COMMENT 0x004 +#define XML_NODE_TYPE_DEFAULT 0x005 +#define MAX_LANGUAGES 99 + + +//#define TESTDRIVER /* use xml2gsi testclass */ +//------------------------------------------------------------------------- + +/** Holds data of Attributes + */ +class XMLAttribute : public String +{ +private: + String sValue; + +public: + /// creates an attribute + XMLAttribute( + const String &rName, // attributes name + const String &rValue // attributes data + ) + : String( rName ), sValue( rValue ) {} + + /// getting value of an attribue + const String &GetValue() { return sValue; } + + void setValue(const String &rValue){sValue=rValue;} + + /// returns true if two attributes are equal and have the same value + BOOL IsEqual( + const XMLAttribute &rAttribute // the attribute which has to be equal + ) + { + return (( rAttribute == *this ) && ( rAttribute.sValue == sValue )); + } +}; + +DECLARE_LIST( XMLAttributeList, XMLAttribute * ) + +//------------------------------------------------------------------------- + +/** Virtual base to handle different kinds of XML nodes + */ +class XMLNode +{ +protected: + XMLNode() {} + +public: + virtual USHORT GetNodeType() = 0; + virtual ~XMLNode() {} +}; + +//------------------------------------------------------------------------- + +/** Virtual base to handle different kinds of child nodes + */ +class XMLChildNode : public XMLNode +{ +private: + XMLParentNode *pParent; + +protected: + XMLChildNode( XMLParentNode *pPar ); + XMLChildNode():pParent( NULL ){}; + XMLChildNode( const XMLChildNode& obj); + XMLChildNode& operator=(const XMLChildNode& obj); +public: + virtual USHORT GetNodeType() = 0; + + /// returns the parent of this node + XMLParentNode *GetParent() { return pParent; } + virtual ~XMLChildNode(){}; +}; + +DECLARE_LIST( XMLChildNodeList, XMLChildNode * ) + +//------------------------------------------------------------------------- + +/** Virtual base to handle different kinds of parent nodes + */ +class XMLData; + +class XMLParentNode : public XMLChildNode +{ +private: + XMLChildNodeList *pChildList; + static int dbgcnt; + //int nParentPos; +protected: + XMLParentNode( XMLParentNode *pPar ) + : XMLChildNode( pPar ), pChildList( NULL ) + { + } + XMLParentNode(): pChildList(NULL){ + } + /// Copyconstructor + XMLParentNode( const XMLParentNode& ); + + XMLParentNode& operator=(const XMLParentNode& obj); + virtual ~XMLParentNode(); + + +public: + virtual USHORT GetNodeType() = 0; + + /// returns child list of this node + XMLChildNodeList *GetChildList() { return pChildList; } + + /// adds a new child + void AddChild( + XMLChildNode *pChild /// the new child + ); + + void AddChild( + XMLChildNode *pChild , int pos /// the new child + ); + + virtual int GetPosition( ByteString id ); + int RemoveChild( XMLElement *pRefElement ); + void RemoveAndDeleteAllChilds(); + + /// returns a child element which matches the given one + XMLElement *GetChildElement( + XMLElement *pRefElement // the reference elelement + ); +}; + +//------------------------------------------------------------------------- + +DECLARE_LIST( XMLStringList, XMLElement* ) + +/// Mapping numeric Language code <-> XML Element +typedef std::hash_map< ByteString ,XMLElement* , hashByteString,equalByteString > LangHashMap; + +/// Mapping XML Element string identifier <-> Language Map +typedef std::hash_map<ByteString , LangHashMap* , + hashByteString,equalByteString> XMLHashMap; + +/// Mapping iso alpha string code <-> iso numeric code +typedef std::hash_map<ByteString, int, hashByteString,equalByteString> HashMap; + +/// Mapping XML tag names <-> have localizable strings +typedef std::hash_map<ByteString , BOOL , + hashByteString,equalByteString> TagMap; + +/** Holds information of a XML file, is root node of tree + */ + + +class XMLFile : public XMLParentNode +{ +public: + XMLFile() ; + XMLFile( + const String &rFileName // the file name, empty if created from memory stream + ); + XMLFile( const XMLFile& obj ) ; + ~XMLFile(); + + ByteString* GetGroupID(std::deque<ByteString> &groupid); + void Print( XMLNode *pCur = NULL, USHORT nLevel = 0 ); + virtual void SearchL10NElements( XMLParentNode *pCur, int pos = 0 ); + void Extract( XMLFile *pCur = NULL ); + void View(); +// void static Signal_handler(int signo);//void*,oslSignalInfo * pInfo); + void showType(XMLParentNode* node); + + XMLHashMap* GetStrings(){return XMLStrings;} + BOOL Write( ByteString &rFilename ); + BOOL Write( ofstream &rStream , XMLNode *pCur = NULL ); + + bool CheckExportStatus( XMLParentNode *pCur = NULL );// , int pos = 0 ); + + XMLFile& operator=(const XMLFile& obj); + + virtual USHORT GetNodeType(); + + /// returns file name + const String &GetName() { return sFileName; } + void SetName( const String &rFilename ) { sFileName = rFilename; } + void SetFullName( const String &rFullFilename ) { sFullName = rFullFilename; } + const std::vector<ByteString> getOrder(){ return order; } + +protected: + // writes a string as UTF8 with dos line ends to a given stream + void WriteString( ofstream &rStream, const String &sString ); + + // quotes the given text for writing to a file + void QuotHTML( String &rString ); + + void InsertL10NElement( XMLElement* pElement); + + // DATA + String sFileName; + String sFullName; + + const ByteString ID,OLDREF,XML_LANG; + + TagMap nodes_localize; + XMLHashMap* XMLStrings; + + std::vector <ByteString> order; +}; + +/// An Utility class for XML +/// See RFC 3066 / #i8252# for ISO codes +class XMLUtil{ + +public: + /// Quot the XML characters and replace \n \t + static void QuotHTML( String &rString ); + + /// UnQuot the XML characters and restore \n \t + static void UnQuotHTML ( String &rString ); + + /// Return the numeric iso language code + //USHORT GetLangByIsoLang( const ByteString &rIsoLang ); + + /// Return the alpha strings representation + ByteString GetIsoLangByIndex( USHORT nIndex ); + + static XMLUtil& Instance(); + ~XMLUtil(); + + void dump(); + +private: + /// Mapping iso alpha string code <-> iso numeric code + HashMap lMap; + + /// Mapping iso numeric code <-> iso alpha string code + ByteString isoArray[MAX_LANGUAGES]; + + static void UnQuotData( String &rString ); + static void UnQuotTags( String &rString ); + + XMLUtil(); + XMLUtil(const XMLUtil&); + +}; + + + +//------------------------------------------------------------------------- + +/** Hold information of an element node + */ +class XMLElement : public XMLParentNode +{ +private: + String sElementName; + XMLAttributeList *pAttributes; + ByteString project, + filename, + id, + sOldRef, + resourceType, + languageId; + int nPos; + +protected: + void Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement); +public: + /// create a element node + XMLElement(){} + XMLElement( + const String &rName, // the element name + XMLParentNode *Parent // parent node of this element + ): XMLParentNode( Parent ), + sElementName( rName ), + pAttributes( NULL ), + project(""), + filename(""), + id(""), + sOldRef(""), + resourceType(""), + languageId(""), + nPos(0) + { + } + ~XMLElement(); + XMLElement(const XMLElement&); + + XMLElement& operator=(const XMLElement& obj); + /// returns node type XML_NODE_ELEMENT + virtual USHORT GetNodeType(); + + /// returns element name + const String &GetName() { return sElementName; } + + /// returns list of attributes of this element + XMLAttributeList *GetAttributeList() { return pAttributes; } + + /// adds a new attribute to this element, typically used by parser + void AddAttribute( const String &rAttribute, const String &rValue ); + + void ChangeLanguageTag( const String &rValue ); + // Return a ASCII String representation of this object + OString ToOString(); + + // Return a Unicode String representation of this object + OUString ToOUString(); + + bool Equals(OUString refStr); + + /// returns a attribute + XMLAttribute *GetAttribute( + const String &rName // the attribute name + ); + void SetProject ( ByteString prj ){ project = prj; } + void SetFileName ( ByteString fn ){ filename = fn; } + void SetId ( ByteString theId ){ id = theId; } + void SetResourceType ( ByteString rt ){ resourceType = rt; } + void SetLanguageId ( ByteString lid ){ languageId = lid; } + void SetPos ( int nPos_in ){ nPos = nPos_in; } + void SetOldRef ( ByteString sOldRef_in ){ sOldRef = sOldRef_in; } + + virtual int GetPos() { return nPos; } + ByteString GetProject() { return project; } + ByteString GetFileName() { return filename; } + ByteString GetId() { return id; } + ByteString GetOldref() { return sOldRef; } + ByteString GetResourceType(){ return resourceType; } + ByteString GetLanguageId() { return languageId; } + + +}; +//------------------------------------------------------------------------- + + +/** Holds character data + */ +class XMLData : public XMLChildNode +{ +private: + String sData; + bool isNewCreated; + +public: + /// create a data node + XMLData( + const String &rData, // the initial data + XMLParentNode *Parent // the parent node of this data, typically a element node + ) + : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){} + XMLData( + const String &rData, // the initial data + XMLParentNode *Parent, // the parent node of this data, typically a element node + bool newCreated + ) + : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( newCreated ){} + + XMLData(const XMLData& obj); + + XMLData& operator=(const XMLData& obj); + virtual USHORT GetNodeType(); + + /// returns the data + const String &GetData() { return sData; } + + bool isNew() { return isNewCreated; } + /// adds new character data to the existing one + void AddData( + const String &rData // the new data + ); + + + +}; + +//------------------------------------------------------------------------- + +/** Holds comments + */ +class XMLComment : public XMLChildNode +{ +private: + String sComment; + +public: + /// create a comment node + XMLComment( + const String &rComment, // the comment + XMLParentNode *Parent // the parent node of this comemnt, typically a element node + ) + : XMLChildNode( Parent ), sComment( rComment ) {} + + virtual USHORT GetNodeType(); + + XMLComment( const XMLComment& obj ); + + XMLComment& operator=(const XMLComment& obj); + + /// returns the comment + const String &GetComment() { return sComment; } +}; + +//------------------------------------------------------------------------- + +/** Holds additional file content like those for which no handler exists + */ +class XMLDefault : public XMLChildNode +{ +private: + String sDefault; + +public: + /// create a comment node + XMLDefault( + const String &rDefault, // the comment + XMLParentNode *Parent // the parent node of this comemnt, typically a element node + ) + : XMLChildNode( Parent ), sDefault( rDefault ) {} + + XMLDefault(const XMLDefault& obj); + + XMLDefault& operator=(const XMLDefault& obj); + + /// returns node type XML_NODE_TYPE_COMMENT + virtual USHORT GetNodeType(); + + /// returns the comment + const String &GetDefault() { return sDefault; } +}; + +//------------------------------------------------------------------------- + +/** struct for error information, used by class SimpleXMLParser + */ +struct XMLError { + XML_Error eCode; // the error code + ULONG nLine; // error line number + ULONG nColumn; // error column number + String sMessage; // readable error message +}; + +//------------------------------------------------------------------------- + +/** validating xml parser, creates a document tree with xml nodes + */ + + +class SimpleXMLParser +{ +private: + XML_Parser aParser; + XMLError aErrorInformation; + + XMLFile *pXMLFile; + XMLParentNode *pCurNode; + XMLData *pCurData; + + + static void StartElementHandler( void *userData, const XML_Char *name, const XML_Char **atts ); + static void EndElementHandler( void *userData, const XML_Char *name ); + static void CharacterDataHandler( void *userData, const XML_Char *s, int len ); + static void CommentHandler( void *userData, const XML_Char *data ); + static void DefaultHandler( void *userData, const XML_Char *s, int len ); + + + void StartElement( const XML_Char *name, const XML_Char **atts ); + void EndElement( const XML_Char *name ); + void CharacterData( const XML_Char *s, int len ); + void Comment( const XML_Char *data ); + void Default( const XML_Char *s, int len ); + + +public: + /// creates a new parser + SimpleXMLParser(); + ~SimpleXMLParser(); + + /// parse a file, returns NULL on criticall errors + XMLFile *Execute( + const String &rFullFileName, + const String &rFileName, // the file name + XMLFile *pXMLFileIn // the XMLFile + ); + + /// parse a memory stream, returns NULL on criticall errors + XMLFile *Execute( + SvMemoryStream *pStream // the stream + ); + + /// returns an error struct + const XMLError &GetError() { return aErrorInformation; } +}; + +#endif diff --git a/transex3/inc/xmlutil.hxx b/transex3/inc/xmlutil.hxx new file mode 100644 index 000000000000..812f50b85c45 --- /dev/null +++ b/transex3/inc/xmlutil.hxx @@ -0,0 +1,9 @@ +#define ENGLISH_US 1 +#define ENGLISH_US_ISO "en-US" +#define ENGLISH_US_PROPERTY "en_US" +#define ENGLISH_US_INDEX 1 +#define GERMAN_DE 4 +#define GERMAN_DE_ISO "x-german" +#define GERMAN_DE_INDEX 3 +#define GERMAN_ISO2 "de-DE" + diff --git a/transex3/inc/xrmmerge.hxx b/transex3/inc/xrmmerge.hxx new file mode 100644 index 000000000000..47be1ea7a038 --- /dev/null +++ b/transex3/inc/xrmmerge.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xrmmerge.hxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// global includes +#include <tools/string.hxx> + +// +// XRMResParser +// + +class XRMResParser +{ +private: + ByteString sGID; + ByteString sLID; + + BOOL bError; + BOOL bText; + + bool sLocalized; + + ByteString sCurrentOpenTag; + ByteString sCurrentCloseTag; + ByteString sCurrentText; + std::vector<ByteString> aLanguages; + +protected: + ByteString GetAttribute( const ByteString &rToken, const ByteString &rAttribute ); + void Error( const ByteString &rError ); + + virtual void Output( const ByteString& rOutput )=0; + virtual void WorkOnText( + const ByteString &rOpenTag, + ByteString &rText + )=0; + virtual void EndOfText( + const ByteString &rOpenTag, + const ByteString &rCloseTag + )=0; + + ByteString GetGID() { return sGID; } + ByteString GetLID() { return sLID; } + + void ConvertStringToDBFormat( ByteString &rString ); + void ConvertStringToXMLFormat( ByteString &rString ); + +public: + XRMResParser(); + virtual ~XRMResParser(); + + int Execute( int nToken, char * pToken ); + + void SetError( BOOL bErr = TRUE ) { bError = bErr; } + BOOL GetError() { return bError; } +}; + +// +// class XRMResOutputParser +// + +class XRMResOutputParser : public XRMResParser +{ +private: + std::vector<ByteString> aLanguages; +protected: + SvFileStream *pOutputStream; +public: + XRMResOutputParser ( const ByteString &rOutputFile ); + virtual ~XRMResOutputParser(); +}; + +// +// XRMResExport +// + +class XRMResExport : public XRMResOutputParser +{ +private: + ResData *pResData; + ByteString sPrj; + ByteString sPath; + std::vector<ByteString> aLanguages; + +protected: + void WorkOnText( + const ByteString &rOpenTag, + ByteString &rText + ); + void EndOfText( + const ByteString &rOpenTag, + const ByteString &rCloseTag + ); + void Output( const ByteString& rOutput ); + +public: + XRMResExport( + const ByteString &rOutputFile, + const ByteString &rProject, + const ByteString &rFilePath + ); + virtual ~XRMResExport(); +}; + +// +// class XRMResMerge +// + +class XRMResMerge : public XRMResOutputParser +{ +private: + MergeDataFile *pMergeDataFile; + ByteString sFilename; + ResData *pResData; + std::vector<ByteString> aLanguages; + +protected: + void WorkOnText( + const ByteString &rOpenTag, + ByteString &rText + ); + void EndOfText( + const ByteString &rOpenTag, + const ByteString &rCloseTag + ); + void Output( const ByteString& rOutput ); +public: + XRMResMerge( + const ByteString &rMergeSource, + const ByteString &rOutputFile, + ByteString &rFilename + ); + virtual ~XRMResMerge(); +}; + diff --git a/transex3/java/l10nconv/build.xml b/transex3/java/l10nconv/build.xml new file mode 100755 index 000000000000..6902227e5122 --- /dev/null +++ b/transex3/java/l10nconv/build.xml @@ -0,0 +1,233 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.4 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="l10nconv" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="l10nconv"/> + + <!-- name of jar file created, without .jar extension --> + <property name="jarname" value="converter"/> + + <!-- relative path to project directory --> + <property name="prj" value="."/> + + <!-- build output directory --> + <property name="out" value="build"/> + + <!-- build directories --> + <property name="build.dir" value="${out}"/> + <property name="build.class" value="${build.dir}/class/converter"/> + <property name="build.misc" value="${build.dir}/misc/converter"/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="java"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for compile and javadoc tasks --> + <path id="classpath"> + <pathelement location="."/> + <pathelement location="${build.class}"/> + </path> + + <!-- name to display in documentation --> + <property name="docname" value="l10n converter"/> + + <!-- set "modern" java compiler --> + <property name="build.compiler" value="modern"/> + + <!-- set wether we want to compile with debug information --> + <property name="debug" value="on"/> + + <!-- set wether we want to compile with optimisation --> + <property name="optimize" value="off"/> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile,jar,javadoc,zipdoc"/> + + <!-- prepare output directories --> + <target name="prepare"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.dir}/doc"/> + <mkdir dir="${build.dir}/doc/javadoc"/> + <mkdir dir="${build.class}"/> + <mkdir dir="${build.misc}"/> + </target> + + + <target name="res" depends="prepare"> + <copy todir="${build.class}"> + <fileset dir="${java.dir}"> + <include name="**/*.properties"/> + <include name="**/*.css"/> + <include name="**/*.dtd"/> + <include name="**/*.form"/> + <include name="**/*.gif "/> + <include name="**/*.htm"/> + <include name="**/*.html"/> + <include name="**/*.js"/> + <include name="**/*.mod"/> + <include name="**/*.sql"/> + <include name="**/*.xml"/> + <include name="**/*.xsl"/> + <include name="**/*.map"/> + + </fileset> + </copy> + </target> + + + <target name="compile" depends="prepare,res"> + <javac destdir="${build.class}" + debug="${debug}" + deprecation="${deprication}" + optimize="${optimize}" + classpathref="classpath"> + <src path="${java.dir}"/> + <include name="**/*.java"/> + </javac> + </target> + + <!-- check if javadoc is up to date --> + <target name="javadoc_check" depends="prepare" if="build.dir"> + <uptodate property="javadocBuild.notRequired" value="true" + targetfile="${build.dir}/doc/converter_javadoc.zip"> + <srcfiles dir="${java.dir}" includes="**/*.java"/> + </uptodate> + </target> + + <!-- generate java documentation --> + <target name="javadoc" depends="prepare,javadoc_check,compile" + unless="javadocBuild.notRequired" + if="build.dir"> + + <javadoc destdir="${build.dir}/doc/javadoc" + verbose="false" + author="false" + nodeprecated="true" + nodeprecatedlist="true" + use="true" + Doctitle="${docname}" + windowtitle="${docname}" + classpathref="classpath"> + + <packageset dir="${java.dir}" defaultexcludes="yes"> + <include name="com/**"/> + </packageset> + + <link offline="true" href="http://java.sun.com/j2se/1.4.2/docs/api" + packagelistLoc="${common.doc}/jdk1.4.2"/> + <link offline="true" + href="http://java.sun.com/products/servlet/2.3/javadoc" + packagelistLoc="${common.doc}/servlet2.3"/> + <link offline="true" + href="http://logging.apache.org/log4j/docs/api" + packagelistLoc="${common.doc}/log4j-1.2.8"/> + <link offline="true" + href="http://java.sun.com/products/javabeans/glasgow/javadocs" + packagelistLoc="${common.doc}/jaf-1.0.2"/> + <link offline="true" + href="http://java.sun.com/products/javamail/javadocs" + packagelistLoc="${common.doc}/javamail-1.3.1"/> + <link offline="true" + href="http://ws.apache.org/soap/docs" + packagelistLoc="${common.doc}/soap-2.3.1"/> + + <bottom><i>Copyright &#169; 2004 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, CA 94303 USA</i></bottom> + <header>${docname}</header> + + </javadoc> + </target> + + <!-- zip documentation and store in build/misc --> + <target name="zipdoc" depends="javadoc" if="build.dir" unless="javadocBuild.notRequired"> + <zip zipfile="${build.dir}/doc/converter_javadoc.zip" + basedir="${build.dir}/doc/javadoc" + update="true"/> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/**/*.class"/> + </patternset> + </fileset> + </delete> + </target> + + <!-- create jar file --> + <target name="jar" depends="prepare,compile" if="build.class"> + <jar jarfile="${build.class}/${jarname}.jar" + basedir="${build.class}" + manifest="${jarname}.MF"> + <include name="**/*.class"/> + <include name="**/*.properties"/> + <include name="**/*.css"/> + <include name="**/*.dtd"/> + <include name="**/*.form"/> + <include name="**/*.gif "/> + <include name="**/*.htm"/> + <include name="**/*.html"/> + <include name="**/*.js"/> + <include name="**/*.mod"/> + <include name="**/*.sql"/> + <include name="**/*.xml"/> + <include name="**/*.xsl"/> + <include name="**/*.map"/> + </jar> + </target> + + <target name="test" depends="prepare"> + </target> + +</project> + diff --git a/transex3/java/l10nconv/converter.MF b/transex3/java/l10nconv/converter.MF new file mode 100755 index 000000000000..843d500b7548 --- /dev/null +++ b/transex3/java/l10nconv/converter.MF @@ -0,0 +1 @@ +Main-Class: com.sun.star.tooling.converter.Convert diff --git a/transex3/java/l10nconv/documentation/readmeConverter.sxw b/transex3/java/l10nconv/documentation/readmeConverter.sxw Binary files differnew file mode 100755 index 000000000000..f779e10acb2c --- /dev/null +++ b/transex3/java/l10nconv/documentation/readmeConverter.sxw diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/DirtyTagWrapCheck.java b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/DirtyTagWrapCheck.java new file mode 100755 index 000000000000..d304c2544bff --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/DirtyTagWrapCheck.java @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DirtyTagWrapCheck.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.DirtyTags; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + + + +public class DirtyTagWrapCheck { + static String line=""; + public static void main(String[] args) { + try { + File fi = new File("D:\\Testfiles\\KID_helpcontent.sdf");//Copy of + FileReader fr = new FileReader(fi); + BufferedReader br = new BufferedReader(fr); + + int readCounter=0; + int missCounter=0; + int lineErrorCounter=0; + while((line=br.readLine())!=null){ + readCounter++; + String [] split = line.split("\t"); + if(split.length<15){ + + lineErrorCounter++; + continue; + } + String string = split[10]; + String wrapped = DirtyTagWrapper.wrapString(string); + String unwrapped=DirtyTagWrapper.unwrapString(wrapped); + if(!string.equals(unwrapped)){ + + missCounter++; + System.out.println(""+readCounter+"\n"+string+"\n"+unwrapped+"\n"+wrapped+"\n"); + } + } + System.out.println("Fertig "+readCounter+" "+missCounter+" "+lineErrorCounter); + } catch (FileNotFoundException e) { + // + e.printStackTrace(); + } catch (IOException e) { + // + e.printStackTrace(); + } catch (DirtyTagWrapper.TagWrapperException e) { + System.out.println(e.getMessage()+"\n"+line+"\n"); + + } + + } +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/DirtyTagWrapper.java b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/DirtyTagWrapper.java new file mode 100755 index 000000000000..49fc08b69d32 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/DirtyTagWrapper.java @@ -0,0 +1,252 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DirtyTagWrapper.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.DirtyTags; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * Solves the problem with translating strings from the + * Star-Office Help. This Strings contain XML snippets + * (that means parts of an xml dokument). I call them 'dirty' + * because the start of a tag (<) and the and of an tag (>) + * are quoted by a single backslash(\<.....\>). This is done + * because the text out of th tags should not contain '<' and '>' + * as Entity references (< or >) but as readable signs. + * This is for translation purposes. + * Because translators get mad while find out the really translatable + * parts between all the markup information, the XLIFF Specification + * allows to wrap parts of a String that should not be translated by + * special tags (<ept>, <bpt>). + * This Class has two static methods that do the wrapping and unwrapping + * NOTE: this won't work with not 'dirty' Strings. + * + * @author Christian Schmidt 2005 + * + */ +public class DirtyTagWrapper { + + private static boolean doWrap=true; + public static void setWrapping(boolean doWrap){ + DirtyTagWrapper.doWrap=doWrap; + } + + /** + * Unwraps the 'dirty' parts of a String from ept and bpt tags + * + * @param checkString The String to unwrap + * @return the unwrapped String + */ + public static String unwrapString(String checkString){ + //remove the ept and bpt tags + String[] splitted =checkString.split("(<ept ([^<>])*>)|(</ept>)|(<bpt ([^<>])*>)|(</bpt>)|(<sub([^<>])*>)|(</sub>)|(<ex ([^<>])*/>)"); + StringBuffer workBuffer= new StringBuffer(); + for(int i=0;i<splitted.length;i++){ + workBuffer.append(splitted[i]); + } + String string = new String(workBuffer); + //replace Entity references + string=string.replaceAll( "&","&").replaceAll( "<","<").replaceAll( ">",">").replaceAll( ""","\"").replaceAll( "'","'"); + + //remove the nsub tags + splitted =string.split("(<sub([^<>])*>)|(</sub>)"); + StringBuffer returnBuffer= new StringBuffer(); + for(int i=0;i<splitted.length;i++){ + returnBuffer.append(splitted[i]); + } + String returnString = new String(returnBuffer); + return returnString; + } + + + /** + * Wrap the dirty parts of a string + * + * @param checkString The String to check if there are dirty Parts to wrap + * @return A String with wrapped dirty parts + * @throws TagWrapperException + * @throws IOException + */ + public static String wrapString(String checkString) throws TagWrapperException, IOException { + // if no wrapping should be done return the given string + if(!doWrap) return checkString; + // let's wrap + String[] parts=null; + int idx=0; + //split the string at tag ends + String[] parts2 = checkString.split("\\\\>"); + + ArrayList tagString =new ArrayList(); + // put the while splitting lost parts to the end of the single strings + for(int j=0;j<parts2.length-1;j++){ + parts2[j]+="\\>"; + } + // same for the last string + if (checkString.endsWith("\\>")){ + parts2[parts2.length-1]+="\\>"; + } + // split the leading text from the real tag string (<...>) + for(int j=0;j<parts2.length;j++){ + + //is it just a tag + if(parts2[j].startsWith("\\<")){ + tagString.add(parts2[j]); + // or is it a tag with leading text? + }else if((idx=parts2[j].indexOf("\\<"))>0&&parts2[j].indexOf("\\>")>0){ + //...then split it in two parts + // the leading text + tagString.add(parts2[j].substring(0,(parts2[j].indexOf("\\<")))); + // ...and the tag + tagString.add(parts2[j].substring(parts2[j].indexOf("\\<"))); + + }else{ + //no tag...must be text only + tagString.add(parts2[j]); + } + + } + ArrayList tagNames=new ArrayList(); + String item=""; + for(int i=0;i<tagString.size();i++){ + item=((String)tagString.get(i)); + int start=item.indexOf("\\<")+2; + // check if we have an index that is ok + if(start==1) start=-1; + int end=item.lastIndexOf("\\>"); + if(start>=0&&end>0){ + boolean isStandalone=false; + if(item.endsWith("/\\>")){ + // this is a standalone tag + isStandalone=true; + } + item=item.substring(start,end); + + if(item.indexOf(" ")>0){ + item=item.substring(0,item.indexOf(" ")); + } + if(isStandalone){ + item=item+"/"; + } + tagNames.add(item); + }else{ + tagNames.add(""); + } + } + ArrayList tagType=new ArrayList(); + for(int i=0;i<tagNames.size();i++){ + if(((String)tagNames.get(i)).equals("")){ + tagType.add("Text"); + }else if(((String)tagNames.get(i)).startsWith("/")){ + tagType.add("EndTag"); + }else if(((String)tagNames.get(i)).endsWith("/")){ + tagType.add("StartAndEndTag"); + }else { + tagType.add("StartTag"); + } + + } + + ArrayList tagList=new ArrayList(); + for(int i=0;i<tagNames.size();i++){ + tagList.add(new Tag( + (String)tagType.get(i), + (String)tagNames.get(i), + (String)tagString.get(i))); + } + tagType=null; + tagNames=null; + tagString=null; + + TagPair start; + StringBuffer returnBuffer=new StringBuffer(); + while(tagList.size()>0){ + try{ + start=new TagPair(tagList); + returnBuffer.append(start.getWrapped()); + }catch(TagPair.TagPairConstructionException e){ + throw (new DirtyTagWrapper()).new TagWrapperException(e); + } + } + TagPair.resetCounter(); + return new String(returnBuffer); + } + /** + * @author Christian Schmidt 2005 + * + */ + public class TagWrapperException extends Exception { + + /** + * Create a new Instance of TagWrapperException + * + * + */ + public TagWrapperException() { + super(); + // + } + + /** + * Create a new Instance of TagWrapperException + * + * @param arg0 + */ + public TagWrapperException(String arg0) { + super(arg0); + // + } + + /** + * Create a new Instance of TagWrapperException + * + * @param arg0 + * @param arg1 + */ + public TagWrapperException(String arg0, Throwable arg1) { + super(arg0, arg1); + // + } + + /** + * Create a new Instance of TagWrapperException + * + * @param arg0 + */ + public TagWrapperException(Throwable arg0) { + super(arg0); + // + } + + } +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/Tag.java b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/Tag.java new file mode 100755 index 000000000000..7495736ab68c --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/Tag.java @@ -0,0 +1,249 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Tag.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.DirtyTags; + +import java.io.IOException; +import java.util.Map; + +import com.sun.star.tooling.converter.ExtMap; + +/** + * @author Christian Schmidt 2005 + * + */ +public class Tag { + private static int indent=0; + Map tagNames; + private String tagType; + private String tagName; + private String tagString; + public static Tag EMPTYTAG=new Tag("","",""); + + /** + * Create a new Instance of Tag + * + * @param tagType + * @param tagName + * @param tagString + */ + public Tag(String tagType, String tagName, String tagString) { + + this.tagType=tagType; + this.tagName=tagName; + this.tagString=tagString; + + tagNames=new ExtMap(); + tagNames.put("link","name"); + tagNames.put("caption","xml-lang"); + tagNames.put("alt","xml-lang"); + } + + public String getWrappedTagString() throws IOException{ + if(this.canHaveTranslateableContent()){ + return this.wrapTagStringIntern(); + }else{ + return xmlString(this.tagString); + } + } + + private final String xmlString( final String string) throws java.io.IOException { + if (string == null) + return string; // "" + String str = string; + + for(int i=0;i<str.length();i++){ + if(str.charAt(i)=='&'){ + str=str.substring(0, i)+"&"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='<'){ + str=str.substring(0, i)+"<"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='>'){ + str=str.substring(0, i)+">"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='"'){ + str=str.substring(0, i)+"""+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='\''){ + str=str.substring(0, i)+"'"+str.substring(i+1); + continue; + } + } + + return str; + } + /** + * @return + */ + private boolean canHaveTranslateableContent() { + return (tagNames.containsKey(this.tagName)); + + } + + /** + * @throws IOException + * + */ + private String wrapTagStringIntern() throws IOException { + + + String[] split=this.tagString.split("="); + int length=split.length; + // no attribute found; + if (length==0) return xmlString(tagString); + else{ + int i=0; + + while(i<length-1/*the last part can only contain an attribute value*/){ + String attributeName = split[i].trim(); + if(split[i]. indexOf("</sub>")<0) split[i]=xmlString(split[i]); + i++; + String value; + attributeName=(attributeName.substring(attributeName.lastIndexOf(" ")).trim()); + if((value=translateableAttributeValue(this.tagName)).equals(attributeName)){ + int valueStart=0; + int valueEnd=0; + + // get the value to the found attribute name + // it must either be surrounded by '"'... + if((valueStart=split[i].indexOf('"'))>=0){ + valueEnd = split[i].lastIndexOf('"'); + //...or surrounded by "'" + }else if((valueStart=split[i].indexOf("'"))>=0){ + valueEnd = split[i].lastIndexOf("'"); + }else{ + // there seems to be an error, + // we found an '=' (we split there) but no '"' or ''' + // but although we don't check the syntax + // we just continue + continue; + } + //ok we found the border of a value that might be translated + //now we wrap it with the tags + + split[i]=xmlString(split[i].substring(0,valueStart+1))+"<sub>"+xmlString(split[i].substring(valueStart+1,valueEnd))+"</sub>"+xmlString(split[i].substring(valueEnd)); + + } + } + String wrappedString=""; + // we have the wrapped parts, now we put them together + int j=0; + for(j=0;j<split.length-1;j++){ + wrappedString+=(split[j]+"="); + } + wrappedString+=split[j]; +// System.out.println(this.tagString); +// System.out.println(wrappedString); + return wrappedString; + } + + } + + + + /** + * @param tagName the name of the tag to check + * @return the name of the attribute that can contain translateable value + */ + private String translateableAttributeValue(String tagName) { + + return (String)this.tagNames.get(tagName); + } + + + /** + * Create a new Instance of Tag + * + * + */ + public Tag(String tagString) { + this(extractTagType(extractTagName(tagString)),extractTagName(tagString),tagString); + } + + private static String extractTagName(String tagString){ + + int start=tagString.indexOf('<')+1; + int end=tagString.lastIndexOf('\\'); + if(start>=0&&end>0){ + tagString=tagString.substring(start,end); + + if(tagString.indexOf(" ")>0){ + tagString=tagString.substring(0,tagString.indexOf(" ")); + } + return tagString; + }else{ + return ""; + } + } + private static String extractTagType(String tagName){ + if(tagName.equals("")){ + return "Text"; + }else if(tagName.startsWith("/")){ + return "EndTag"; + }else if(tagName.endsWith("/")){ + return "StartAndEndTag"; + }else { + return "StartTag"; + } + } + + /** + * @return Returns the tagName. + */ + public String getTagName() { + return this.tagName; + } + /** + * @return Returns the tagString. + */ + public String getTagString() { + return this.tagString; + } + /** + * @return Returns the tagType. + */ + public String getTagType() { + return this.tagType; + } + + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/TagPair.java b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/TagPair.java new file mode 100755 index 000000000000..7993fc9cf0a4 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/DirtyTags/TagPair.java @@ -0,0 +1,310 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TagPair.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.DirtyTags; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + + +/** + * @author Christian Schmidt 2005 + * + */ +public class TagPair { + + + private Tag startTag=Tag.EMPTYTAG; + private Tag endTag=Tag.EMPTYTAG; + private String startingText=""; + private ArrayList enclosedTags=new ArrayList(); + private long id; + private static int ElementCounter=1; + private String endingText=""; + + /** + * @author Christian Schmidt 2005 + * + */ + public class TagPairConstructionException extends Exception { + + /** + * Create a new Instance of TagPairConstructionException + * + * @param string + */ + public TagPairConstructionException(String string) { + + } + + } + + /** + * Create a new Instance of TagPair + * + * + */ + public TagPair() { + + } + + + /** + * Create a new Instance of TagPair + * + * Find matching tags in tagList, create a TagPair of it, create + * tagPairs from the content in the tagPair and remove all used + * tags from tagList. The rest of the tagList starts after the + * endTag of this TagPair. + * + * @param tagList a List of the tags to check + * + * @throws TagPairConstructionException + */ + public TagPair(ArrayList tagList) throws TagPairConstructionException { + + if(tagList.size()==0){ + return; + } + ArrayList contentList=new ArrayList();; + Tag tag=(Tag)tagList.get(0); + tagList.remove(0); + + + if("Text".equals(tag.getTagType())){ + // is this Text the only content + // of this Tag ? + if(tagList.size()==0){ + //yes...then it is the starting Text of this TagPair + this.startingText=tag.getTagString(); + return; + }else{ + //no...the tag is normal content + contentList.add(tag); + } + this.startingText=tag.getTagString(); + + }else if("EndTag".equals(tag.getTagType())){ + //ERRor throw EXception + }else if("StartTag".equals(tag.getTagType())){ + // find the matching end tag + this.startTag=tag; + Iterator iter=tagList.iterator(); + + int equivalentTagCounter=0; + while(iter.hasNext()){ + //is this the end tag? + if((tag=(Tag)iter.next()).getTagName().equals('/'+this.startTag.getTagName())&&equivalentTagCounter==0){ + //found the corresponding end tag + + //this TagPair is complete + //so it needs an id + this.id=TagPair.ElementCounter++; + this.endTag=tag; + //...remove it from list + tagList.removeAll(contentList); + tagList.remove(tag); + break; + }else{ + // tag is not the end tag + // so it is between the start and the end tag + // and belongs to the content + // but first check if it has the same name as the current tag + if(tag.getTagName().equals(this.startTag.getTagName())){ + // if this is a start tag like the current start tag + // we count it to find out the matching end tag in nested tags + if(tag.getTagType().equals("StartTag")){ + equivalentTagCounter++; + } + } + if(tag.getTagName().equals("/"+this.startTag.getTagName())){ + if(tag.getTagType().equals("EndTag")){ + equivalentTagCounter--; + } + } + + contentList.add(tag); + } + } + //found the end tag ? + //no... + if (this.endTag.getTagType()==""){ + + throw new TagPairConstructionException("ERROR: Missing end tag ("+ + this.startTag.getTagString()+")."); + //...yes + }else{ + //We need to check whether the content is starting or ending with text + //...check starting with text + if(contentList.size()>=1&&((String)((Tag)contentList.get(0)).getTagType()).equals("Text")){ + //yes...store it as startingText + this.startingText=(String)((Tag)contentList.get(0)).getTagString(); + //remove it from list + contentList.remove(0); + } + // ...check ending with text + if(contentList.size()>=1&&((String)((Tag)contentList.get(contentList.size()-1)).getTagType()).equals("Text")){ + //yes...store it as endingText + this.endingText=(String)((Tag)contentList.get(contentList.size()-1)).getTagString(); + //remove it from list + contentList.remove(contentList.size()-1); + } + //create the list of tags enclosed by this tagPair + createEnclosedTags(contentList); + } + //if stand AloneTag create own TagObject...give ID...add to List + }else if("StartAndEndTag".equals(tag.getTagType())){ + this.startTag=tag; + this.endTag=new Tag("EndOfStandAlone","",""); + createEnclosedTags(contentList); + } + + } + + /** + * @param contentList + * @throws TagPairConstructionException + */ + private void createEnclosedTags(ArrayList contentList) throws TagPairConstructionException { + while(contentList.size()>0){ + //create the inner TagPairs + this.enclosedTags.add(new TagPair(contentList)); + } + + } + + public String toString(){ + StringBuffer outString= new StringBuffer(this.startTag.toString()); + TagPair help=new TagPair(); + Iterator iter=enclosedTags.iterator(); + outString.append(this.startingText); + while(iter.hasNext()){ + if((help=(TagPair)iter.next())==null){ + continue; + }else{ + outString.append(help.toString()); + } + } + outString.append(this.endingText); + outString.append(this.endTag.toString()); + return new String(outString); + } + + public String getWrapped() throws IOException{ + Iterator iter=enclosedTags.iterator(); + StringBuffer returnBuffer=new StringBuffer(); + + returnBuffer.append(wrap(this.startTag)+xmlString(this.startingText)); + while(iter.hasNext()){ + returnBuffer.append(((TagPair)iter.next()).getWrapped()); + } + returnBuffer.append(xmlString(this.endingText)+wrap(this.endTag)); + + + + return new String(returnBuffer); + } + + private String wrap(Tag tag) throws IOException{ + String string=""; + //can be a start tag + if(tag.getTagType().startsWith("Start")){ + return new String("<bpt id='"+this.id+"'>"+tag.getWrappedTagString()+"</bpt>"); + //...or a end tag + }else if (tag.getTagType().startsWith("End")){ + //maybe the end tag of a Start and end tag +// if("EndOfStandAlone".equals(tag.getTagType())){ +// return new String("<ex id='"+this.id+"'/>"); +// }else{ + string=tag.getWrappedTagString(); + return new String("<ept id='"+this.id+"'>"+string+"</ept>"); +// } + + //...or text + }else{ + return xmlString(tag.getTagString()); + } + } + /** + * Replaces all characters that mustn't be in XLIFF PCdata + * + * @param string the string to check + * @return the checked string with all characters replaced + * @throws java.io.IOException + */ + private final String xmlString( final String string) throws java.io.IOException { + if (string == null) + return string; // "" + String str = string; + + for(int i=0;i<str.length();i++){ + if(str.charAt(i)=='&'){ + str=str.substring(0, i)+"&"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='<'){ + str=str.substring(0, i)+"<"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='>'){ + str=str.substring(0, i)+">"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='"'){ + str=str.substring(0, i)+"""+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='\''){ + str=str.substring(0, i)+"'"+str.substring(i+1); + continue; + } + } + + return str; + } + + /** + * + */ + public static void resetCounter() { + TagPair.ElementCounter=1; + + } + + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Convert.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Convert.java new file mode 100755 index 000000000000..5b1fb6c62b61 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Convert.java @@ -0,0 +1,553 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Convert.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * the main Class + * + * Command Line arguments are reviewed + * and a Converter is constructed + */ +package com.sun.star.tooling.converter; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Calendar; + +import com.sun.star.tooling.DirtyTags.DirtyTagWrapper; + +/** + * The main class of the converter tool + * + * The converter tool is command line based. + * Its classes allow the converting between the + * file formats sdf, gsi and <a href="http://www.oasis-open.org/committees/xliff/documents/cs-xliff-core-1.1-20031031.htm">xliff</a>. + * + * Those file formats are used in localization + * of Star-Office and Open-Office. + * + * Information about the whole localization process can be found in + * <a href="http://ded-1.germany.sun.com/webcontent/guidelines/pdf/L10NSO8.pdf">http://ded-1.germany.sun.com/webcontent/guidelines/pdf/L10NSO8.pdf</a> + * + * @author Christian Schmidt 2005 + * + */ +public class Convert { + + private static Calendar cal; + + private static final String EMPTY = ""; + + /** + * The name of the file containing the debug information + * that where found while converting (every output goes here too) + */ + private static String dbgName = EMPTY; + + /** + * the character that separates the extension from the file name + */ + private static final char extensionSeperator = '.'; + + /** + * the log File + */ + private static File log; + + /** + * the name of the log file + */ + private static String logString = EMPTY; + + /** + * indicates whether existing sources should be overwritten + * without asking + */ + private static boolean overwrite = false; + + /** + * A second Source File needed for GSI Merging + */ + private static File secondSource; + + //private static final char pathSeperator = '\\'; + + /** + * The language that should be the source language + * that means the language to translate from + */ + private static String sourceLanguage = "en-US"; + + /** + * the name of the source file + */ + private static String sourceName = EMPTY; + + /** + * the type of the source file (sdf,xliff,...) + */ + private static String sourceType = EMPTY; + + /** + * The time when converting started + */ + private static String startTime = EMPTY; + /** + * The language that should be the target language + * that means the language to translate to + */ + private static String TargetLanguage = EMPTY; + + /** + * the name of the target file + */ + private static String targetName = EMPTY; + + /** + * the type of the target file (sdf,xliff,...) + */ + private static String targetType = EMPTY; + + /** + * Store the current version ID and number of this tool + */ + final static String version = " Prod.20050710:1255 "; + + /** + * The name of the (original) sdf file used as second source for gsi->sdf merging + */ + private static String secondSourceName=EMPTY; + /** + * Indicate whether strings in xliff files should + * be wrapped with ept/bpt or sub tags to enable translation tools + * to synchronize source language string with there translation + * + * @see <a href="http://ded-1.germany.sun.com/webcontent/guidelines/pdf/L10NSO8.pdf">http://ded-1.germany.sun.com/webcontent/guidelines/pdf/L10NSO8.pdf</a> + */ + private static boolean doWrap=true; + + + + public static void main(String[] args) throws IOException, Exception { + try{ + + //go, parse and check the command line parameters + ParameterChecker.checkClParameters(args); + ParameterChecker.createContentOfClParameters(); + //Initialize the tagWrapper + DirtyTagWrapper.setWrapping(doWrap); + //create an instance of converter + Converter conv = new Converter(sourceType, sourceName, sourceLanguage, + targetType, targetName, TargetLanguage,secondSourceName, overwrite); + // get aktual time + cal = Calendar.getInstance(); + startTime = cal.getTime().toString(); + //show infos + printPreamble(); + //do the job + conv.convert(); + + showStatistic(); + + //close log, debug... + OutputHandler.closeAll(); + + } catch(Exception e){ + System.out.print("An EXCEPTION occured, please check your commad line settings \n"+e.getMessage()); + System.exit(-1); + }catch(Throwable t){ + System.out.print("A FATAL ERROR occured, please check your commad line settings \n"+t.getMessage()); + System.exit(-1); + } + + } + + /** + * show the command line help + */ + private static void printHelp() { + + final String ls = System.getProperty("line.separator"); + System.out + .println( + + "File Converting Tool 'converter' Version " + + Convert.version + + ls + + "Converts SDF files to wellformed XLIFF or GSI files and vice versa" + ls + + ls + + "Use: " + ls + + "convert [-h]|[SourcePath [TargetPath] [-T Type] [[-S Type [secondSourcePath]] " + ls + + " [-s LanguageID] [-t LanguageID] [-l [LogPath]] [-o]]" + ls + + ls + + "-h show this help." + ls + + "SourcePath path of the file to convert." + ls + + "secondSourcePath path of the SDF file to merge to (GSI -> SDF only!)." + ls + + "TargetPath path where to store the result." + ls + + "LogPath path of the log file" + ls + + "-T Type the type of the target file (xliff,sdf,gsi)" + ls + + "-S Type the type of the source file (xliff,sdf,gsi)" + ls + + "-s LanguageID the ISO language code of the source language (de, fr...)." + ls + + " Default is 'en-US' " + ls + + "-t LanguageID the language code of the target language (de, fr...)." + ls + + " Default is first found Language other than source language." + ls + + "-l [LogPath] write a log file, you can name the file." + ls + + "-o overwrite existing files without asking." + ls + + "-nw disable the wrapping with ept/bpt tags." + ls + + ls + + "The created files were stored in the SourceFile Path if nothing else is given. " + ls + + "The extension is '.xliff','.sdf' depending on the source file and '.log' " + ls + + "for the logfile." + ls); + } + + /** + * show the parameters the converter starts with + * + * @throws IOException + */ + final private static void printPreamble() throws IOException { + OutputHandler.out(EMPTY); + OutputHandler.out("Source File is: " + sourceName); + OutputHandler.out("Target File is: " + targetName); + if (OutputHandler.doLog) { + OutputHandler.out("Log File is: " + logString); + } else { + OutputHandler.out("Log File is: disabled"); + } + + OutputHandler.out(EMPTY); + + } + + /** + * show some statistic data + * + * @throws IOException + */ + final private static void showStatistic() throws IOException { + OutputHandler.dbg(EMPTY); + OutputHandler + .out((targetType.equalsIgnoreCase("xliff") ? "TransUnits written: " + : "Lines written : ") + + Converter.getLineCounter()); + OutputHandler.dbg(EMPTY); + OutputHandler.out("Started at : " + Convert.startTime); + Convert.cal = Calendar.getInstance(); + OutputHandler.out("Finished at : " + Convert.cal.getTime()); + OutputHandler.dbg(EMPTY); + + } + + /** + * Get the extensiion of a file name + * (sdf,xliff,gsi) + * + * @param sourceString the file name + * @return the extension + */ + static protected String extractExtension(String sourceString) { + String ext = sourceString.substring(sourceString + .lastIndexOf(Convert.extensionSeperator) + 1); + return ext; + } + +// static protected String extractFileName(String sourceString) { +// String sName = EMPTY; +// sName = (sourceString.substring(sourceString +// .lastIndexOf(File.separator) + 1, sourceString +// .lastIndexOf(Convert.extensionSeperator))); +// +// return sName; +// } +// +// static protected String extractPath(String sourceString) { +// String sPath = sourceString.substring(0, sourceString +// .lastIndexOf(File.separator) + 1); +// return sPath; +// } + + /** + * + */ + public Convert() { + } + + /** + * + * Verify a parameter array and create content useable by the programm + * from the switches and attributes set at command line + * + * @author Christian Schmidt 2005 + */ + private static class ParameterChecker { + + /** + * Holds the path of the source file + */ + private static String filePath; + /** + * Holds the name of the source file + */ + private static String fileName; + + /** + * Create a new Instance of ParameterChecker + * + * + */ + public ParameterChecker(){}; + /** + * Checks the command line parameters + * + * @param args the parameters to check and to parse + * @throws IOException + */ + private static void checkClParameters(String[] args) throws IOException { + try { + //show help if no attrributes... + if (args.length == 0) { + printHelp(); + System.exit(-1); + } + //...or attribute is -h + if (args[0].equals("-h")) { + printHelp(); + System.exit(0); + } + if (args[0].equals("-ver")) { + System.out.println("File Converting Tool Version "+version); + System.exit(0); + } + //source file Location and path is always first attribute + sourceName = new String(args[0]); + + File source = new File(sourceName); + //break if there is no source to convert + if (!source.exists()) + throw new IOException("ERROR:Can not find Source File '" + + sourceName + "'. Aborting..."); + + // String name=source.getName(); + // String parent=source.getParent(); + // String path=source.getPath(); + + filePath = (source.getParent()==null)?"":source.getParent()+File.separator; //extractPath(sourceName); + fileName = source.getName().substring(0,source.getName().lastIndexOf(extensionSeperator)); + + for (int i = 1; i < args.length; i++) { + + + if ("-s".equals(args[i])) { + if (args.length > i + 1) { + sourceLanguage = args[++i]; + + } else { + throw new ConverterException( + "missing argument for -s source language"); + } + continue; + } + + if ("-S".equals(args[i])) { + if (args.length > i + 1) { + sourceType = args[++i]; + if (args.length > i +1 &&!args[i+1].startsWith("-")) { + secondSourceName = args[++i]; + } + + } else { + throw new ConverterException( + "missing argument for -S source type"); + } + continue; + } + + if ("-T".equals(args[i])) { + if (args.length > i + 1) { + targetType = args[++i]; + + + } else { + throw new ConverterException( + "missing argument for -T target type"); + } + continue; + } + + if ("-l".equals(args[i])) { + OutputHandler.doLog = true; + if (args.length > i + 1 + && (!args[i + 1].startsWith("-"))) { + logString = args[++i]; + } else { + logString = EMPTY; + } + continue; + } + + if ("-o".equals(args[i])) { + overwrite = true; + continue; + } + + if ("-nw".equals(args[i])) { + doWrap = false; + continue; + } + + if ("-h".equals(args[i])) { + printHelp(); + System.exit(0); + } + + if ("-dbg".equals(args[i])) { + OutputHandler.doDebug = true; + continue; + } + + if ("-t".equals(args[i])) { + if (args.length > i + 1) { + TargetLanguage = args[++i]; + } else { + throw new ConverterException( + "missing argument for -t target language"); + } + continue; + } + + if (i == 1 && !args[i].startsWith("-")) { //target file + // found + targetName = args[i]; + continue; + } + //if we come here we + //can not match the Attribute + throw new ConverterException("unknown Attribute: " + + args[i]); + + + }//end for + } catch (ConverterException e) { + OutputHandler.out("ERROR: "+e.getMessage()); + System.exit(-1); + } catch (Throwable t){ + System.out.print("An Error occured while parsing the command line,\n please check your commad line settings.\n "+t.getMessage()); + System.exit(-1); + } + + }//end checkClParameters + + /** + * Creates the appropriate content of what ever data + * we found in the command line + * + * @throws IOException + */ + private static void createContentOfClParameters() throws IOException { + + try { + if (OutputHandler.doDebug) { + // if the -dbg switch is set, we + // create + // a file that gets all information + // produced by this tool + + OutputHandler.dbgFile = new BufferedWriter(new FileWriter( + new File(new String(filePath + fileName + ".dbg")))); + } + + if (OutputHandler.doLog) {// create a logfile? + //given at command line? + if (EMPTY.equals(logString) || logString == null) { + logString = new String(filePath + fileName + ".log"); + } + log = FileMaker.newFile(logString, overwrite); + OutputHandler.logFile = (new BufferedWriter(new FileWriter( + log))); + } + + if (EMPTY.equals(sourceType) || sourceType == null) { + // not given at command line? + if (!(EMPTY.equals(sourceName) || sourceName == null)) { + sourceType = extractExtension(sourceName); + } else { + throw new ConverterException("Source type is missing"); + } + } + + if(sourceType.equalsIgnoreCase("gsi")){ + + if(EMPTY.equals(Convert.secondSourceName)){ + Convert.secondSourceName=filePath+fileName+".sdf"; + } + //secondSource=new File(Convert.secondSourceName); + + } + + if (EMPTY.equals(sourceName)) { + sourceName = filePath + fileName + "." + sourceType; + } + //no target type given at command line? + if (EMPTY.equals(targetType) || targetType == null) { + if (!(EMPTY.equals(targetName) || targetName == null)) { + targetType = extractExtension(targetName); + } else { + throw new ConverterException("Target type is missing"); + + } + } + //no target File specified at command line + if (EMPTY.equals(targetName) || targetName == null) { + targetName = filePath + fileName + "." + targetType; + if (targetName.equals(Convert.secondSourceName)){ + OutputHandler.out("ERROR: \nSource '"+Convert.secondSourceName+"' and \nTarget'"+targetName+"' are the same"); + System.exit(0); + }else if (targetName.equals(Convert.sourceName)){ + OutputHandler.out("ERROR: \nSource '"+Convert.sourceName+"' and \nTarget'"+targetName+"' are the same"); + System.exit(0); + } + }else if (targetName.equals(Convert.secondSourceName)){ + OutputHandler.out("ERROR: \nSource '"+Convert.secondSourceName+"' and \nTarget'"+targetName+"' are the same"); + System.exit(0); + }else if (targetName.equals(Convert.sourceName)){ + OutputHandler.out("ERROR: \nSource '"+Convert.sourceName+"' and \nTarget'"+targetName+"' are the same"); + System.exit(0); + } + + + } catch (ConverterException e) { + OutputHandler.out(e.getMessage()); + } + + } + + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Converter.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Converter.java new file mode 100755 index 000000000000..7ec09bcb411a --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Converter.java @@ -0,0 +1,523 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Converter.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Converter.java + * + * create Source and Target + * for converting + * TODO maybe a factory would be good here + */ + +package com.sun.star.tooling.converter; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.EntityResolver; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; + +/** + * + * This class handles the creating of the source to read from, + * the target to write to and the appropriate DataHandler + * + * @author Christian Schmidt 2005 + */ +public final class Converter { + + /** + * the used charset f.e. UTF-8 + */ + private final static String CHARSET = new String("UTF-8"); + + private static final String EMPTY = new String(""); + + /** + * The DataHandler use to connect reader and writer + */ + private static DataHandler handler; + + /** + * Counting the lines written by a writer + */ + private static int lineCounter; + + /** + * The target to write to + */ + private static DataWriter theTargetWriter; + + + /** + * Overwrite existing files + */ + private boolean overwrite = false; + /** + * The source to read from + */ + private Source reader; + /** + * The name of the source file + */ + private String sourceString; + /** + * the Type of the Source file(SDF,GSI,XLIFF) + */ + private String sourceType; + /** + * The name of the target fille + */ + private String targetString; + /** + * the Type of the Target file(SDF,GSI,XLIFF) + */ + private String targetType; + /** + * The writer that handles the output + */ + private Target writer; + + /** + * The sourceLanguage + */ + String sourceLanguage = "en-US"; + + /** + * The targetLanguage + */ + String targetLanguage = ""; + + /** + * The name of the second source, needed for GSI to SDF merge + */ + private String secondSourceString=EMPTY; + + + /** + * Get the line counter + * @return Returns the lineCounter. + */ + public static int getLineCounter() { + return lineCounter; + } + + /** + * increment the lineCounter + */ + final static void countLine() { + lineCounter++; + } + + /** + * Creates a new instance of Converter + * + * @param sourceType the type of the sourceFile + * @param sourceString the name of the sourceFile + * @param SourceLanguage the ISO Id of the sourceLanguage + * @param targetType the type of the targetFile + * @param targetString the name of the targetFile + * @param TargetLanguage the ISO Id of the targetLanguage + * @param secondSourceString the name of the second sourceFile (GSI merge only) + * @param overwrite indicates whether overwrite existing files + * @throws IOException + * @throws Exception + */ + public Converter(String sourceType, String sourceString, + String SourceLanguage, String targetType, String targetString, + String TargetLanguage,String secondSourceString, boolean overwrite) throws IOException, + Exception { + + this.sourceType = sourceType; + this.sourceString = sourceString; + this.sourceLanguage = SourceLanguage; + this.targetType = targetType; + this.targetString = targetString; + this.targetLanguage = TargetLanguage; + this.secondSourceString=secondSourceString; + this.overwrite = overwrite; + + handler = new DataHandler(); + + if ("sdf".equalsIgnoreCase(sourceType)) { + reader = new SDFSource(); + } else if ("xliff".equalsIgnoreCase(sourceType)||"dbxliff".equalsIgnoreCase(sourceType)) { + reader = new XLIFFSource(); + } else if ("gsi".equalsIgnoreCase(sourceType)) { + reader = new GSISource(); + } else { + throw new ConverterException("Unknown Source File Type: '"+sourceType+"'"); + } + + if ("sdf".equalsIgnoreCase(targetType)) { + writer = new SDFTarget(); + } else if ("xliff".equalsIgnoreCase(targetType)) { + writer = new XLIFFTarget(); + } else if ("gsi".equalsIgnoreCase(targetType)) { + writer = new GSITarget(); + } else { + throw new ConverterException("Unknown Target File Type: '"+targetType+"'"); + } + + } + + /** + * Do the converting from the source file format to the target file format + * + * @throws IOException + */ + public final void convert() throws IOException { + + try { + + reader.convertTo(writer); + + //TODO this belongs in the Target Class + theTargetWriter.flush(); + theTargetWriter.close(); + } catch (Exception e) { + OutputHandler.out(e.getMessage()); + } + + } + + + /** + * + * Encapsulate the reading from an GSI file + * + * @author Christian Schmidt 2005 + * + */ + private class GSISource implements Source { + DataReader theSourceReader; + /** + * Create a new Instance of GSISource + * + * @throws IOException + * @throws Exception + */ + public GSISource() throws IOException { + + theSourceReader = new GSIandSDFMerger(new File(sourceString),new File(secondSourceString), sourceLanguage, + targetLanguage, CHARSET); + } + + public void convertTo(Target t) { + + try { + theTargetWriter = t.getWriter(); + while (handler.fillDataFrom(theSourceReader)) { + + theTargetWriter.getDatafrom(handler); + theTargetWriter.writeData(); + } + } catch (IOException e) { + OutputHandler.out(e.getMessage()); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + } + /** + * + * Encapsulate to write to a GSI file + * + * @author Christian Schmidt 2005 + * + */ + private class GSITarget implements Target { + + File target; + + /** + * Create a new Instance of GSITarget + * + * @throws FileNotFoundException + * @throws IOException + */ + public GSITarget() throws FileNotFoundException, IOException { + + target = FileMaker.newFile(targetString, overwrite); + theTargetWriter = new GSIWriter(new BufferedOutputStream( + new FileOutputStream(target)), CHARSET); + } + + public DataWriter getWriter() { + + return theTargetWriter; + } + + } + /** + * + * Encapsulate the reading from an SDF file + * + * @author Christian Schmidt 2005 + * + */ + private final class SDFSource implements Source { + + DataReader Source; + + /** + * Create a new Instance of SDFSource + * @throws IOException + * @throws Exception + */ + public SDFSource() throws IOException, Exception { + + Source = new SDFReader(new File(sourceString), sourceLanguage, + targetLanguage, CHARSET); + } + + public void convertTo(Target t) { + try { + theTargetWriter = t.getWriter(); + while (handler.fillDataFrom(Source)) { + + theTargetWriter.getDatafrom(handler); + theTargetWriter.writeData(); + } + + } catch (IOException e) { + OutputHandler.out(e.getMessage()); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + } + /** + * Encapsulate writing to a SDF file + * + * @author Christian Schmidt 2005 + * + */ + private class SDFTarget implements Target { + + /** + * Create a new Instance of SDFTarget + * + * @throws IOException + */ + public SDFTarget() throws IOException { + File target = FileMaker.newFile(targetString, overwrite); + theTargetWriter = new SDFWriter(new BufferedOutputStream( + new FileOutputStream(target)), CHARSET); + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.Converter.Target#getWriter() + */ + public DataWriter getWriter() { + + return theTargetWriter; + } + + } + + /** + * The interface for all convertable sources + * + * @author Christian Schmidt 2005 + * + */ + private interface Source { + + DataReader Source=null; + /** + * Convert this. to the designated target + * @param target the target of the converting + * @throws IOException + */ + abstract void convertTo(Target target) throws IOException; + } + + /** + * The interface for all creatable targets + * + * @author Christian Schmidt 2005 + * + */ + private interface Target { + /** + * The writer to use + */ + public OutputStream writer = null; + + /** + * Get the writer + * this target uses to write the + * data in the correct format. + * + * @return the used DataWriter + */ + abstract DataWriter getWriter(); + + } + /** + * Encapsulate the reading from an XLIFF file + * + * @author Christian Schmidt 2005 + * + */ + private class XLIFFSource implements Source { + File source; + + /** + * Create a new Instance of XLIFFSource + * + * + */ + public XLIFFSource() { + + source = new File(sourceString); + } + + public void convertTo(Target t) throws IOException { + try { + System.setProperty("entityExpansionLimit", "1000000"); + boolean laden = source.canRead(); + if (laden) { + DefaultHandler contentHandler=null; + if("dbxliff".equalsIgnoreCase(sourceType)){ + contentHandler = new XLIFFReader(handler, t + .getWriter(),false); + }else{ + contentHandler = new XLIFFReader(handler, t + .getWriter()); + } + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware( true ); + factory.setValidating( true ); + + SAXParser parser=factory.newSAXParser(); + XMLReader xliffreader=parser.getXMLReader(); + + + +// XMLReader xliffreader = XMLReaderFactory +// .createXMLReader("org.apache.crimson.parser.XMLReaderImpl"); + xliffreader.setErrorHandler(contentHandler); + xliffreader.setContentHandler(contentHandler); + /* one possibility to resolve an extern entity (DTD) */ + EntityResolver res = new Resolver(); + xliffreader.setEntityResolver(res); + /* + * a second possibility to resolve an extern entity (DTD) + * + * xliffreader.setFeature("xml.org/sax/features/validation",true); + * xliffreader.setEntityResolver(new EntityResolver() { + * public InputSource resolveEntity(java.lang.String + * publicId, java.lang.String systemId) throws SAXException, + * java.io.IOException { if (publicId.equals("-//XLIFF//DTD + * XLIFF//EN")) // this deactivates the open office DTD + * return new InputSource(new ByteArrayInputStream( " <?xml + * version='1.0' encoding='UTF-8'?>" .getBytes())); else + * return null; } }); + * + */ + + xliffreader.parse(sourceString); + + } else { + System.out.println("Datei existiert nicht"); + } + + } catch (SAXParseException e) { + try { + theTargetWriter.flush(); + } catch (IOException e1) { + + e1.printStackTrace(); + } + OutputHandler.out("PARSE ERROR Zeile " + e.getLineNumber() + + ", " + e.getMessage()); + + }catch (SAXException e){ + try { + theTargetWriter.flush(); + } catch (IOException e1) { + + e1.printStackTrace(); + } + OutputHandler.out("PARSE EXCEPTION " + e.getMessage()); + } catch (ParserConfigurationException e) { + OutputHandler.out("PARSER Configuration failed\n " + e.getMessage()); + } + } + + } + /** + * Encapsulate writing to a XLIFF file + * + * @author Christian Schmidt 2005 + * + */ + private class XLIFFTarget implements Target { + File target; + + /** + * Create a new Instance of XLIFFTarget + * + * @throws FileNotFoundException + * @throws IOException + */ + public XLIFFTarget() throws FileNotFoundException, IOException { + target = FileMaker.newFile(targetString, overwrite); + theTargetWriter = new XLIFFWriter(new BufferedOutputStream( + new FileOutputStream(target)), CHARSET); + + } + + public DataWriter getWriter() { + + return theTargetWriter; + } + } + + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ConverterException.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ConverterException.java new file mode 100755 index 000000000000..07a3708d4366 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ConverterException.java @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConverterException.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * a simple exception + * just to seperate + * it from other + * exceptions + */ +package com.sun.star.tooling.converter; + +/** + * @author Christian Schmidt + * + * Thrown if an error occurs during converting from one file format to another + * that does not belong to an other exception + */ +public class ConverterException extends Exception { + + /** + * + */ + public ConverterException() { + super(); + + } + + /** + * @param arg0 + */ + public ConverterException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + */ + public ConverterException(Throwable arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public ConverterException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataHandler.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataHandler.java new file mode 100755 index 000000000000..e8b4136f185a --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataHandler.java @@ -0,0 +1,149 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DataHandler.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * DataHandler.java + * + * take the data from the reader + * and put it to the Writer + * + */ + +package com.sun.star.tooling.converter; + +import java.util.*; + +/** + * Handle the Data to get it from the Source + * readable to the Target + * + * @author Christian Schmidt + */ +public class DataHandler { + + /** + * An arrays that holds the names that will be + * keys for the HashMap containing the data + * + */ + private final String[] dataNames = { "BlockNr", "Project", + "SourceFile", "Dummy", "ResType", "GID", "LID", "HID", "Platform", + "Width", "SourceLanguageID", "SourceText", "SourceHText", + "SourceQText", "SourceTitle", "TargetLanguageID", "TargetText", + "TargetHText", "TargetQText", "TargetTitle", "TimeStamp" }; + + private static final String EMPTY = new String(""); + + /** + * The HashMap containing the data + */ + private final Map data = new ExtMap(dataNames, null); + + /** Creates a new instance of DataHandler */ + public DataHandler() { + } + + /** + * fill the data from the desired source + * + * @param source where to get the data from + * @return true if data is read and false if null is read + * @throws IOException + * @throws ConverterException + */ + public boolean fillDataFrom(DataReader source) throws java.io.IOException, + ConverterException { + + Map line = null; + + line = source.getData(); + if (line == null){ + + return false; + }else{ + + this.data.putAll(line); + return true; + } + + + } + + /** + * fill this data with the inData + * + * @param inData the data to handle by this handler + */ + public void fillDataWith(Map inData) { + data.putAll(inData); + } + +// public void transfer(DataWriter target, DataReader source) { +// +// source.setHandler(this); +// +// } + + /** + * The designated output is filled with the content of this handler + * + * @param output an array of Maps [0] should hold the source language data [1] the target language data + * @throws java.io.IOException + */ + public void putDataTo(Map[] output) throws java.io.IOException { + String aKey = EMPTY; + for (int j = 0; j < output.length; j++) { + Set keys = output[j].keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + aKey = (String) iter.next(); + output[j].put(aKey, data.get(aKey)); + } + } + + } + /** + * The designated output is filled with the content of this handler + * + * @param output a Map that should hold the source language data and the target language data + * @throws java.io.IOException + */ + public void putDataTo(Map output) throws java.io.IOException { + String aKey = EMPTY; + + Set keys = output.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + aKey = (String) iter.next(); + output.put(aKey, data.get(aKey)); + } + + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataReader.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataReader.java new file mode 100755 index 000000000000..59de7ca7e1f4 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataReader.java @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DataReader.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package com.sun.star.tooling.converter; + +import java.io.*; +import java.util.*; + +/** + * Gets Line counting from LineNumberReader all Converter Reader classes inherit + * from this. + * The abstract parent class of all converter reader classes + * + * @author Christian Schmidt + */ +abstract public class DataReader extends LineNumberReader { + + /** + * Creates a new instance of DataReader + * + * @param isr + * InputStreamReader used as Source for this class + */ + public DataReader(InputStreamReader isr) { + super(isr); + } + + /** + + * @throws java.io.IOException + * @throws ConverterException + * + * TODO this should no longer use an array as return type better a Map + * + */ + /** + * The next block of the SDF file is reviewed and the Line including the + * source language and the Line including the target Language are given back + * in an array + * + * + * @return A Map including the source language + * and the target Language content are given back + * + * @throws java.io.IOException + * @throws ConverterException + */ + public Map getData() throws java.io.IOException, ConverterException { + return null; + } + + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataWriter.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataWriter.java new file mode 100755 index 000000000000..c5d6765e3840 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/DataWriter.java @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DataWriter.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * DataWriter.java + * + * parent of all XXXWriter classes used by + * Converter + */ + +package com.sun.star.tooling.converter; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; + +/** + * The abstract parent class of all converter writer classes + * + * @author Christian Schmidt + */ +abstract public class DataWriter extends OutputStreamWriter { + protected final String seperator = new String("|"); + + /** + * the char sequence used as line seperator + */ + protected final String lineEnd = java.lang.System.getProperty( + "line.seperator", "\n"); + + /** Creates a new instance of DataWriter */ + /** + * @param bos the buffered output stream holding the data + * @param encoding the encoding to use for read from bos + * @throws java.io.UnsupportedEncodingException + */ + public DataWriter(BufferedOutputStream bos, String encoding) + throws java.io.UnsupportedEncodingException { + super(bos, encoding); + } + +// abstract protected void writeData(Map[] data) throws java.io.IOException; + + /** + * get the data that should be written from the DataHandler + * + * @param handler the DataHandler having the data + * @throws java.io.IOException + */ + abstract protected void getDataFrom(DataHandler handler) + throws java.io.IOException; + + /** + * write the Data + * + * @throws java.io.IOException + */ + abstract protected void writeData() throws java.io.IOException; + + /** + * @param handler + * @throws IOException + */ + abstract protected void getDatafrom(DataHandler handler) throws IOException; +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ExtMap.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ExtMap.java new file mode 100755 index 000000000000..b05767e93ae3 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ExtMap.java @@ -0,0 +1,97 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ExtMap.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * A special HashMap, + * can be constructed of + * two Arrays + */ +package com.sun.star.tooling.converter; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Christian Schmidt + * + * Create a Hash Map from two Arrays + * + */ +public class ExtMap extends HashMap { + + /** + * + */ + public ExtMap() { + super(); + + } + + /** + * @see java.util.HashMap + * @param arg0 + */ + public ExtMap(int arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public ExtMap(int arg0, float arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public ExtMap(Map arg0) { + super(arg0); + + } + + // create a new Map from two string arrays + public ExtMap(String[] names, String[] content) { + super(names.length); + if (content == null) + content = new String[names.length]; + for (int i = 0; i < names.length; i++) { + if (i >= content.length) { + break; + } else { + this.put(names[i], content[i]); + } + } + + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/FileMaker.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/FileMaker.java new file mode 100755 index 000000000000..a21b8daa7b1d --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/FileMaker.java @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: FileMaker.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * creates new files + * checks if they exist or + * can be overwritten + * + */ +package com.sun.star.tooling.converter; + +import java.io.File; +import java.io.IOException; + +/** + * Creates new files only if the file does not yet exist + * or overwriting is allowed + * + * @author Christian Schmidt 2005 + * + */ +public final class FileMaker { + + /** + * Create a new file if overwriting is not alowed + * ask if existing files should be overwritten + * + * @param fileName the files name to overwrite + * @param overwrite indicates wether the file can be overwritten + * @return the File created from the fileName + * @throws IOException + */ + public final static File newFile(String fileName, boolean overwrite) + throws IOException { + File file = new File(fileName); + if (file.exists()) { + if (!overwrite) { + char c = 0; + + System.out.print("Warning: File " + fileName + + " already exist.\n" + "Overwrite (y/n) ? :"); + byte[] waste = new byte[10]; + System.in.read(waste); + c = (char) waste[0]; + if (c == 'y') { + OutputHandler.out("...overwriting " + fileName); + } else { + OutputHandler.out( + "\nPlease set '-o' switch at command line to overwrite.\n\nProgramm Aborted."); + System.exit(-1); + } + } else { + OutputHandler.out("...overwriting " + fileName); + } + } else { + OutputHandler.out("...creating new target file " + fileName); + } + return file; + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIReader.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIReader.java new file mode 100755 index 000000000000..adb6e358a74c --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIReader.java @@ -0,0 +1,250 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: GSIReader.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.converter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +import com.sun.star.tooling.languageResolver.LanguageResolver; +import com.sun.star.tooling.languageResolver.LanguageResolver.LanguageResolvingException; + +/** + * @author Christian Schmidt 2005 + * + */ +public class GSIReader extends DataReader { + /** + * A Map holding an empty GSIBlock + */ + private Map EmptyGSIBlock; + + /** + * @see LanguageResolver + */ + LanguageResolver languageResolver; + + /** + * The source language identifier + */ + protected String sourceLanguage; + + /** + * The target language identifier + */ + protected String targetLanguage; + + /** + * The number of the last block + */ + private String oldBlockNr; + + /** + * A buffer holding one GSILine + */ + private Map GSILineBuffer; + + /** + * Indicates whether to use the buffered line + */ + private boolean useBuffer = false; + + private static final String EMPTY = new String(""); + + /** + * An empty Map to fill with language depending data + */ + private ExtMap EmptyLanguageMap; + + /** + * Indicates whether the first block is read + */ + private boolean isFirst = true; + + private int lineCounter; + + private int blockCounter; + /** + * Indicates whether the last line is read + */ + private boolean lastLineFound = false; + + /** + * Create a new Instance of GSIReader + * + * @param source + * the file to read from + * @param sourceLanguage + * the sourceLanguage (must not be empty) + * @param targetLanguage + * the targetLanguage + * @param charset + * the charset used to read source + * @throws java.io.IOException + * @throws Exception + */ + public GSIReader(File source, String sourceLanguage, String targetLanguage, + String charset) throws java.io.IOException { + super(new InputStreamReader(new FileInputStream(source), charset)); + this.languageResolver = new LanguageResolver(); + this.sourceLanguage = sourceLanguage; + this.targetLanguage = targetLanguage; + + EmptyLanguageMap = new ExtMap(new String[0], new String[0]); + + } + + /** + * Read the next GSIBlock and return the data + * + * @return A Map containing the data of the read GSIBlock the keys for the language depending data are the language id (numeric) the + * single language are acessible with the keys "BlockNr", "resType", "languageNr", "status","content". + * + * @throws IOException + */ + public Map getGSIData() throws IOException { + String help; + Map helpmap; + Map GSIBlock = new HashMap(); + GSIBlock.put(sourceLanguage, EmptyLanguageMap.clone()); + GSIBlock.put(targetLanguage, EmptyLanguageMap.clone()); + String line = EMPTY; + String[] splitLine; + Map GSILine; + String[] GSINames = { "BlockNr", "resType", "languageNr", "status", + "content" }; + + while (useBuffer || (line = readLine()) != null) { + + + + if (useBuffer) { + GSILine = GSILineBuffer; + GSIBlock.put(sourceLanguage, EmptyLanguageMap.clone()); + GSIBlock.put(targetLanguage, EmptyLanguageMap.clone()); + GSIBlock.put("BlockNr", GSILine.get("BlockNr")); + useBuffer = false; + } else { + this.lineCounter++; + if ((splitLine = split(line)) == null) { + continue; + } + GSILine = new ExtMap(GSINames, splitLine); + if (isFirst) { + GSIBlock.put("BlockNr", GSILine.get("BlockNr")); + oldBlockNr = (String) GSILine.get("BlockNr"); + isFirst = false; + } + } + if (oldBlockNr == null) { + oldBlockNr = (String) GSILine.get("BlockNr"); + } + if (!oldBlockNr.equals((String) GSILine.get("BlockNr"))) { + GSILineBuffer = GSILine; + oldBlockNr = (String) GSILine.get("BlockNr"); + useBuffer = true; + break; + } + String lang; + try { + // Is there the source language in this line? + if ((lang = languageResolver.getISOfromNr((String) GSILine + .get("languageNr"))).equals(this.sourceLanguage)) { + // ok..store it as Source String under the depending + // ressource type + + ((Map) GSIBlock.get(sourceLanguage)).put("Source" + + ResTypeResolver.getInternKey((String) GSILine + .get("resType")), GSILine.get("content")); + // ..maybe the target language? + } else { + if (targetLanguage.equals(EMPTY)) { + // if no target language is given at command line + targetLanguage = lang; + GSIBlock.put(targetLanguage, EmptyLanguageMap.clone()); + } + if (lang.equals(this.targetLanguage)) { + + // ok..store it as target String under the depending + // ressource type + ((Map) GSIBlock.get(targetLanguage)).put("Target" + + ResTypeResolver.getInternKey((String) GSILine + .get("resType")), GSILine + .get("content")); + } + } + } catch (LanguageResolvingException e) { + OutputHandler.out("Can not resolve the language "+e.getMessage()); + } + + } + if (line == null) { + if (lastLineFound){ + OutputHandler.out("\n\n"); + OutputHandler.out("GSI Blocks : " + this.blockCounter); + OutputHandler.out("GSI Lines : " + this.lineCounter); + + return null; + }else{ + lastLineFound = true; + this.blockCounter++; + return GSIBlock; + } + } else { + this.blockCounter++; + return GSIBlock; + } + + } + + /** + * Split a GSILine to single fields + * + * @param line + * The line to split + * @return An array containing the contents of the columns in the given line + */ + private String[] split(String line) { + String[] splitLine = (line.substring(0, line.length() - 1)) + .split("\\(\\$\\$\\)"); + if (splitLine.length != 5) + return null; + else + return splitLine; + } + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIWriter.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIWriter.java new file mode 100755 index 000000000000..085e26475e09 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIWriter.java @@ -0,0 +1,246 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: GSIWriter.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.tooling.converter; +import java.io.*; +import java.util.Map; + +import com.sun.star.tooling.languageResolver.LanguageResolver; +import com.sun.star.tooling.languageResolver.LanguageResolver.LanguageResolvingException; +/** + * + * @author cs156069 + */ +public class GSIWriter extends DataWriter { + /** + * The seperator used to seperate GSI columns + */ + final String seperator=new String("($$)"); + + /** + * Holding the keys used by a map holding the content of an GSI Line contianing the source language + */ + final static String[] sourceLineNames= {"Project","SourceFile","Dummy","ResType","GID","LID","HID","Platform","Width","SourceLanguageID","SourceText","SourceHText","SourceQText","SourceTitle","TimeStamp"}; + /** + * Holding the keys used by a map holding the content of an GSI Line contianing the target language + */ + final static String[] targetLineNames= {"Project","SourceFile","Dummy","ResType","GID","LID","HID","Platform","Width","TargetLanguageID","TargetText","TargetHText","TargetQText","TargetTitle","TimeStamp"}; + /** + * Holding the keys used by a map holding the content of an GSI Line contianing the source and the target language + */ + final static String[] outLineNames= {"BlockNr","Project","SourceFile","Dummy","ResType","GID","LID","HID","Platform","Width","SourceLanguageID","SourceText","SourceHText","SourceQText","SourceTitle","TargetLanguageID","TargetText","TargetHText","TargetQText","TargetTitle","TimeStamp"}; + + /** + * A map holding the content of an GSI Line contianing the source language + */ + private ExtMap sourceLine=new ExtMap(sourceLineNames,null); + /** + * A map holding the content of an GSI Line contianing the target language + */ + private ExtMap targetLine=new ExtMap(targetLineNames,null); + /** + * A map holding the content of an GSI Line contianing the source and the target language + */ + private ExtMap outData=new ExtMap(outLineNames, null); + + private static final String EMPTY = new String(""); + /** + * The sourceLanguage to use + */ + private String sourceLanguage; + /** + * The sourceLanguage to use + */ + private String targetLanguage; + + /** + * GSILines have a special Line End + */ + private final static String lineEnd="!"+'\r'+'\n'; + //private boolean SourceIsFirst=false; + + /** + * The blockNr of the current line + */ + private String blockNr; + + + + + /** + * Create a new Instance of GSIWriter + * + * @param bos the Buffered Output Stream to write to + * @param charset the used charset + * @throws java.io.UnsupportedEncodingException + */ + public GSIWriter(BufferedOutputStream bos,String charset) throws java.io.UnsupportedEncodingException { + super(bos,charset); + + + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#writeData() + */ + public final void writeData() throws java.io.IOException { + + StringBuffer buffer=new StringBuffer(""); + if(this.sourceLanguage==null&&this.targetLanguage==null){ + LanguageResolver lang =new LanguageResolver(); + try { + this.sourceLanguage=lang.getNrFromISO((String)outData.get("SourceLanguageID")); + this.targetLanguage=lang.getNrFromISO((String)outData.get("TargetLanguageID")); + } catch (LanguageResolvingException e) { + + OutputHandler.out(e.getMessage()); + System.exit(0); + } + } + + + this.blockNr=(String)outData.get("BlockNr"); + // get the values of the found fields + //create the gsi lines + // + //at first the source language line + buffer.append(getSourceLine("Text")); + buffer.append(getSourceLine("HText")); + buffer.append(getSourceLine("QText")); + buffer.append(getSourceLine("Title")); + + //now the target language line + // put them together for output + buffer.append(getTargetLine("Text")); + buffer.append(getTargetLine("HText")); + buffer.append(getTargetLine("QText")); + buffer.append(getTargetLine("Title")); + //ok...put all to disk; + this.write(buffer.toString()); + + } + + /** + * Create a line containing the source string from the data + * @param resType + * @return The StringBuffer containing the line + */ + private StringBuffer getSourceLine(String resType){ + StringBuffer buffer =new StringBuffer(200); + String resString = "Source"+resType; + + String help; + if(EMPTY.equals((String)outData.get(resString))||" ".equals(outData.get(resString))) return new StringBuffer(EMPTY); + else { + // put them together for output + buffer.append(this.blockNr); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append(ResTypeResolver.getExternKey(resType)); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append(this.sourceLanguage); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append("int"); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append(outData.get(resString)); + + // this line is full + // so close it with '! cr lf' + buffer.append(GSIWriter.lineEnd); + Converter.countLine(); + return buffer; + } + + } + /** + * Create a line containing the target string from the data + * @param resType + * @return The StringBuffer containing the line + */ + private StringBuffer getTargetLine(String resType){ + StringBuffer buffer =new StringBuffer(200); + String resString = "Target"+resType; + + if(EMPTY.equals((String)outData.get(resString))||" ".equals(outData.get(resString))) return new StringBuffer(EMPTY); + else { + // put them together for output + buffer.append(this.blockNr); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append(ResTypeResolver.getExternKey(resType)); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append(this.targetLanguage); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append("ext"); + // seperate the fields with ($$) + buffer.append(this.seperator); + buffer.append(outData.get(resString)); + + // this line is full + // so close it with '! cr lf' + buffer.append(GSIWriter.lineEnd); + Converter.countLine(); + return buffer; + } + + } + + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#writeData(java.util.Map[]) + */ + protected void writeData(Map[] data) throws IOException { + // TODO redesign DataHandler in the way that this is not nessesary any more + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#getDataFrom(com.sun.star.tooling.converter.DataHandler) + */ + protected void getDataFrom(DataHandler handler) throws IOException { + + handler.putDataTo(this.outData); + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#getDatafrom(com.sun.star.tooling.converter.DataHandler) + */ + protected void getDatafrom(DataHandler handler) throws IOException { + + handler.putDataTo(this.outData); + + } +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIandSDFMerger.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIandSDFMerger.java new file mode 100755 index 000000000000..ff0348f97d3d --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/GSIandSDFMerger.java @@ -0,0 +1,167 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: GSIandSDFMerger.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.converter; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * Merge GSIFiles back to to the original (!) SDFFile + * + * + * @author Christian Schmidt 2005 + * + */ +public class GSIandSDFMerger extends SDFReader { + + int lineCounter=0; + + GSIReader gsiReader; + + private Map temp=new HashMap(); + private int j; + private boolean skip=true; + Map gsiBlock=null; + Map sdfBlock=null; + + private boolean dontLoadGSI=false; + + private int count; + /** + * Merge the GSIFile back to the original(!) SDFFile + * + * @param source the file to read from + * @param sourceLanguage the source language in the source file + * @param targetLanguage the target language in the source file + * @param charset the charset of the files + * @throws java.io.IOException + * @throws Exception + */ + public GSIandSDFMerger(File source, File secondSource,String sourceLanguage, + String targetLanguage, String charset) throws IOException { + // merging GSI and SDF requieres two Sources + //this. is the SDF source + super(secondSource, sourceLanguage, targetLanguage, charset); + //create the GSI Source + + gsiReader=new GSIReader(source,sourceLanguage,targetLanguage,charset); + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataReader#getData() + */ + public Map getData()throws java.io.IOException{ + do{ + skip=false; + this.temp=matchGSI(); + }while(skip); + if(temp==null){ + OutputHandler.out("Blocks merged : "+this.lineCounter); + } + return temp; + + } + + /** + * Read each block of the GSIFile and check whether there is a matching + * block in the SDFFile. Match depends on the BlockNr and BlockId. + * + * @return A Map that contains the source language content + * and the target language content. + * @throws IOException + * @throws ConverterException + */ + public Map matchGSI() throws IOException{ + + + try { + //System.out.println("Start..."); + + if (dontLoadGSI||(gsiBlock=gsiReader.getGSIData())!=null){ + dontLoadGSI=false; + //check if we must update this block + //if so its BlockNr is in the gsi file + if((sdfBlock = super.getData())!=null){ + + if(((String)sdfBlock.get("BlockNr")).equals((String)gsiBlock.get("BlockNr"))){ + + gsiBlock.remove(EMPTY); + //if the target language string is empty this may be caused by an error in the source sdf File + //I don't want to overwrite a possibly correct translation with an empty string + // so remove the target part from the gsiBlock + Map mp=(Map)gsiBlock.get(gsiReader.targetLanguage); + if (mp.size()!=0&&!((String)mp.get("TargetText")).equals("")){ + + // target language part in this gsiBlock +// if(((String)mp.get("TargetText")).equals("")){ +// gsiBlock.remove(targetLanguage); +// } + // count the merged blocks + lineCounter++; + Map helpMap = (Map)gsiBlock.get(super.targetLanguage);//"ja" + sdfBlock.putAll(helpMap); + skip=false; + }else{ + //no target language part in this gsiBlock + skip=true; +// +// return null; + } + }else{ +// skip=true; +// +// // we cant match this gsi block to the current sdf block + // try matching the next sdf block with this gsi line + dontLoadGSI=true; + } + } + return sdfBlock; + } + + } catch (IOException e) { + + e.printStackTrace(); + } + return null; + } + + + + + + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/LineErrorException.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/LineErrorException.java new file mode 100755 index 000000000000..6a11360cc472 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/LineErrorException.java @@ -0,0 +1,81 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: LineErrorException.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Exception for errors in + * SDFLines + */ +package com.sun.star.tooling.converter; + + +/** + * This Exeption is thrown if a DataReader finds an error in a read Line + * f. e. wrong column number + * + * @author Christian Schmidt 2005 + * + */ +public class LineErrorException extends Exception { + + public int tokenCount; + /** + * + */ + public LineErrorException() { + super(); + + } + + /** + * @param arg0 + */ + public LineErrorException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + */ + public LineErrorException(Throwable arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public LineErrorException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/OutputHandler.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/OutputHandler.java new file mode 100755 index 000000000000..997c05a70b4f --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/OutputHandler.java @@ -0,0 +1,228 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: OutputHandler.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Creates logfile and file for debug information + * + */ +package com.sun.star.tooling.converter; + +import java.io.BufferedWriter; +import java.io.IOException; + +/** + * Handle the whole output during converting process except the converted files. + * Write output to logfiles and to screen depending on switches given + * at command line. + * @author Christian Schmidt 2005 + * + */ +public class OutputHandler { + + private static final String EMPTY = ""; + + /** + * The logfile to write + */ + public static BufferedWriter logFile; + + /** + * Indicates whether excisting files should be overwritten + */ + public static boolean doLog = false; + + /** + * Indicate whether the debug information should be written + */ + public static boolean doDebug = false; + + /** + * The File to write the debug information to + */ + public static BufferedWriter dbgFile; + + /** + * Write the data to screen and if the switches were set to + * logfile and debugfile + * + * @param out the String to write + */ + final static void out(String out) { + try { + if (doDebug) + OutputHandler.dbg(out); + + if (!doLog || logFile == null) { + System.out.println(out); + } else { + System.out.println(out); + if (EMPTY.equals(out)) { + OutputHandler.log(EMPTY); + } else { + OutputHandler.log(out); + } + } + } catch (IOException e) { + + OutputHandler.log(e.toString()); + } + } + + /** + * make a dot on the screen to show the user that it is going on + */ + final static void printDot() { + System.out.print("."); + + } + + /** + * write the data to log file and if the switch is set + * to the debug file + * + * @param out the String to write + */ + final static void log(String out) { + try { + if(out==null) return; + if (doDebug) + + OutputHandler.dbg(out); + + if (doLog) { + if (!EMPTY.equals(out)) { + logFile.write(out); + } + logFile.newLine(); + logFile.flush(); + } + } catch (IOException e) { + + System.out.println(e.getMessage()); + } + } + + /** + * write the string to the debug file + * + * @param out the String to write + * @throws IOException + */ + final static void dbg(String out) throws IOException { + if(out==null) return; + if (doDebug) { + if (!EMPTY.equals(out)) { + dbgFile.write(out); + + } + dbgFile.newLine(); + dbgFile.flush(); + } + } + + /** + * Set a new value to indicate whether a debug file should be written or not + * + * @param doDebug + * The debug value to set. + */ + private static void setDebug(boolean doDebug) { + OutputHandler.doDebug = doDebug; + } + + // /** + // * @return Returns the doDebug. + // */ + // private static boolean isDebug() { + // return doDebug; + // } + + /** + * Set the debug file to write to. + * + * @param dbgFile + * The debug File to use. + */ + private static void setDbgFile(BufferedWriter dbgFile) { + OutputHandler.dbgFile = dbgFile; + } + + /** + * @return Returns the debug File. + */ + private static BufferedWriter getDbgFile() { + return dbgFile; + } + + /** + * @param doLog + * The log value to set. + */ + private static void setLog(boolean doLog) { + OutputHandler.doLog = doLog; + } + + /** + * @return Returns the log value. + */ + private static boolean isLog() { + return doLog; + } + + /** + * @param logFile + * The logFile to set. + */ + private static void setLogFile(BufferedWriter logFile) { + OutputHandler.logFile = logFile; + } + + /** + * @return Returns the logFile. + */ + private static BufferedWriter getLogFile() { + return logFile; + } + + /** + * @throws IOException + * close log and dbg + */ + public static void closeAll() throws IOException { + if (OutputHandler.logFile != null) { + OutputHandler.logFile.flush(); + OutputHandler.logFile.close(); + } + if (OutputHandler.dbgFile != null) { + OutputHandler.dbgFile.flush(); + OutputHandler.dbgFile.close(); + } + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ResTypeResolver.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ResTypeResolver.java new file mode 100755 index 000000000000..f53fe0101275 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/ResTypeResolver.java @@ -0,0 +1,71 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ResTypeResolver.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.converter; + +import java.util.Map; + +/** + * Helps resolving restype descriptors used outside the tool to + * restype descriptors used by this tool + * + * @author Christian Schmidt 2005 + * + */ +public class ResTypeResolver { + final static String[] inFields={"Text","QText","HText","Title"}; + final static String[] outFields={"res","res-quickhelp","res-help","res-title"}; + final static Map internKeys=new ExtMap(inFields,outFields); + final static Map externKeys=new ExtMap(outFields,inFields); + + /** + * Get the intern key depending to the given extern key + * + * @param externKey the externKey {"res","res-quickhelp","res-help","title"} + * @return the depending intern key + */ + public static String getInternKey(String externKey){ + return (String)externKeys.get(externKey); + } + + /** + * Get the extern key to the given intern key + * + * @param internKey the internal key + * @return the external key + */ + public static String getExternKey(String internKey){ + return (String)internKeys.get(internKey); + } + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Resolver.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Resolver.java new file mode 100755 index 000000000000..29a9ee2e528a --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/Resolver.java @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Resolver.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 27.01.2005 + * + */ +package com.sun.star.tooling.converter; + +import java.io.IOException; +import java.io.InputStream; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Resolve external entities by provide the + * XLIFF DTD stored in the jar file + */ +public class Resolver implements EntityResolver { + + /** + * Resolver constructor. + */ + public Resolver() { + } + + /** + * Allow the application to resolve external entities. + * + * The Parser will call this method before opening any external entity + * except the top-level document entity (including the external DTD subset, + * external entities referenced within the DTD, and external entities + * referenced within the document element): the application may request that + * the parser resolve the entity itself, that it use an alternative URI, or + * that it use an entirely different input source. + */ + + /* (non-Javadoc) + * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String) + */ + + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException { + + if ((publicId != null) && (publicId.equals("-//XLIFF//DTD XLIFF//EN"))) { + systemId = "dtd:///xliff.dtd"; + } + if (systemId != null) { + if (systemId.startsWith("dtd://")) { + String dtd = "com/sun/star/tooling/converter/dtd" + + systemId.substring(6); + ClassLoader cl = this.getClass().getClassLoader(); + InputStream in = cl.getResourceAsStream(dtd); + InputSource ins = new InputSource(in); + ins.setSystemId(systemId); + return ins; + } /* + * else if ( systemId.startsWith("jar:") ) { try { URL url=new + * URL(systemId); JarURLConnection jarConn = + * (JarURLConnection)url.openConnection(); InputSource ins=new + * InputSource(jarConn.getInputStream()); + * ins.setSystemId(systemId); return ins; } + * catch(MalformedURLException me){ throw new SAXException(me); + * Incorrect URL format used } } + */ + } + return null; + } + +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/SDFReader.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/SDFReader.java new file mode 100755 index 000000000000..4c0c234778ec --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/SDFReader.java @@ -0,0 +1,635 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SDFReader.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * SDFReader.java + * + * + */ + +package com.sun.star.tooling.converter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.text.DecimalFormat; +import java.util.*; + +/** + * + * SDFReader is a FileReader that knows about + * the content of SDFFiles + * + * A SDFBlock is read of the given file. A SDFBlock + * consists of all SDFLines that are traanslations of the + * same String and the SDFLine containing the source string + * itself. SDFFile lines are read and checked whether they + * have the allowed column count and don't contain illeagal + * characters (like most unprintable characters below 0x00df). + * If the given source language is not found in the first + * block of SDFLines a ConverterException is thrown at runtime. + * If the given target language is "" (that means not given) + * the first language that is not the given source language + * is taken for target language. The found values are returned in HashMaps that + * use the following keys: + * <br/> + * "BlockNr" originally coming from reading the sdf file, contains 'block nr in sdf file'+'-'+'hash value of the sdf id fields'.<br/> + * "Project" first column in sdf file format.<br/> + * "SourceFile" second column in sdf file format.<br/> + * "Dummy" third column in sdf file format.<br/> + * "ResType" 4. column in sdf file format.<br/> + * "GID" 5. column in sdf file format. <br/> + * "LID" 6. column in sdf file format.<br/> + * "HID" 7. column in sdf file format.<br/> + * "Platform" 8. column in sdf file format. <br/> + * "Width", 9. column in sdf file format.<br/> + * "SourceLanguageID" 10. column in sdf file format(in the line with the source language).<br/> + * "SourceText" 11. column in sdf file format(in the line with the source language).<br/> + * "SourceHText" 12. column in sdf file format(in the line with the source language).<br/> + * "SourceQText" 13. column in sdf file format(in the line with the source language).<br/> + * "SourceTitle" 14. column in sdf file format(in the line with the source language).<br/> + * "TargetLanguageID" 10. column in sdf file format (in the line with the target language).<br/> + * "TargetText" 11. column in sdf file format (in the line with the target language).<br/> + * "TargetHText" 12. column in sdf file format (in the line with the target language).<br/> + * "TargetQText" 13. column in sdf file format (in the line with the target language).<br/> + * "TargetTitle", 14. column in sdf file format (in the line with the target language).<br/> + * "TimeStamp" 15. column in sdf file format.<br/> + * + * @author Christian Schmidt 2005 + * + */ + +public class SDFReader extends DataReader { + + /** + * an array of the SDF files column names + */ + final static String[] fieldnames = { "Project", "SourceFile", "Dummy", + "ResType", "GID", "LID", "HID", "Platform", "Width", "LanguageID", + "Text", "HText", "QText", "Title", "TimeStamp" }; + + /** + * an array of the SDF files column names if the source language is in + */ + final static String[] sourceLineNames = { "Project", "SourceFile", "Dummy", + "ResType", "GID", "LID", "HID", "Platform", "Width", + "SourceLanguageID", "SourceText", "SourceHText", "SourceQText", + "SourceTitle", "TimeStamp" }; + + /** + * an array of the SDF files column names if the target language is in + */ + final static String[] targetLineNames = { "Project", "SourceFile", "Dummy", + "ResType", "GID", "LID", "HID", "Platform", "Width", + "TargetLanguageID", "TargetText", "TargetHText", "TargetQText", + "TargetTitle", "TimeStamp" }; + + final static String EMPTY = new String(""); + + private int dotCount = 0; + + /** + * a Map containing an SDF line with source language + */ + private Map sourceMap; + + /** + * a Map containing an SDF line with target language + */ + private Map targetMap; + + /** + * a Map containing an SDF + */ + private Map SDFMap; + + /** + * a Map Array containing one SDF source language line and one SDF target + * language line + */ + private Map[] data = { sourceMap, targetMap }; + + /** + * The Id of the current SDFBlock + */ + private String CurrentBlockId; + + /** + * The SDF file to read from + */ + private File sourceFile; + + /** + * The language in the source file that should be handelt as source language + */ + protected String sourceLanguage; + + /** + * The language in the source file that should be handelt as target language + */ + protected String targetLanguage; + + /** + * A counter holding the number of blocks just read + * from this file + */ + private long blockNr = 0;// If we use Integer, more then numbers greater than 128k would be signed + + /** + * A counter holding the number of skipped lines that means + * lines that can not be worked with because they contain an error + */ + private int skippedLines = 0; + + /** + * This switch is set for indicating that all source file lines + * are read and no lines remain buffered. Finding this like 'true' + * means the source file is finished + */ + private boolean endIt = false; + + /** + * Indicates whether the targetLanguage is found in this source file so far + */ + private boolean foundTarget = false; + /** + * Indicates whether the sourceLanguage is found in this source file so far + */ + private boolean foundSource = false; + + /** + * Counts how many lines were skipped because the language is + * neither sourceLanguage nor targetLanguage + */ + private int langMiss; + + /** + * Indicates whether there is a line in the read buffer or not + */ + private boolean useBuffer = false; + + /** + * A buffer for SDFLines + */ + private String lineBuffer; + + /** + * The buffer for the already splitted SDFLines + */ + private String[] splittedLineBuffer; + + /** + * Counts how many Blocks were skipped + * f.e. because no sourceLanguage is found + * in it + */ + private int skippedBlocks; + + /** + * Counts the blocks without targetLanguage + */ + private int targetLangMiss; + + /** + * Counts the blocks without sourceLanguage + */ + private int sourceLangMiss; + + /** + * Counts the lines where no targetLanguage line was found + * and so empty lines were created + */ + private int targetLangCreate; + + + DecimalFormat blockNrFormatter = new DecimalFormat("000000"); + + /** + * The hashcode of the current block + */ + private int CurrentBlockHash; + + private boolean skip; + + /** + * Create a new Instance of SDFREader + * + * @param source the file to read from + * @param sourceLanguage the sourceLanguage (must not be empty) + * @param targetLanguage the targetLanguage + * @param charset the charset used to read source + * @throws java.io.IOException + * @throws Exception + */ + public SDFReader(File source, String sourceLanguage, String targetLanguage, + String charset) throws java.io.IOException { + super(new InputStreamReader(new FileInputStream(source), charset)); + sourceFile = source; + this.sourceLanguage = sourceLanguage; + this.targetLanguage = targetLanguage; + String line; + String[] splitLine; + //read first line to get the first + //SDF block id + mark(16000); + if ((line = readLine()) != null) { + if ((splitLine = split(line)) != null){ + this.CurrentBlockId = getSDFBlockId(splitLine); + this.CurrentBlockHash=this.CurrentBlockId.hashCode(); + //found the first + this.blockNr++; + } + this.splittedLineBuffer = splitLine; + } + reset(); + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataReader#getData() + */ + public Map getData()throws IOException { + + Map map=new HashMap(); +// do { + this.skip=false; + Map[] help=readBlock(); + if(help==null||help[1]==null||help[0]==null){ + return null; +// }else if (help[1].get("TargetLanguageID")==null||help[0].get("SourceLanguageID")==null) { +// OutputHandler.log("Missing Language Id in block "+blockNr+"\nthe block is skipped." ); +// this.skippedBlocks++; +// this.skip=true; + }else{ + map.putAll(help[1]); + map.putAll(help[0]); + + } +// }while(this.skip=true); + return map; + } + + + /** + * Read a Block from the sdf file and return + * @return a Map[] where [0] holds the source and [1] the target language data. + * + * @throws java.io.IOException + */ + public Map[] readBlock() throws java.io.IOException { + String line = EMPTY; + String blockId = EMPTY; + String[] splittedLine = null; + data[0]=new ExtMap(); + data[1]=new ExtMap(); + String help; + String c = null; + //read next line or use buffered line + while (useBuffer || (line = readLine()) != null) { //works because '||' is shortcut + + try { + // buffer used? + if (useBuffer) { + line = this.lineBuffer; + splittedLine = this.splittedLineBuffer; + this.SDFMap = new ExtMap(SDFReader.fieldnames, splittedLine); + + try { + checkLanguage(splittedLine); + } catch (ConverterException e) { + throw e; + }finally{ + + useBuffer = false; + } + } else { + //...are there wrong characters? + if ((check(line)).length() < line.length()) { + throw new LineErrorException(getLineNumber() + + " : Line contains wrong character " + //+ Integer.toHexString(Integer.parseInt(c)) + + " \n" + line); + } + //...is the number of columns ok? + if ((splittedLine = split(line)) == null) { + + throw new LineErrorException(super.getLineNumber() + + " : Line has wrong column number \n" + line); + //continue; + } else { + // TODO makeDot is better in Data Handler + makeDot(); + // ...is this line in a new SDF block ? + if ((blockId = getSDFBlockId(splittedLine)) + .equals(CurrentBlockId)) { + + this.SDFMap = new ExtMap(SDFReader.fieldnames, + splittedLine); + //what language is in it ? + checkLanguage(splittedLine); + + } else { + + /* + * we found the next block , but do we have the + * target text? + */ + + if (!foundTarget) { + createTargetLine(); + } + + blockNr++; + splittedLineBuffer = splittedLine;//read one line + // too much so + // buffer it + lineBuffer = line; + useBuffer = true;//reset(); + + this.CurrentBlockId = blockId; + this.CurrentBlockHash=this.CurrentBlockId.hashCode(); + + /* ...and what about the source text ? */ + if (!foundSource) { + + OutputHandler + .log("Error in Line:" + + getLineNumber() + + "Source Language is missing maybe " + + "previous block has an error.\nBlock " + + (blockNr - 1) + + " is skipped. before line: \n" + + line); + + foundTarget = false;//no target without source + skippedBlocks++; + skippedLines++; + sourceLangMiss++; + continue;// skip output of this block if no + // source language is found + + } + + break; + + } + } + + } + + } catch (LineErrorException e) { + + OutputHandler.log(e.getMessage()); + this.skippedLines++; + } catch (ConverterException e) { + OutputHandler.log(e.getMessage()); + } + + } + // did we read the whole stuff? + if (null != line) { + // no + foundSource = false; + foundTarget = false; + + return this.data; + + } else { + // ok , its the end but is everything written now? + if (!endIt) { + // there is something to write + // but next time we can end it + endIt = true; + if(!foundTarget){ + createTargetLine(); + } + // write + return this.data;//last lines + } else { + + showStat(); + return null; + } + } + // }catch(ConverterException e) { + // Converter.log(e.getMessage()); + // return null; + // } + } + + /** + * + */ + private void createTargetLine() { + targetLangMiss++; + // if not, create one ... + data[1] = new ExtMap(SDFReader.targetLineNames, + splittedLineBuffer); + data[1].put("TargetLanguageID", + this.targetLanguage); + if ((String) data[1].get("TargetText") != EMPTY) + data[1].put("TargetText", EMPTY); + if ((String) data[1].get("TargetHText") != EMPTY) + data[1].put("TargetHText", EMPTY); + if ((String) data[1].get("TargetQText") != EMPTY) + data[1].put("TargetQText", EMPTY); + if ((String) data[1].get("TargetTitle") != EMPTY) + data[1].put("TargetTitle", EMPTY); + this.data[1].put("BlockNr", blockNrFormatter.format(blockNr)+'-'+Integer.toString(this.CurrentBlockHash)); + targetLangCreate++; + } + + /** + * Show the statistic information got while + * reading the file + * + * @throws IOException + */ + private void showStat() throws IOException { + OutputHandler.out(EMPTY);OutputHandler.out(EMPTY); + // OutputHandler.out("Hashes: " + (theHashes.size()) + " "); + OutputHandler.out("Blocks found: " + blockNr + " "); + OutputHandler.out(EMPTY); + OutputHandler.out("Lines read: " + (getLineNumber()) + " "); + OutputHandler + .dbg("Lines created " + (targetLangCreate) + " "); + OutputHandler.dbg(" -------"); + OutputHandler.dbg("Lines total: " + + (getLineNumber() + targetLangCreate) + " "); + OutputHandler.dbg("Lines skipped: " + skippedLines + " "); + + OutputHandler.dbg("Source Language misses: " + sourceLangMiss + " "); + OutputHandler.dbg("Target Language misses: " + targetLangMiss + " "); + OutputHandler.dbg("Blocks found: " + blockNr + " "); + OutputHandler.dbg("Blocks skipped: " + skippedBlocks + " "); + if ((sourceLangMiss + skippedBlocks + skippedLines) > 0) + OutputHandler.out("\n---! Errors found !--- view Logfile.\n\n" + + "To enable logfile use -l option at command line.\n" + + "For help type 'convert -h {Enter}'.\n"); + } + + /** + * Check the current line whether the source language + * or target language is in it + * + * @throws ConverterException if a not needed language or no target language is found + * in this block + * @throws IOException + * + */ + final private void checkLanguage(String[] splittedLine) + throws ConverterException, IOException { + String langID = (String) SDFMap.get("LanguageID"); + + //maybe the source language is in this line + if (!foundSource && this.sourceLanguage.equals(langID)) { +// found the next source language line + this.data[0] = new ExtMap(SDFReader.sourceLineNames, splittedLine); + +// this.data[0].put("BlockNr", Integer.toHexString(blockNr)); +// this.data[0].put("BlockHash", Integer.toHexString(this.CurrentBlockHash)); + this.data[0].put("BlockNr", blockNrFormatter.format(blockNr)+'-'+Integer.toHexString(this.CurrentBlockHash)); +// this.data[0].put("BlockHash", blockHashFormatter.format(this.CurrentBlockHash)); + foundSource = true; + return; + + } else { + // or the target language is in this line + if (!foundTarget) { + //no target language is given at command line + if (this.targetLanguage.equals(EMPTY)) { + //try if we can use the current lines language for target + // language + if (!langID.equals(this.sourceLanguage)) { + //yes , we can use this lines laanguage as target + this.targetLanguage = langID; + + //source and target language both are known: show it + OutputHandler.out("Source Language is: " + + this.sourceLanguage + " "); + OutputHandler.out("Target Language is: " + + this.targetLanguage + " "); + OutputHandler.out(EMPTY); + System.out.println("Start"); + + } else { + throw new ConverterException("(" + getLineNumber() + + ") No target language found: " + + this.targetLanguage); + } + } + if (this.targetLanguage.equals(langID)) { + this.data[1] = new ExtMap(SDFReader.targetLineNames, + splittedLine);// found the next target language line + this.data[1].put("BlockNr", blockNrFormatter.format(blockNr)+'-'+Integer.toHexString(this.CurrentBlockHash)); + foundTarget = true; + + return; + } + }//end !foundTarget + } + //if we go here we dont need the found language... + throw new ConverterException("found not needed language '" + + this.SDFMap.get("LanguageID") + "' in Line: " + + getLineNumber()); + + } + + /** + * Make a dot on the screen to show the user that it is going on + */ + private void makeDot() { + int count = 0; + if ((count = (int) super.getLineNumber() / 1000) > this.dotCount) { + this.dotCount = count; + OutputHandler.printDot(); + } + + } + + /** + * split the SDFLine in its columns + * + * @param line the current SDFLine + * @return the splitted SDFLine as array of String + * or null if an error occours + * @throws IOException + */ + private String[] split(String line) throws IOException { + check(line); + String[] splitLine; + if ((splitLine = line.split("\t")).length == 15) + return splitLine; + else + //an error occured + return null; + } + + /** + * create a block Id from a splitted SDFLine + * the blockId consists of the column one to eight of an SDF File + * + * @param splitLine the line to create a block id from + * @return the blockId as String + */ + private String getSDFBlockId(String[] splitLine) { + StringBuffer BlockId = new StringBuffer(""); + for (int i = 0; i < 8; i++) { + BlockId.append(splitLine[i]); + } + return BlockId.toString(); + } + +// public final boolean canRead() { +// return this.sourceFile.canRead(); +// } + + /** + * Check if there are not allowed characters in this line + * + * @param line the SDFLine to check + * @return if everything, ok the original + * else the wrong character as String + * + * @throws java.io.IOException + */ + private String check(String line) throws java.io.IOException { + char c = ' '; + for (int i = 0; i < line.length(); i++) { + c = line.charAt(i); + if (c < 30 && c != 9) { + return (new Character(c)).toString(); + } + + } + return line; + + } +}
\ No newline at end of file diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/SDFWriter.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/SDFWriter.java new file mode 100755 index 000000000000..98eb8c856e6a --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/SDFWriter.java @@ -0,0 +1,175 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: SDFWriter.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * SDFWriter.java + * + * + */ + +package com.sun.star.tooling.converter; +import java.io.*; +import java.util.Map; + +/** + * Write data to a SDFFile + * + * @author Christian Schmidt 2005 + * + */ +public class SDFWriter extends DataWriter { + /** + * the seperator the seperate columns + */ + final String seperator=new String("\t"); + /** + * an array of the SDF files column names if the source language is in + */ + final static String[] sourceLineNames= {"Project","SourceFile","Dummy","ResType","GID","LID","HID","Platform","Width","SourceLanguageID","SourceText","SourceHText","SourceQText","SourceTitle","TimeStamp"}; + /** + * an array of the SDF files column names if the target language is in + */ + final static String[] targetLineNames= {"Project","SourceFile","Dummy","ResType","GID","LID","HID","Platform","Width","TargetLanguageID","TargetText","TargetHText","TargetQText","TargetTitle","TimeStamp"}; + /** + * an array of the SDF files column names if the source and the target language is in + */ + final static String[] outLineNames= {"BlockNr","Project","SourceFile","Dummy","ResType","GID","LID","HID","Platform","Width","SourceLanguageID","SourceText","SourceHText","SourceQText","SourceTitle","TargetLanguageID","TargetText","TargetHText","TargetQText","TargetTitle","TimeStamp"}; + + /** + * A Map holding the source language line content + */ + private ExtMap sourceLine=new ExtMap(sourceLineNames,null); + /** + * A Map holding the target language line content + */ + private ExtMap targetLine=new ExtMap(targetLineNames,null); + /** + * A Map holding the whole content for output + */ + private ExtMap outData=new ExtMap(outLineNames, null); +// private ExtMap SDFLine; +// private InputStreamReader isr; + /** + * The language to translate from + */ + private String sourceLanguage; + /** + * The language to translate to + */ + private String targetLanguage; + +// private boolean SourceIsFirst=false; + + + + + /** + * Create a new Instance of SDFWriter + * + * @param bos BufferedWriter to write to + * @param charset the charset to use to write + * @throws java.io.UnsupportedEncodingException + */ + public SDFWriter(BufferedOutputStream bos,String charset) throws java.io.UnsupportedEncodingException { + super(bos,charset); + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#writeData() + */ + public final void writeData() throws java.io.IOException { + + StringBuffer buffer=new StringBuffer(""); + + // get the values of the found fields + //create the two sdf lines + + //at first the source language line + for(int i=0;i<sourceLineNames.length;i++){ + // put them together for output + buffer.append(outData.get(sourceLineNames[i])); + if(i!=sourceLineNames.length-1) { + // seperate the fields with tab + buffer.append(seperator); + }else{ + // this line is full + // so close it with lf + buffer.append(lineEnd); + Converter.countLine(); + } + } + // is there a target line with anything in the strings? + if (!(outData.get("TargetLanguageID")==null||((outData.get("TargetTitle").equals("")&&outData.get("TargetText").equals("")&&outData.get("TargetHText").equals("")&&outData.get("TargetQText").equals(""))))){ + //now the target language line + for(int i=0;i<targetLineNames.length;i++){ + // put them together for output + buffer.append(outData.get(targetLineNames[i])); + if(i!=targetLineNames.length-1) { + // seperate the fields with tab + buffer.append(seperator); + }else{ + // this line is full + //so close it with lf + buffer.append(lineEnd); + Converter.countLine(); + } + } + } + this.write(buffer.toString()); + + } + + + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#writeData(java.util.Map[]) + */ + protected void writeData(Map[] data) throws IOException { + // TODO redesign DataHandler in the way that this is not nessesary any more + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#getDataFrom(com.sun.star.tooling.converter.DataHandler) + */ + protected void getDataFrom(DataHandler handler) throws IOException { + + handler.putDataTo(this.outData); + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#getDatafrom(com.sun.star.tooling.converter.DataHandler) + */ + protected void getDatafrom(DataHandler handler) throws IOException { + + handler.putDataTo(this.outData); + + } +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/XLIFFReader.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/XLIFFReader.java new file mode 100755 index 000000000000..522dcc18a5bd --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/XLIFFReader.java @@ -0,0 +1,745 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: XLIFFReader.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * XLIFFReader.java + * + * + */ +package com.sun.star.tooling.converter; + +import java.io.IOException; +import java.util.Hashtable; +import java.util.Map; + +import com.sun.star.tooling.languageResolver.LanguageResolver; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.AttributesImpl; +import org.xml.sax.helpers.DefaultHandler; + + +/** + * Parse the given file and extract the content needed. + * <br/> + * This Reader understands the parts of the + * <a href="http://www.oasis-open.org/committees/xliff/documents/cs-xliff-core-1.1-20031031.htm">xliff</a> spezification used to translate + * the strings in Star-Office and Open-Office. + * <br/> + * The given file is parsed and the content is stored in a HashMap with those keys: + * <br/> + * "BlockNr" originally coming from reading the sdf file, contains 'block nr in sdf file'+'-'+'hash value of the sdf id fields'.<br/> + * "Project" first column in sdf file format.<br/> + * "SourceFile" second column in sdf file format.<br/> + * "Dummy" third column in sdf file format.<br/> + * "ResType" 4. column in sdf file format.<br/> + * "GID" 5. column in sdf file format. <br/> + * "LID" 6. column in sdf file format.<br/> + * "HID" 7. column in sdf file format.<br/> + * "Platform" 8. column in sdf file format. <br/> + * "Width", 9. column in sdf file format.<br/> + * "SourceLanguageID" 10. column in sdf file format(in the line with the source language).<br/> + * "SourceText" 11. column in sdf file format(in the line with the source language).<br/> + * "SourceHText" 12. column in sdf file format(in the line with the source language).<br/> + * "SourceQText" 13. column in sdf file format(in the line with the source language).<br/> + * "SourceTitle" 14. column in sdf file format(in the line with the source language).<br/> + * "TargetLanguageID" 10. column in sdf file format (in the line with the target language).<br/> + * "TargetText" 11. column in sdf file format (in the line with the target language).<br/> + * "TargetHText" 12. column in sdf file format (in the line with the target language).<br/> + * "TargetQText" 13. column in sdf file format (in the line with the target language).<br/> + * "TargetTitle", 14. column in sdf file format (in the line with the target language).<br/> + * "TimeStamp" 15. column in sdf file format.<br/> + * @ + * @author Christian Schmidt 2005 + * + */ +public class XLIFFReader extends DefaultHandler { + + /** + * A String array holding the keys used by the HashMap holding the Data + */ + private final String[] dataNames = { "BlockNr", "Project", + "SourceFile", "Dummy", "ResType", "GID", "LID", "HID", "Platform", + "Width", "SourceLanguageID", "SourceText", "SourceHText", + "SourceQText", "SourceTitle", "TargetLanguageID", "TargetText", + "TargetHText", "TargetQText", "TargetTitle", "TimeStamp" }; + + /** + * Used to index in the data array + */ + static int index = 0; + + /** + * The Map that holds the data returned by this class + */ + private Map moveData = new ExtMap(); + + /** + * A Map that holds yet incomplete data + * until all depending transunits are found + */ + private Hashtable DataStore = new Hashtable(); + + /** + * An Elements name + */ + private String name = new String(""); + + /** + *List of Attributes used by an Element + */ + private Attributes attrs; + +// private String tagElement = new String(""); + + /** + * Indicates whether the next found content string should be printed + */ + private boolean printThis = false; + /** + * Indicates whether the next found content string should be stored + */ + private boolean storeIt = false; + + /** + * data holds the information created while parsing + * + */ + private String[] data = new String[26]; + + /** + * The handler used by this class + */ + private final DataHandler handler; + /** + * The target used by this class + */ + private final DataWriter target; + +// private boolean searchForText = false; + + /** + * counts how many dots are made + */ + private int dotCount; + + /** + * Counts how many Trans Units are read + */ + private int transUnitCounter; + + /** + * used source Language + */ + private String sourceLanguage; + + /** + * used target language + */ + private String targetLanguage; + + /** + * indicates whether this is the first Transunit + */ + private boolean isFirst = true; + + private static final String EMPTY = new String(""); + + /** + * the last index in data where something is written + */ + private int oldindex; + +// private boolean isBptEptTag; + +// private String innerString; +// +// private String key; + + /** + * Index for the BlockNr in the data array + */ + private static final int BLOCKNR_IDX = 0; + /** + * Index for the Project in the data array + */ + private static final int PROJECT_IDX = 1; + /** + * Index for the Sourcefile name in the data array + */ + private static final int SOURCEFILE_IDX = 2; + /** + * Index for the 'dummy' in the data array + */ + private static final int DUMMY_IDX = 3; + /** + * Index for the Group Id in the data array + */ + private static final int GID_IDX = 4; + /** + * Index for the Local Id in the data array + */ + private static final int LID_IDX = 5; + /** + * Index for the Help Id in the data array + */ + private static final int HID_IDX = 6; + /** + * Index for the Platform in the data array + */ + private static final int PLATFORM_IDX = 7; + /** + * Index for the 'Width' in the data array + */ + private static final int WIDTH_IDX = 8; + /** + * Index for the Sourcelanguage Id in the data array + */ + private static final int SOURCE_LANGUAGE_ID_IDX = 10; + /** + * Index for the Source Text in the data array + */ + private static final int SOURCE_TEXT_IDX = 11; + /** + * Index for the Source Helptext in the data array + */ + private static final int SOURCE_HELPTEXT_IDX = 12; + /** + * Index for the Source Quickhelp Text in the data array + */ + private static final int SOURCE_QUICK_HELPTEXT_IDX = 13; + /** + * Index for the Source Titletext in the data array + */ + private static final int SOURCE_TITLETEXT_IDX = 14; + /** + * Index for the Timestamp in the data array + */ + private static final int TIMESTAMP_IDX = 15; + /** + * Index for the res type in the data array + */ + private static final int RESTYPE_IDX = 16; + /** + * Index for the Target Language Id in the data array + */ + private static final int TARGET_LANGUAGE_ID_IDX = 20; + /** + * Index for the Target Text in the data array + */ + private static final int TARGET_TEXT_IDX = 21; + /** + * Index for the Target Helptext in the data array + */ + private static final int TARGET_HELP_TEXT_IDX = 22; + /** + * Index for the Target Quickhelp Text in the data array + */ + private static final int TARGET_QUICKHELP_TEXT_IDX = 23; + /** + * Index for the Target Titletext in the data array + */ + private static final int TARGET_TITLE_TEXT_IDX = 24; + /** + * Index for the Found Parts Counter in the data array + */ + private static final int FOUND_PARTS_COUNTER_IDX = 18; + + /** + * used to find the matching ISO or RFC3066 language code + */ + LanguageResolver languageResolver; + + private boolean doBlockCompleteCheck=true; + + + + /** + * Create a new Instance of XLIFFReader + * + * @param handler the DataHandler to use + * @param target the target used + * @throws IOException + */ + public XLIFFReader(DataHandler handler, DataWriter target) throws IOException { + this.languageResolver = new LanguageResolver(); + this.handler = handler; + this.target = target; + } + + /** + * Create a new Instance of XLIFFReader + * + * @param handler the DataHandler to use + * @param target the target used + * @param doBlockCompleteCheck indicates whether every single transunit should be returned or the whole block data is to be collected + * + * @throws IOException + */ + public XLIFFReader(DataHandler handler, DataWriter target,boolean doBlockCompleteCheck) throws IOException { + this(handler, target); + this.languageResolver = new LanguageResolver(); + this.doBlockCompleteCheck=doBlockCompleteCheck; + + } + + /** + * delete and initialize the data content + */ + public void initData() { + for (int i = BLOCKNR_IDX; i < SOURCE_LANGUAGE_ID_IDX; i++) { + data[i] = ""; + } + for (int i = SOURCE_TEXT_IDX; i < TIMESTAMP_IDX; i++) { // skip Time Stamp + data[i] = ""; + } + for (int i = RESTYPE_IDX; i < TARGET_LANGUAGE_ID_IDX; i++) { // skip Source language ID + data[i] = ""; + } + for (int i = TARGET_TEXT_IDX; i < 26; i++) {// skip Target language ID, + data[i] = ""; + } + + data[DUMMY_IDX] = "0";//dummy + data[FOUND_PARTS_COUNTER_IDX] = "1";//parts found + + } + + /** (non-Javadoc) + * @see org.xml.sax.ContentHandler#startDocument() + */ + public void startDocument() { + initData(); + //System.out.print("Start"); + + } + + /** (non-Javadoc) + * @see org.xml.sax.ContentHandler#endDocument() + */ + public void endDocument() { + + try { + showStatistic(); + } catch (IOException e) { + + OutputHandler.log(e.getMessage()); + + } + } + + /** (non-Javadoc) + * @throws SAXException + * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) + */ + public void startElement(String namespaceURI, String sName, String qName, + Attributes attrs) throws SAXException { + this.name = new String(qName); + this.attrs = new AttributesImpl(attrs); + String resType; + + String attributeName = new String(""); + String attribute = new String(""); + String tagElement = new String(""); + int i; + + if (qName.equals("bpt")||qName.equals("ept")||qName.equals("sub")||qName.equals("ex")) { + //ignore bpt, ept, ex and sub tags + // content of the tags will be stored + + storeIt=true; + return; + + } + if (qName.equals("target")) { + if ((resType = data[RESTYPE_IDX]) == null) { + + } else { + if ("res".equals(resType)) { + index = TARGET_TEXT_IDX; + + storeIt = true; + return; + } + // if("res-Help".equals(resType)){ + // index=TARGET_HELP_TEXT_IDX; + // storeIt=true; + // return; + // } + if ("res-QuickHelp".equals(resType)) { + index = TARGET_QUICKHELP_TEXT_IDX; + + storeIt = true; + return; + } + if ("res-Title".equals(resType)) { + index = TARGET_TITLE_TEXT_IDX; + + storeIt = true; + return; + } + } + + } + if (qName.equals("source")) { + if ((resType = data[RESTYPE_IDX]) == null) { + //throw new SAXException("Ressource type not found"); + } else { + if ("res".equals(resType)) { + index = SOURCE_TEXT_IDX; + + storeIt = true; + return; + } + // if("res-Help".equals(resType)){ + // index=SOURCEHELPTEXT_IDX; + // storeIt=true; + // return; + // } + if ("res-QuickHelp".equals(resType)) { + index = SOURCE_QUICK_HELPTEXT_IDX; + storeIt = true; + return; + } + if ("res-Title".equals(resType)) { + index = SOURCE_TITLETEXT_IDX; + storeIt = true; + return; + } + } + } + + if (qName.equals("file")) { + data[TIMESTAMP_IDX] = attrs.getValue("date"); + //data[17]=(attrs.getValue("original")); + try{ + data[SOURCE_LANGUAGE_ID_IDX] = (languageResolver.getISOFromRFC((String)attrs.getValue("source-language"))); + if(languageResolver.getISOFromRFC((String)attrs.getValue("target-language"))!=null){ + data[TARGET_LANGUAGE_ID_IDX] = (languageResolver.getISOFromRFC((String)attrs.getValue("target-language"))); + } + }catch(Exception e){ + OutputHandler.log(e.getMessage()); + } + return; + } + if (qName.equals("trans-unit")) { + String id = attrs.getValue("id"); + if ((DataStore.get(id)) != null) { + //TODO arraycopy might not be nessessary + System.arraycopy((String[]) DataStore.get(id), 0, data, 0, + data.length); + int help = (new Integer(data[FOUND_PARTS_COUNTER_IDX])).intValue(); //found one more part + help++; // refresh the actual found parts + data[FOUND_PARTS_COUNTER_IDX] = (new Integer(help)).toString(); // belonging to this information + + DataStore.remove(attrs.getValue("id")); // TODO this can be deleted? + } else { + + data[BLOCKNR_IDX] = (attrs.getValue("id")); // a new part + } + data[RESTYPE_IDX] = (attrs.getValue("restype")); + + return; + } + + if (qName.equals("context")) { + + String value = attrs.getValue("context-type"); + + if ("SourceHelpText".equals(value)) { + index = SOURCE_HELPTEXT_IDX; + storeIt = true; + return; + }else if ("TargetHelpText".equals(value)) { + index = TARGET_HELP_TEXT_IDX; + storeIt = true; + return; + }else if ("DBType".equals(value)) { + //index=SOURCEFILE_IDX; + //storeIt=true; + return; + }else if ("Project".equals(value)) { + index = PROJECT_IDX; + storeIt = true; + return; + }else if ("Filename".equals(value)) { + index = SOURCEFILE_IDX; + storeIt = true; + return; + }else if ("Type".equals(value)) { + index = RESTYPE_IDX; + storeIt = true; + return; + }else if ("GID".equals(value)) { + index = GID_IDX; + storeIt = true; + return; + }else if ("LID".equals(value)) { + index = LID_IDX; + storeIt = true; + return; + }else if ("HID".equals(value)) { + index = HID_IDX; + storeIt = true; + return; + }else if ("Platform".equals(value)) { + index = PLATFORM_IDX; + storeIt = true; + return; + }else if ("Width".equals(value)) { + index = WIDTH_IDX; + storeIt = true; + return; + } + + } + + } + + /** (non-Javadoc) + * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) + */ + public void endElement(String namespaceURI, String sName, String qName) + throws SAXException { + //we ignore bpt and ept tags + if(!(qName.equals("bpt")||qName.equals("ept")||qName.equals("sub")||qName.equals("ex"))){ + storeIt = false; + } + if (qName.equals("trans-unit")) { + showData(); + } + + } + + /** (non-Javadoc) + * @see org.xml.sax.ContentHandler#characters(char[], int, int) + */ + public void characters(char[] ch, int start, int length) { + + // checkContent(); + String str2 = new String(ch, start, length); + + if (storeIt) { + + String str = new String(ch, start, length); + if (index == oldindex) { + data[index] += str; + } else { + data[index] = str; + } + + } + oldindex = index; + + } + + /** (non-Javadoc) + * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) + */ + public void error(SAXParseException e) throws SAXParseException { + + OutputHandler.log(e.getMessage()); + } + + /** (non-Javadoc) + * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) + */ + public void fatalError(SAXParseException e) throws SAXParseException { + + OutputHandler.log("PARSE ERROR in line " + e.getLineNumber() + ", " + + e.getMessage() ); + + } + + /** (non-Javadoc) + * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) + */ + public void warning(SAXParseException e) throws SAXParseException { + //throw e; + OutputHandler.log(e.getMessage()); + } + + /** + * Put the Data to the DataHandler + * tell the Writer to write it + * + * @throws SAXException + */ + public void showData() throws SAXException { + transUnitCounter++; + makeDot(); + if (isComplete()) { + + try { + moveData(); + if (isFirst == true) { + this.sourceLanguage = (String) this.moveData + .get("SourceLanguageID"); + this.targetLanguage = (String) this.moveData + .get("TargetLanguageID"); + OutputHandler.out(EMPTY); + OutputHandler.out("Source Language is: " + + this.sourceLanguage); + OutputHandler.out("Target Language is: " + + this.targetLanguage); + OutputHandler.out(EMPTY); + OutputHandler.out("Start"); + OutputHandler.out(EMPTY); + isFirst = false; + } + target.getDataFrom(handler); + target.writeData(); + + } catch (java.io.IOException e) { + throw new SAXException(e); + } + + } else { + DataStore.put(data[BLOCKNR_IDX], data.clone()); + initData(); + + } + initData(); + } + + + /** + * put the data in an Map in the format that + * DataHandler can handle it + */ + final public void moveData() { + + moveData.put("BlockNr", data[BLOCKNR_IDX]); + + moveData.put("Project", data[PROJECT_IDX]); + + moveData.put("SourceFile", data[SOURCEFILE_IDX]); + + moveData.put("Dummy", "0"); + + moveData.put("ResType", data[RESTYPE_IDX]); + + moveData.put("GID", data[GID_IDX]); + + moveData.put("LID", data[LID_IDX]); + + moveData.put("HID", data[HID_IDX]); + + moveData.put("Platform", data[PLATFORM_IDX]); + + if (EMPTY.equals(data[WIDTH_IDX])) + data[WIDTH_IDX] = "0"; + moveData.put("Width", data[WIDTH_IDX]); + + moveData.put("SourceLanguageID", data[SOURCE_LANGUAGE_ID_IDX]); + + moveData.put("SourceText", data[SOURCE_TEXT_IDX]); + + moveData.put("SourceHText", data[SOURCE_HELPTEXT_IDX]); + + moveData.put("SourceQText", data[SOURCE_QUICK_HELPTEXT_IDX]); + + moveData.put("SourceTitle", data[SOURCE_TITLETEXT_IDX]); + + moveData.put("TargetLanguageID", data[TARGET_LANGUAGE_ID_IDX]); + + moveData.put("TargetText", data[TARGET_TEXT_IDX]); + + moveData.put("TargetHText", data[TARGET_HELP_TEXT_IDX]); + + moveData.put("TargetQText", data[TARGET_QUICKHELP_TEXT_IDX]); + + moveData.put("TargetTitle", data[TARGET_TITLE_TEXT_IDX]); + + moveData.put("TimeStamp", data[TIMESTAMP_IDX]); + + //and give it to the data handler + this.handler.fillDataWith(moveData); + } + + /** + * complete means all depending parts have been found esp. all res types + * that belong to the same SDF Line + * + * @return true if the data is complete + * + */ + final public boolean isComplete() { + + if(!doBlockCompleteCheck){ + return true; + } + + String sParts; + if (data[FOUND_PARTS_COUNTER_IDX] == EMPTY) + data[FOUND_PARTS_COUNTER_IDX] = "1"; //this is the first part + + String sFoundParts = data[FOUND_PARTS_COUNTER_IDX]; + //create the new 'id' + sParts = data[BLOCKNR_IDX].substring(data[BLOCKNR_IDX].lastIndexOf(":") + 1); + + if (sFoundParts.equals(sParts)) { + return true; + } + return false; + } + + // TODO this belongs in OutputHandler + /** + * show the user that it is going + * on by printing dots on the screen + * + */ + private void makeDot() { + int count = 0; + if ((count = (int) this.transUnitCounter / 1000) > this.dotCount) { + this.dotCount = count; + OutputHandler.printDot(); + } + } + + /** + * show the statistic data found while parse this file + * + * @throws IOException + */ + final void showStatistic() throws IOException { + OutputHandler.out(EMPTY); + OutputHandler.out("TransUnits found: " + this.transUnitCounter); + // every data in DataStore is + // skipped 'cause its not complete + // TODO count really every transunit not only the data (might consist of + // more than one + OutputHandler.dbg("TransUnits skip : " + this.DataStore.size()); + //Converter.out(EMPTY); + } +} + diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/XLIFFWriter.java b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/XLIFFWriter.java new file mode 100755 index 000000000000..42eef42884c1 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/XLIFFWriter.java @@ -0,0 +1,535 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: XLIFFWriter.java,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * + /* + * XLIFFWriter.java + * + * + */ + +package com.sun.star.tooling.converter; + +import java.io.*; +import java.util.*; + +import com.sun.star.tooling.DirtyTags.DirtyTagWrapper; +import com.sun.star.tooling.languageResolver.LanguageResolver; +import com.sun.star.tooling.languageResolver.LanguageResolver.LanguageResolvingException; + +/** + * Write the Data to a wellformed XLIFF File + * + * @author Christian Schmidt + */ +public class XLIFFWriter extends DataWriter { + + /** + * An array holding the keys of the HashMap containing the source language string + */ + private final static String[] sourceLineNames = { "Project", "SourceFile", + "Dummy", "ResType", "GID", "LID", "HID", "Platform", "Width", + "SourceLanguageID", "SourceText", "SourceHText", "SourceQText", + "SourceTitle", "TimeStamp" }; + /** + * An array holding the keys of the HashMap containing the target language string + */ + private final static String[] targetLineNames = { "Project", "SourceFile", + "Dummy", "ResType", "GID", "LID", "HID", "Platform", "Width", + "TargetLanguageID", "TargetText", "TargetHText", "TargetQText", + "TargetTitle", "TimeStamp" }; + /** + * An array holding the keys of the HashMap containing the source and target language string + */ + private final static String[] outLineNames = { "BlockNr", "Project", + "SourceFile", "Dummy", "ResType", "GID", "LID", "HID", "Platform", + "Width", "SourceLanguageID", "SourceText", "SourceHText", + "SourceQText", "SourceTitle", "TargetLanguageID", "TargetText", + "TargetHText", "TargetQText", "TargetTitle", "TimeStamp" }; + /** + * An Map holding the source and target content + */ + private final Map data = new ExtMap(outLineNames, null); + + + /** + * Indicates if this is the first Transunit to write + */ + boolean isFirst = true; + + LanguageResolver languageResolver; + + + /** + * Create a new Instance of XLIFFWriter + * + * @param bos the Buffered Output Stream to write to + * @param charset the charset to use + * @throws IOException + */ + public XLIFFWriter(BufferedOutputStream bos, String charset) + throws IOException { + super(bos, charset); + this.languageResolver =new LanguageResolver(); + + + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#getDatafrom(com.sun.star.tooling.converter.DataHandler) + */ + public void getDatafrom(DataHandler handler) throws java.io.IOException { + handler.putDataTo(this.data); + } + + /** + * check if the item is an empty String + * + * @param item the string to check + * @return true if it is not empty, false if it is empty + */ + private final boolean isUsed(String item) { + if (!"".equals(item)) + return true; + return false; + } + + /** + * Replaces all characters that mustn't be in XLIFF PCdata + * + * @param string the string to check + * @return the checked string with all characters replaced + * @throws java.io.IOException + */ + private final String xmlString( final String string) throws java.io.IOException { + if (string == null) + return string; // "" + String str = string; +// str = str.replaceAll("&", "&"); +// str = str.replaceAll("<", "<"); +// str = str.replaceAll(">", ">"); +// str = str.replaceAll("\"", """); +// str = str.replaceAll("'", "'"); + for(int i=0;i<str.length();i++){ + if(str.charAt(i)=='&'){ + str=str.substring(0, i)+"&"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='<'){ + str=str.substring(0, i)+"<"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='>'){ + str=str.substring(0, i)+">"+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='"'){ + str=str.substring(0, i)+"""+str.substring(i+1); + continue; + } + + if(str.charAt(i)=='\''){ + str=str.substring(0, i)+"'"+str.substring(i+1); + continue; + } + } + + return str; + } + + /* (non-Javadoc) + * @see java.io.Writer#close() + */ + public void close() throws IOException { + this.writeTrailer(); + + super.close(); + } + + /* (non-Javadoc) + * @see com.sun.star.tooling.converter.DataWriter#writeData() + */ + public void writeData() throws IOException { + if (isFirst) { + + writeHeader(); + isFirst = false; + } + try{ + writeTransUnit(); + }catch(DirtyTagWrapper.TagWrapperException e){ + + } + } + + /** + * Write the XLIFFFiles header + * + * @throws IOException + */ + private void writeHeader() throws IOException { + + this.write(getHeader()); + } + + /** + * Write the XLIFFFiles Trailer + * + * @throws IOException + */ + private void writeTrailer() throws IOException { + this.write(getTrailer()); + } + + /** + * Write the next TransUnit + * + * @throws IOException + */ + private void writeTransUnit() throws IOException, DirtyTagWrapper.TagWrapperException { + try{ + StringBuffer writeBuffer = new StringBuffer(1000); + + StringBuffer allLinesEnd = new StringBuffer(200); + String sRessource = ""; + int parts = 0; + if (data == null) { + OutputHandler.out("error");// TBD Exception + } + + if (!(this.data.get("SourceText").equals("") || this.data.get( + "SourceText").equals(" "))) { + parts++; + } + // if(!(this.data.get("SourceHText").equals("")||this.data.get("SourceHText").equals(" + // "))){ + // parts++; + // } + if (!(this.data.get("SourceQText").equals("") || this.data.get( + "SourceQText").equals(" "))) { + parts++; + } + if (!(this.data.get("SourceTitle").equals("") || this.data.get( + "SourceTitle").equals(" "))) { + parts++; + } + if (!(this.data.get("SourceText").equals("") || this.data.get( + "SourceText").equals(" "))) { + sRessource = "res"; // normal TEXT source + + allLinesEnd + .append("\t\t\t\t<context-group name=\"StarOffice Attributes\">\n"); + + if (isUsed((String) this.data.get("ResType"))) + allLinesEnd + .append("\t\t\t\t\t<context context-type=\"DBType\">" + + xmlString((String) this.data.get("ResType")) + + "</context>\n"); + if (isUsed((String) this.data.get("Project"))) + allLinesEnd + .append("\t\t\t\t\t<context context-type=\"Project\">" + + xmlString((String) this.data.get("Project")) + + "</context>\n"); + if (isUsed((String) this.data.get("SourceFile"))) + allLinesEnd + .append("\t\t\t\t\t<context context-type=\"Filename\">" + + xmlString((String) this.data + .get("SourceFile")) + "</context>\n"); + if (isUsed((String) this.data.get("SourceHText"))) + allLinesEnd + .append("\t\t\t\t\t<context context-type=\"SourceHelpText\">" + + xmlString((String) this.data + .get("SourceHText")) + "</context>\n"); + if (isUsed((String) this.data.get("TargetHText"))) + allLinesEnd + .append("\t\t\t\t\t<context context-type=\"TargetHelpText\">" + + xmlString((String) this.data + .get("TargetHText")) + "</context>\n"); + if (isUsed((String) this.data.get("ResType"))) + allLinesEnd.append("\t\t\t\t\t<context context-type=\"Type\">" + + xmlString((String) this.data.get("ResType")) + + "</context>\n"); + if (isUsed((String) this.data.get("GID"))) + allLinesEnd.append("\t\t\t\t\t<context context-type=\"GID\">" + + xmlString((String) this.data.get("GID")) + + "</context>\n"); + if (isUsed((String) this.data.get("LID"))) + allLinesEnd.append("\t\t\t\t\t<context context-type=\"LID\">" + + xmlString((String) this.data.get("LID")) + + "</context>\n"); + if (isUsed((String) this.data.get("HID"))) + allLinesEnd.append("\t\t\t\t\t<context context-type=\"HID\">" + + xmlString((String) this.data.get("HID")) + + "</context>\n"); + if (isUsed((String) this.data.get("Platform"))) + allLinesEnd + .append("\t\t\t\t\t<context context-type=\"Platform\">" + + xmlString((String) this.data.get("Platform")) + + "</context>\n"); + if (isUsed((String) this.data.get("Width"))) + allLinesEnd.append("\t\t\t\t\t<context context-type=\"Width\">" + + xmlString((String) this.data.get("Width")) + + "</context>\n"); + allLinesEnd.append("\t\t\t\t</context-group>\n" + + "\t\t\t</trans-unit>\n"); + + writeBuffer.append("\t\t\t<trans-unit id=\"" + + this.data.get("BlockNr") + ":" + parts + "\" restype=\"" + + sRessource + "\" translate=\"yes\">\n"); + if (isUsed((String) this.data.get("SourceText"))) + writeBuffer.append("\t\t\t\t<source xml:lang=\"" + + languageResolver.getRFCFromISO((String)this.data.get("SourceLanguageID")) + "\">" + + DirtyTagWrapper.wrapString((String) this.data.get("SourceText")) + + "</source>\n"); + + if (isUsed((String) this.data.get("TargetText"))) + writeBuffer + .append("\t\t\t\t<target state=\"to_translate\" xml:lang=\"" + + languageResolver.getRFCFromISO((String)this.data.get("TargetLanguageID")) + + "\">" + +DirtyTagWrapper.wrapString((String) this.data + .get("TargetText")) + "</target>\n"); + writeBuffer.append(allLinesEnd); + Converter.countLine(); + + } + // if(!(this.data.get("SourceHText").equals("")||this.data.get("SourceHText").equals(" + // "))){ + // sRessource="res-Help"; //Source is Help + // //sLineNumber=String.valueOf(iLineNumber);// + // writeBuffer.append("\t\t<trans-unit + // id=\""+this.data.get("BlockNr")+":"+parts+"\" + // restype=\""+sRessource+"\" translate=\"yes\">\n");//always translate + // if(isUsed((String)this.data.get("SourceHText"))) + // writeBuffer.append("\t\t\t<source + // xml:lang=\""+this.data.get("SourceLanguageID")+"\">"+xmlString((String)this.data.get("SourceHText"))+"</source>\n"); + // if(isUsed((String)this.data.get("TargetHText"))) + // writeBuffer.append("\t\t\t<target state=\"to_translate\" + // xml:lang=\""+this.data.get("TargetLanguageID")+"\">"+xmlString((String)this.data.get("TargetHText"))+"</target>\n"); + // writeBuffer.append(allLinesEnd); + // Converter.countLine(); + // } + + if (!(this.data.get("SourceQText").equals("") || this.data.get( + "SourceQText").equals(" "))) { + sRessource = "res-QuickHelp"; // Source is OuickHelp + // sLineNumber=String.valueOf(iLineNumber);// + writeBuffer.append("\t\t\t<trans-unit id=\"" + + this.data.get("BlockNr") + ":" + parts + "\" restype=\"" + + sRessource + "\" translate=\"yes\">\n");// always translate + if (isUsed((String) this.data.get("SourceQText"))) + writeBuffer.append("\t\t\t\t<source xml:lang=\"" + + languageResolver.getRFCFromISO((String)this.data.get("SourceLanguageID")) + "\">" + + DirtyTagWrapper.wrapString((String) this.data.get("SourceQText")) + + "</source>\n"); + if (isUsed((String) this.data.get("TargetQText"))) + writeBuffer + .append("\t\t\t\t<target state=\"to_translate\" xml:lang=\"" + + languageResolver.getRFCFromISO((String)this.data.get("TargetLanguageID")) + + "\">" + + DirtyTagWrapper.wrapString((String) this.data + .get("TargetQText")) + "</target>\n"); + writeBuffer.append(allLinesEnd); + Converter.countLine(); + } + + if (!(this.data.get("SourceTitle").equals("") || this.data.get( + "SourceTitle").equals(" "))) { + sRessource = "res-Title"; // Source is Title + + writeBuffer.append("\t\t\t<trans-unit id=\"" + + this.data.get("BlockNr") + ":" + parts + "\" restype=\"" + + sRessource + "\" translate=\"yes\">\n");// always translate + if (isUsed((String) this.data.get("SourceTitle"))) + writeBuffer.append("\t\t\t\t<source xml:lang=\"" + + languageResolver.getRFCFromISO((String)this.data.get("SourceLanguageID")) + "\">" + + DirtyTagWrapper.wrapString((String) this.data.get("SourceTitle")) + + "</source>\n"); + if (isUsed((String) this.data.get("TargetTitle"))) + writeBuffer + .append("\t\t\t\t<target state=\"to_translate\" xml:lang=\"" + + languageResolver.getRFCFromISO((String)this.data.get("TargetLanguageID")) + + "\">" + + DirtyTagWrapper.wrapString((String) this.data + .get("TargetTitle")) + "</target>\n"); + writeBuffer.append(allLinesEnd); + Converter.countLine(); + } + this.write(writeBuffer.toString()); + }catch(Exception e){ + OutputHandler.log(e.getMessage()); + } + } + + /** + * Create the XLIFFFiles Header + * + * @return the header as string + * @throws java.io.UnsupportedEncodingException + */ + private String getHeader() throws java.io.UnsupportedEncodingException { + return new String( + (getProcessingInstructionTag() + getDTDLine() + + openVersionLine() + openFileLine() + getHeaderTag() + openBodyTag()) + .getBytes(), "UTF8"); + + } + + /** + * Create the XLIFFFiles Trailer + * + * @return the trailer as string + */ + private String getTrailer() { + return closeBodyTag() + closeFileLine() + closeVersionLine(); + } + + /** + * Create the Processing Instruction Tag used by this XLIFFFile + * @return the Processing Instruction Tag used by this XLIFFFile + */ + private String getProcessingInstructionTag() { + String sPITagStart = "<?"; + String sPIName = "xml "; + String sPIVersion = "version=\"1.0\" "; + String sPIEncoding = "encoding=\"UTF-8\""; + String sPITagEnd = "?>"; + return sPITagStart + sPIName + sPIVersion + sPIEncoding + + /* sPIStandalone+ */sPITagEnd + '\n'; + } + + /** + * Create the line holding the DTD referenced by this XLIFFFile + * @return a string holding the DTD referenced by this XLIFFFile + */ + private String getDTDLine() { + String sDTDTagStart = "<!DOCTYPE "; + String sDTDType = "xliff "; + String sDTDSource = "PUBLIC \"-//XLIFF//DTD XLIFF//EN\" \"http://www.oasis-open.org/committees/xliff/documents/xliff.dtd\">";// http://www.oasis-open.org/committees/xliff/documents/ + String sDTSTagEnd = ">"; + return sDTDTagStart + sDTDType + sDTDSource + '\n'; + } + + /** + * Create the beginning of the line holding the version of this XIFFFile + * + * @return a string with the beginning of the line holding the version of this XIFFFile + */ + private String openVersionLine() { + return "<xliff version=\"1.0\">\n"; + } + /** + * Create the ending of the line holding the version of this XIFFFile + * + * @return a string with the ending of the line holding the version of this XIFFFile + */ + private String closeVersionLine() { + return "</xliff>"; + } + /** + * Create the beginning of the line holding the file tag of this XIFFFile + * + * @return a string with the beginning of the file tag of this XIFFFile + */ + private String openFileLine() { + + String FileTagStart = "\t<file"; + String FileDataType = " datatype=\"STAROFFICE\""; + String FileDate = " date=\"" + this.data.get("TimeStamp") + "\""; + String FileOriginal = " original=\"" + this.data.get("SourceFile") + + "\""; + String FileSourceLanguage=""; + String FileTargetLanguage=""; + try { + FileSourceLanguage = " source-language=\"" + + languageResolver.getRFCFromISO((String)this.data.get("SourceLanguageID")) + "\" "; + FileTargetLanguage = " target-language=\"" + + languageResolver.getRFCFromISO((String)this.data.get("TargetLanguageID")) + "\" "; + } catch (LanguageResolvingException e) { + OutputHandler.out(e.getMessage()); + } + String FileTagEnd = ">"; + return FileTagStart + FileDataType + FileDate + FileOriginal + + FileSourceLanguage + FileTargetLanguage + FileTagEnd; + + } + /** + * Create the ending of the line holding the file tag of this XIFFFile + * + * @return a string with the ending of the file tag of this XIFFFile + */ + private String closeFileLine() { + return "\t</file>"; + } + /** + * Create a String containing the header tag + * @return the String containing the header tag + */ + private String getHeaderTag() { + return "<header></header>\n"; + } + /** + * Create the begining of the line holding the body tag of this XIFFFile + * + * @return a string with the begining of the body tag of this XIFFFile + */ + private String openBodyTag() { + return "\t\t<body>\n"; + } + /** + * Create the ending of the line holding the body tag of this XIFFFile + * + * @return a string with the ending of the body tag of this XIFFFile + */ + private String closeBodyTag() { + return "\t\t</body>"; + } + + /* + * (non-Javadoc) + * + * @see com.sun.star.tooling.converter.DataWriter#writeData(java.util.Map[]) + */ + protected void writeData(Map[] data) throws IOException { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see com.sun.star.tooling.converter.DataWriter#getDataFrom(com.sun.star.tooling.converter.DataHandler) + */ + protected void getDataFrom(DataHandler handler) { } + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/converter/dtd/xliff.dtd b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/dtd/xliff.dtd new file mode 100755 index 000000000000..91262ec28204 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/converter/dtd/xliff.dtd @@ -0,0 +1,391 @@ +<!-- XLIFF + +Public Identifier: "-//XLIFF//DTD XLIFF//EN" + +History of modifications (latest first): + +Jul-14-2003 by YS: Added extype definition (was missing) +Jan-28-2003 by YS: Implemented fixes for resname +Jan-28-2002 by YS: Implemented fixes after OASIS TC spec revision +May-15-2001 by YS: Add phase-name to <trans-unit> and <bin-unit> +May-15-2001 by YS: Reverse id for <trans-unit> to required +Apr-19-2001 by YS: Enda+JohnR last changes +Apr-18-2001 by YS: Removed empty ATTLISTs +Apr-12-2001 by YS: Changed target* to target+ in trans-match +Apr-11-2001 by YS: Fixed DOCTYPE id +Apr-10-2001 by YS: Synchronize from conference call +Apr-05-2001 by YS: Synchronize with latest specs +Apr-04-2001 by YS: Synchronize with latest specs +Apr-03-2001 by YS: Added name in <prop-group> +Apr-02-2001 by YS: Implemented JR fixes +Mar-29-2001 by JC: fixes for xml:space and bin-unit +Mar-28-2001 by YS: First draft version + +--> + + +<!ENTITY % CodeContent "#PCDATA|sub" > +<!ENTITY % TextContent "#PCDATA|g|bpt|ept|ph|it|mrk|x|bx|ex" > + +<!ENTITY lt "&#60;" > +<!ENTITY amp "&#38;" > +<!ENTITY gt ">" > +<!ENTITY apos "'" > +<!ENTITY quot """ > + + +<!-- ***************************************************************** --> +<!-- Structural Elements --> +<!-- ***************************************************************** --> + +<!ELEMENT xliff (file)+ > +<!ATTLIST xliff + version CDATA #FIXED "1.0" + xml:lang CDATA #IMPLIED +> + +<!ELEMENT file (header,body) > +<!ATTLIST file + original CDATA #REQUIRED + source-language CDATA #REQUIRED + datatype CDATA #REQUIRED + tool CDATA #IMPLIED + date CDATA #IMPLIED + xml:space (default|preserve) "default" + ts CDATA #IMPLIED + category CDATA #IMPLIED + target-language CDATA #IMPLIED + product-name CDATA #IMPLIED + product-version CDATA #IMPLIED + build-num CDATA #IMPLIED +> +<!-- tool default = "manual" --> + + +<!ELEMENT header (skl?,phase-group?,(prop-group|glossary|reference|note|count-group)*) > + +<!ELEMENT skl (internal-file|external-file) > + +<!ELEMENT internal-file (#PCDATA) > +<!ATTLIST internal-file + form CDATA #IMPLIED + crc NMTOKEN #IMPLIED +> +<!-- text|base64 (text is default) --> + +<!ELEMENT external-file EMPTY > +<!ATTLIST external-file + href CDATA #REQUIRED + crc NMTOKEN #IMPLIED + uid NMTOKEN #IMPLIED +> + +<!ELEMENT glossary (internal-file|external-file) > + +<!ELEMENT reference (internal-file|external-file) > + +<!ELEMENT note (#PCDATA) > +<!ATTLIST note + xml:lang CDATA #IMPLIED + priority (1|2|3|4|5|6|7|8|9|10) "1" + from CDATA #IMPLIED +> + +<!ELEMENT prop-group (prop)+ > +<!ATTLIST prop-group + name CDATA #IMPLIED +> + +<!ELEMENT prop (#PCDATA) > +<!ATTLIST prop + prop-type CDATA #REQUIRED + xml:lang CDATA #IMPLIED +> + +<!ELEMENT context-group (context)+ > +<!ATTLIST context-group + name CDATA #REQUIRED + crc NMTOKEN #IMPLIED +> + +<!-- Processing instructions related to <context-group>: + +<?xliff-show-context-group name='value' ?> + +Indicates that any <context-group> element with a name set to 'value' should be +displayed to the end-user. + +--> + +<!ELEMENT context (#PCDATA) > +<!ATTLIST context + context-type CDATA #REQUIRED + match-mandatory (yes|no) "no" + crc NMTOKEN #IMPLIED +> + +<!-- Processing instructions related to <context>: + +<?xliff-show-context context-type='value' ?> + +Indicates that any <context> element with a context-type set to 'value' should +be displayed to the end-user. + +--> + +<!ELEMENT phase-group (phase)+ > + +<!ELEMENT phase (note)* > +<!ATTLIST phase + phase-name CDATA #REQUIRED + process-name CDATA #REQUIRED + company-name CDATA #IMPLIED + tool CDATA #IMPLIED + date CDATA #IMPLIED + job-id CDATA #IMPLIED + contact-name CDATA #IMPLIED + contact-email CDATA #IMPLIED + contact-phone CDATA #IMPLIED +> + +<!ELEMENT count-group (count)* > +<!ATTLIST count-group + name CDATA #REQUIRED +> + +<!ELEMENT count (#PCDATA) > +<!ATTLIST count + count-type CDATA #IMPLIED + unit CDATA #IMPLIED +> + +<!ELEMENT body (group|trans-unit|bin-unit)* > + +<!ELEMENT group ((context-group*,count-group*,prop-group*,note*),(group|trans-unit|bin-unit)*) +> +<!ATTLIST group + id NMTOKEN #IMPLIED + datatype CDATA #IMPLIED + xml:space (default|preserve) "default" + ts CDATA #IMPLIED + restype CDATA #IMPLIED + resname CDATA #IMPLIED + extradata CDATA #IMPLIED + extype CDATA #IMPLIED + help-id NMTOKEN #IMPLIED + menu CDATA #IMPLIED + menu-option CDATA #IMPLIED + menu-name CDATA #IMPLIED + coord CDATA #IMPLIED + font CDATA #IMPLIED + css-style CDATA #IMPLIED + style NMTOKEN #IMPLIED + exstyle NMTOKEN #IMPLIED +> + +<!ELEMENT trans-unit (source,target?,(count-group|note|context-group|prop-group|alt-trans)*) > +<!ATTLIST trans-unit + id NMTOKEN #REQUIRED + approved (yes|no) #IMPLIED + translate (yes|no) "yes" + reformat (yes|no) "yes" + xml:space (default|preserve) "default" + datatype CDATA #IMPLIED + ts CDATA #IMPLIED + restype CDATA #IMPLIED + resname CDATA #IMPLIED + extradata CDATA #IMPLIED + extype CDATA #IMPLIED + help-id NMTOKEN #IMPLIED + menu CDATA #IMPLIED + menu-option CDATA #IMPLIED + menu-name CDATA #IMPLIED + coord CDATA #IMPLIED + font CDATA #IMPLIED + css-style CDATA #IMPLIED + style NMTOKEN #IMPLIED + exstyle NMTOKEN #IMPLIED + size-unit CDATA #IMPLIED + maxwidth NMTOKEN #IMPLIED + minwidth NMTOKEN #IMPLIED + maxheight NMTOKEN #IMPLIED + minheight NMTOKEN #IMPLIED + maxbytes NMTOKEN #IMPLIED + minbytes NMTOKEN #IMPLIED + charclass CDATA #IMPLIED + phase-name CDATA #IMPLIED +> +<!-- size-unit: char|byte|pixel|glyph|dlgunit default='pixel' --> + +<!ELEMENT source (%TextContent;)* > +<!ATTLIST source + xml:lang CDATA #IMPLIED + ts CDATA #IMPLIED +> +<!-- coord = "x;y;cx;cy" + font= "fontname[;size[;weight]]" +--> + +<!ELEMENT target (%TextContent;)* > +<!ATTLIST target + state NMTOKEN #IMPLIED + phase-name NMTOKEN #IMPLIED + xml:lang CDATA #IMPLIED + ts CDATA #IMPLIED + restype CDATA #IMPLIED + resname CDATA #IMPLIED + coord CDATA #IMPLIED + font CDATA #IMPLIED + css-style CDATA #IMPLIED + style NMTOKEN #IMPLIED + exstyle NMTOKEN #IMPLIED +> + +<!ELEMENT alt-trans (source?,target+,(note|context-group|prop-group)*) > +<!ATTLIST alt-trans + match-quality CDATA #IMPLIED + tool CDATA #IMPLIED + crc NMTOKEN #IMPLIED + xml:lang CDATA #IMPLIED + origin CDATA #IMPLIED + datatype CDATA #IMPLIED + xml:space (default|preserve) "default" + ts CDATA #IMPLIED + restype CDATA #IMPLIED + resname CDATA #IMPLIED + extradata CDATA #IMPLIED + extype CDATA #IMPLIED + help-id NMTOKEN #IMPLIED + menu CDATA #IMPLIED + menu-option CDATA #IMPLIED + menu-name CDATA #IMPLIED + coord CDATA #IMPLIED + font CDATA #IMPLIED + css-style CDATA #IMPLIED + style NMTOKEN #IMPLIED + exstyle NMTOKEN #IMPLIED +> + + +<!ELEMENT bin-unit (bin-source,bin-target?,(note|context-group|prop-group|trans-unit)*) > +<!ATTLIST bin-unit + id NMTOKEN #REQUIRED + mime-type NMTOKEN #REQUIRED + approved (yes|no) #IMPLIED + translate (yes|no) "yes" + reformat (yes|no) "yes" + ts CDATA #IMPLIED + restype CDATA #IMPLIED + resname CDATA #IMPLIED + phase-name CDATA #IMPLIED +> + +<!ELEMENT bin-source (internal-file|external-file) > +<!ATTLIST bin-source + ts CDATA #IMPLIED +> + +<!ELEMENT bin-target (internal-file|external-file) > +<!ATTLIST bin-target + mime-type NMTOKEN #IMPLIED + ts CDATA #IMPLIED + state NMTOKEN #IMPLIED + phase-name NMTOKEN #IMPLIED + restype CDATA #IMPLIED + resname CDATA #IMPLIED +> + + + +<!-- ***************************************************************** --> +<!-- In-Line Elements --> +<!-- ***************************************************************** --> + +<!ELEMENT g (%TextContent;)* > +<!ATTLIST g + id CDATA #REQUIRED + ctype CDATA #IMPLIED + clone (yes|no) "yes" + ts CDATA #IMPLIED +> + +<!ELEMENT x EMPTY > +<!ATTLIST x + id CDATA #REQUIRED + ctype CDATA #IMPLIED + clone (yes|no) "yes" + ts CDATA #IMPLIED +> + +<!ELEMENT bx EMPTY > +<!ATTLIST bx + id CDATA #REQUIRED + rid NMTOKEN #IMPLIED + ctype CDATA #IMPLIED + clone (yes|no) "yes" + ts CDATA #IMPLIED +> + +<!ELEMENT ex EMPTY > +<!ATTLIST ex + id CDATA #REQUIRED + rid NMTOKEN #IMPLIED + ts CDATA #IMPLIED +> + +<!ELEMENT ph (%CodeContent;)* > +<!ATTLIST ph + id CDATA #REQUIRED + ctype CDATA #IMPLIED + ts CDATA #IMPLIED + crc NMTOKEN #IMPLIED + assoc CDATA #IMPLIED +> + +<!ELEMENT bpt (%CodeContent;)* > +<!ATTLIST bpt + id CDATA #REQUIRED + rid NMTOKEN #IMPLIED + ctype CDATA #IMPLIED + ts CDATA #IMPLIED + crc NMTOKEN #IMPLIED +> + +<!ELEMENT ept (%CodeContent;)* > +<!ATTLIST ept + id CDATA #REQUIRED + rid NMTOKEN #IMPLIED + ts CDATA #IMPLIED + crc NMTOKEN #IMPLIED +> + +<!ELEMENT it (%CodeContent;)* > +<!ATTLIST it + id CDATA #REQUIRED + pos (open|close) #REQUIRED + rid NMTOKEN #IMPLIED + ctype CDATA #IMPLIED + ts CDATA #IMPLIED + crc NMTOKEN #IMPLIED +> + +<!ELEMENT mrk (%TextContent;)* > +<!ATTLIST mrk + mtype CDATA #REQUIRED + mid NMTOKEN #IMPLIED + comment CDATA #IMPLIED + ts CDATA #IMPLIED +> + +<!ELEMENT sub (%TextContent;)* > +<!ATTLIST sub + datatype CDATA #IMPLIED + ctype CDATA #IMPLIED +> + + + +<!-- ***** End of DTD ************************************************ --> + + + diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/languageResolver/LanguageResolver.java b/transex3/java/l10nconv/java/com/sun/star/tooling/languageResolver/LanguageResolver.java new file mode 100755 index 000000000000..62ff008156ab --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/languageResolver/LanguageResolver.java @@ -0,0 +1,201 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: LanguageResolver.java,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +/* + * Created on 2005 + * by Christian Schmidt + */ +package com.sun.star.tooling.languageResolver; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.ListIterator; + +/** + * Translate language codes into another format + * between ISO, RFC3066 and numeric + * + * @author Christian Schmidt 2005 + * + */ +public class LanguageResolver { + private final static int ISO =2; + private final static int LANGID =0; + private final static int LANGNAME =1; + private final static int RFC3066 =3; + + ArrayList languages=new ArrayList(); + +// public static void main(String[] args){ +// try { +// LanguageResolver lr=new LanguageResolver(); +// } catch (IOException e) { +// // +// e.printStackTrace(); +// } +// } + + /** + * Create a new Instance of LanguageResolver + * + * @throws IOException + */ + public LanguageResolver() throws IOException{ + String lang = "com/sun/star/tooling/languageResolver/lang.map"; + ClassLoader cl = this.getClass().getClassLoader(); + InputStream in = cl.getResourceAsStream(lang); + BufferedReader languageTable= new BufferedReader(new InputStreamReader(in)); + + String line; + + while((line=(languageTable.readLine()))!=null){ + languages.add(line.split(",")); + } + } + /** + * Get the numeric value of the given ISO Language Code + * + * @param isoCode the ISO Language Code to find + * @return numeric value of the given isoCode + * @throws LanguageResolvingException if the Language ISO Code is not known + */ + public String getNrFromISO(String isoCode) throws LanguageResolvingException{ + if("".equals(isoCode)) return ""; + ListIterator iter=languages.listIterator(); + String[] line=new String[5]; + while(isoCode!="" && iter.hasNext()){ + line=(String[]) iter.next(); + if(line[ISO].equals(isoCode)) return line[LANGID]; + } + throw new LanguageResolvingException("Can not find ISO Code: "+isoCode ); + + } + + /** + * Get the ISO Language Code corresponding with the given Language ID + * + * @param ID the numeric language id to find + * @return the ISO Language Code corresponding with the given Language ID + * @throws LanguageResolvingException if the Language ID is not known + */ + public String getISOfromNr(String ID) throws LanguageResolvingException{ + if("".equals(ID)) return ""; + ListIterator iter=languages.listIterator(); + String[] line=new String[5]; + while(iter.hasNext()){ + line=(String[]) iter.next(); + if(line[LANGID].equals(ID)) return line[ISO]; + } + throw new LanguageResolvingException("Can not find Language Id: "+ID ); + } + + /** + * Get the RFC3066 value of the given ISO Language Code + * + * @param isoCode the ISO Language Code to find + * @return RFC3066 value of the given isoCode + * @throws LanguageResolvingException if the Language ISO Code is not known + */ + public String getRFCFromISO(String isoCode) throws LanguageResolvingException{ + if("".equals(isoCode)) return ""; + ListIterator iter=languages.listIterator(); + String[] line=new String[5]; + while(iter.hasNext()){ + line=(String[]) iter.next(); + if(line[ISO].equals(isoCode)) return line[RFC3066]; + } + throw new LanguageResolvingException("Can not find ISO Code: "+isoCode ); + } + + /** + * Get the ISO Language Code corresponding with the given RFC3066 code + * + * @param RFC RFC3066 language id to find + * @return the ISO Language Code corresponding with the given RFC3066 code + * @throws LanguageResolvingException if the RFC3066 code is not known + */ + public String getISOFromRFC(String RFC) throws LanguageResolvingException{ + if("".equals(RFC)) return ""; + ListIterator iter=languages.listIterator(); + String[] line=new String[5]; + while(iter.hasNext()){ + line=(String[]) iter.next(); + if(line[RFC3066].equals(RFC)) return line[ISO]; + } + throw new LanguageResolvingException("Can not find Language Id: "+RFC ); + } + + + /** + * This Exception is thrown if a Language Identfier is unknown + * + * @author Christian Schmidt 2005 + * + */ + public class LanguageResolvingException extends Exception { + + /** + * + */ + public LanguageResolvingException() { + super(); + // + } + + /** + * @param arg0 + */ + public LanguageResolvingException(String arg0) { + super(arg0); + // + } + + /** + * @param arg0 + * @param arg1 + */ + public LanguageResolvingException(String arg0, Throwable arg1) { + super(arg0, arg1); + // + } + + /** + * @param arg0 + */ + public LanguageResolvingException(Throwable arg0) { + super(arg0); + // + } + + } + +} diff --git a/transex3/java/l10nconv/java/com/sun/star/tooling/languageResolver/lang.map b/transex3/java/l10nconv/java/com/sun/star/tooling/languageResolver/lang.map new file mode 100755 index 000000000000..a43e8f5e0218 --- /dev/null +++ b/transex3/java/l10nconv/java/com/sun/star/tooling/languageResolver/lang.map @@ -0,0 +1,41 @@ +1,English,en-US,en-US,1033 +3,Portuguese,pt,pt-PT,2070 +30,Greek,el,el-GR,1032 +33,French,fr,fr-FR,1036 +35,Finnish,fi,fi-FI,1035 +39,Italian,it,it-IT,1040 +43,Slowak,sk,sk-SK,1051 +46,Swedish,sv,sv-SE,1053 +48,Polish,pl,pl-PL,1045 +55,Portuguese (Brasil),pt-BR,pt-BR,2070 +82,Korean,ko,ko-KR,1042 +88,Chinese (traditional),zh-TW,zh-TW,1028 +96,Arabic,ar,,1025 +97,Hebrew,he,he-IL,1037 +7,Russian,ru,ru-RU,1049 +31,Dutch,nl,nl-NL,1043 +34,Spanish,es,es-ES,1034 +36,Hungarian,hu,hu-HU,1038 +42,Czech,cs,cs-CZ,1029 +45,Danish,da,da-DK,1030 +47,Norwegian (Bokmal),nb,nb-NB,1044 +49,German,de,de-DE,1031 +81,Japanese,ja,ja-JP,1041 +86,Chinese (simple),zh-CN,zh-CN,2052 +90,Turkish,tr,tr-TR,1055 +37,Catalan,ca,, +66,Thai,th,th-TH, +91,Hindi,hi-IN,hi-IN, +77,Estonian,et,et, +50,Slovenian,sl,sl, +79,Norwegian Nynorsk,nn,nn-NN, +53,Welsh,cy,cy, +27,Afrikaans,af,af-ZA, +38,Galician,gl-ES,gl-ES, +58,Lithuanian,lt,lt-LT, +29,Tswana,tn,tn-TN, +76,Khmer ( Cambodia ),km,km, +26,Northern Sotho,ns,ns-ZA, +28,Zulu,zu,zu-ZA, +10,Basque,eu,eu-ES, +93,Kannada,kn,kn-KN,
\ No newline at end of file diff --git a/transex3/java/l10nconv/makefile.mk b/transex3/java/l10nconv/makefile.mk new file mode 100755 index 000000000000..feb869778e80 --- /dev/null +++ b/transex3/java/l10nconv/makefile.mk @@ -0,0 +1,39 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=../.. +PRJNAME=transex3 +TARGET=converter + +.INCLUDE : ant.mk + +ALLTAR : ANTBUILD + diff --git a/transex3/java/receditor/build.xml b/transex3/java/receditor/build.xml new file mode 100755 index 000000000000..34f02128f034 --- /dev/null +++ b/transex3/java/receditor/build.xml @@ -0,0 +1,173 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2008 by Sun Microsystems, Inc. + + OpenOffice.org - a multi-platform office productivity suite + + $RCSfile: build.xml,v $ + + $Revision: 1.3 $ + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + +--> +<project name="receditor" default="main" basedir="."> + + <!-- ================================================================= --> + <!-- settings --> + <!-- ================================================================= --> + + <!-- name of this sub target used in recursive builds --> + <property name="target" value="receditor"/> + + <!-- name of jar file created, without .jar extension --> + <property name="jarname" value="receditor"/> + + <!-- relative path to project directory --> + <property name="prj" value="."/> + + <!-- build output directory --> + <property name="out" value="build"/> + + <!-- build directories --> + <property name="build.dir" value="${out}"/> + <property name="build.class" value="${build.dir}/class/receditor"/> + <property name="build.misc" value="${build.dir}/misc/receditor"/> + + <!-- start of java source code package structure --> + <property name="java.dir" value="java"/> + + <!-- define how to handle CLASSPATH environment --> + <property name="build.sysclasspath" value="ignore"/> + + <!-- classpath settings for compile and javadoc tasks --> + <path id="classpath"> + <pathelement location="."/> + <pathelement location="${build.class}"/> + </path> + + <!-- name to display in documentation --> + <!-- <property name="docname" value="l10n converter"/> --> + + <!-- set "modern" java compiler --> + <property name="build.compiler" value="modern"/> + + <!-- set wether we want to compile with debug information --> + <property name="debug" value="on"/> + + <!-- set wether we want to compile with optimisation --> + <property name="optimize" value="off"/> + + <!-- set wether we want to compile with or without deprecation --> + <property name="deprecation" value="on"/> + + <target name="info"> + <echo message="--------------------"/> + <echo message="${target}"/> + <echo message="--------------------"/> + </target> + + <!-- ================================================================= --> + <!-- custom targets --> + <!-- ================================================================= --> + + <!-- the main target, called in recursive builds --> + <target name="main" depends="info,prepare,compile,jar"/> + + <!-- prepare output directories --> + <target name="prepare"> + <mkdir dir="${build.dir}"/> + <mkdir dir="${build.class}"/> + <mkdir dir="${build.misc}"/> + </target> + + + <target name="res" depends="prepare"> + <copy todir="${build.class}"> + <fileset dir="${java.dir}"> + <include name="**/*.properties"/> + <include name="**/*.css"/> + <include name="**/*.dtd"/> + <include name="**/*.form"/> + <include name="**/*.gif "/> + <include name="**/*.htm"/> + <include name="**/*.html"/> + <include name="**/*.js"/> + <include name="**/*.mod"/> + <include name="**/*.sql"/> + <include name="**/*.xml"/> + <include name="**/*.xsl"/> + <include name="**/*.map"/> + + </fileset> + </copy> + </target> + + + <target name="compile" depends="prepare,res"> + <javac destdir="${build.class}" + debug="${debug}" + deprecation="${deprication}" + optimize="${optimize}" + classpathref="classpath"> + <src path="${java.dir}"/> + <include name="**/*.java"/> + </javac> + </target> + + <!-- clean up --> + <target name="clean" depends="prepare"> + <delete includeEmptyDirs="true"> + <fileset dir="${build.class}"> + <patternset> + <include name="${package}/**/*.class"/> + </patternset> + </fileset> + </delete> + </target> + + <!-- create jar file --> + <target name="jar" depends="prepare,compile" if="build.class"> + <jar jarfile="${build.class}/${jarname}.jar" + basedir="${build.class}" + manifest="${jarname}.MF"> + <include name="**/*.class"/> + <include name="**/*.properties"/> + <include name="**/*.css"/> + <include name="**/*.dtd"/> + <include name="**/*.form"/> + <include name="**/*.gif "/> + <include name="**/*.htm"/> + <include name="**/*.html"/> + <include name="**/*.js"/> + <include name="**/*.mod"/> + <include name="**/*.sql"/> + <include name="**/*.xml"/> + <include name="**/*.xsl"/> + <include name="**/*.map"/> + </jar> + </target> + + <target name="test" depends="prepare"> + </target> + +</project> + diff --git a/transex3/java/receditor/java/transex3/controller/EditorController.java b/transex3/java/receditor/java/transex3/controller/EditorController.java new file mode 100644 index 000000000000..38462d665304 --- /dev/null +++ b/transex3/java/receditor/java/transex3/controller/EditorController.java @@ -0,0 +1,334 @@ +package transex3.controller; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.Runtime; +import java.util.*; + +import javax.swing.ListSelectionModel; +import javax.swing.WindowConstants; +import javax.swing.event.*; + +import transex3.model.*; + +import java.io.*; +import javax.swing.*; +//import transex3.model.*; +public class EditorController { + public final String[] RESTYPES = { ".src",".hrc",".xcu",".xrm",".xhp" }; + public final String RECFILE = ".recommand"; + // Editor View + static transex3.view.Editor aEditor = null; + // Editor Model + static Vector sdfstrings = new Vector(); + static HashMap hashedsdfstrings = new HashMap(); + int oldindex = 0; + //HashMap hashedfilenames = new HashMap(); + // Search for source Strings + public String fetchSourceStrings( String rootdir ){ + + //String outputfile = "h:\\workspace\\recommandEditor\\null2"; + File tempfile = null; + + try { + tempfile = File.createTempFile( "receditor" , "tmp" ); + } catch (IOException e1) { + // TODO Auto-generated catch block + System.err.println("Can not create temp file\n"); + e1.printStackTrace(); + } + + String outputfile = tempfile.getAbsolutePath(); + try + { + //System.out.println("localize_sl -QQ -skip_links -e -l en-US -f "+outputfile+" -d "+rootdir); + System.out.println("localize_sl -QQ -skip_links -e -l en-US -f "+outputfile ); + java.lang.Process aProc = Runtime.getRuntime().exec("localize_sl -QQ -skip_links -e -l en-US -f "+outputfile); + + //java.lang.Process aProc = Runtime.getRuntime().exec("localize_sl -QQ -e -l en-US -f "+outputfile+" -d "+rootdir); + BufferedReader aBR = new BufferedReader( new InputStreamReader( aProc.getInputStream() ) ); + String line = aBR.readLine(); + while( line != null && line.length() > 0 ){ + //System.out.print( line ); + line = aBR.readLine(); + } + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return outputfile; + } + // Search for recommand files + public void findRecommandFiles( File rootdir , Vector list ){ + System.out.print("."); + System.out.flush(); + File[] aFileArray = rootdir.listFiles(); + if( aFileArray != null ){ + for( int cnt = 0; aFileArray.length > cnt ; cnt++ ){ + if( aFileArray[ cnt ].isDirectory() && !aFileArray[ cnt ].getAbsolutePath().endsWith(".lnk") ) + findRecommandFiles( aFileArray[ cnt ] , list); + else if( aFileArray[ cnt ].isFile() && isRecommandFile( aFileArray[ cnt ] ) ) + list.add( aFileArray[ cnt ]); + } + } + } + private boolean isResourceType( File aFile ){ + String filename = aFile.getName(); + boolean isResType = false; + for(int cnt = 0; cnt < RESTYPES.length ; cnt++){ + if( filename.endsWith( RESTYPES[ cnt ] ) ) + isResType = true; + } + return isResType; + } + private boolean isRecommandFile( File aFile ){ + return aFile.getName().endsWith( RECFILE ); + } + public void clearAllRows( JTable aTable ){ + for ( int n = 0; n < aTable.getRowCount() ; n++ ){ + aTable.setValueAt( null , n , 0 ); + aTable.setValueAt( null , n , 1 ); + aTable.setValueAt( null , n , 2 ); + aTable.setValueAt( null , n , 3 ); + aTable.setValueAt( null , n , 4 ); + } + } + // Add all data to view + void updateData(){ + JTable recTable =transex3.controller.EditorController.aEditor.getRectable(); + + SdfString aSdfString = (SdfString) sdfstrings.get( oldindex ); + Vector newStrings = new Vector(); + for ( int n = 1; n < recTable.getRowCount() ; n++ ){ + String lang = (String) recTable.getValueAt(n , 0 ); + String text = (String) recTable.getValueAt(n , 1 ); + String htext = (String) recTable.getValueAt(n , 2 ); + String qhtext = (String) recTable.getValueAt(n , 3 ); + String ttext = (String) recTable.getValueAt(n , 4 ); + if( lang != null && text != null ){ + //System.out.println("Data "+ lang + " " + text ); + SdfEntity aSdfEntity = new SdfEntity(); + aSdfEntity.setLangid( lang ); + aSdfEntity.setText( text ); + aSdfEntity.setHelptext( htext ); + aSdfEntity.setQuickhelptext( qhtext ); + aSdfEntity.setTitle( ttext ); + newStrings.add( aSdfEntity ); + aSdfString.setLanguageStrings( newStrings ); + } + } + } + + public void initView(){ + Object[][] sourceStringData = new Object[ sdfstrings.size() ][ 4 ]; + Object[][] firstData = new Object[100][5]; + // Set the files + Iterator aIter = sdfstrings.iterator(); + int counter = 0; + while( aIter.hasNext() ){ + SdfString aSdfString = (SdfString) aIter.next(); + sourceStringData[ counter ][ 0 ] = aSdfString.getSourceString().getProject()+"\\"+aSdfString.getSourceString().getSource_file(); + sourceStringData[ counter ][ 1 ] = aSdfString.getSourceString().getGid(); + sourceStringData[ counter ][ 2 ] = aSdfString.getSourceString().getLid(); + sourceStringData[ counter ][ 3 ] = aSdfString.getSourceString().getText(); + if( counter == 0 ){ + firstData[ 0 ][ 0 ] = "en-US"; + firstData[ 0 ][ 1 ] = aSdfString.getSourceString().getText(); + firstData[ 0 ][ 2 ] = aSdfString.getSourceString().getHelptext(); + firstData[ 0 ][ 3 ] = aSdfString.getSourceString().getQuickhelptext(); + firstData[ 0 ][ 4 ] = aSdfString.getSourceString().getTitle(); + aSdfString = (SdfString) sdfstrings.get( 0 ); + Vector values = aSdfString.getLanguageStrings(); + for( int n = 0; n < values.size() ; n++ ) + { + SdfEntity aEntity = (SdfEntity) values.get( n ); + firstData[ n+1 ][ 0 ] = aEntity.getLangid(); + firstData[ n+1 ][ 1 ] = aEntity.getText(); + firstData[ n+1 ][ 2 ] = aEntity.getHelptext(); + firstData[ n+1 ][ 3 ] = aEntity.getQuickhelptext(); + firstData[ n+1 ][ 4 ] = aEntity.getTitle(); + } + } + counter++; + } + // Set the source srtings + + + //aEditor = new transex3.view.Editor( sourceStringData , filedata.toArray() ); + aEditor = new transex3.view.Editor( sourceStringData , firstData ); + + aEditor.setBounds(100,100,800,900); + aEditor.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); + aEditor.setVisible(true); + aEditor.repaint(); + aEditor.addWindowListener( new WindowAdapter(){ + public void windowClosed(WindowEvent e ){ + System.exit( 0 ); + } + }); + + aEditor.getMiExit().addActionListener( new ActionListener(){ + public void actionPerformed( ActionEvent e ){ + System.exit( 0 ); + } + }); + + aEditor.getMiSave().addActionListener( new ActionListener(){ + public void actionPerformed( ActionEvent e ){ + Iterator aIter = sdfstrings.iterator(); + String lastFile=""; + while( aIter.hasNext() ) + { + SdfString aSdfString = (SdfString )aIter.next(); + if( aSdfString.getFileId().compareTo( lastFile ) != 0 ){ + //aSdfString.removeFile(); + } + aSdfString.writeString(); + lastFile = aSdfString.getFileId(); + } + } + }); + + //aEditor.getRectable().putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); + aEditor.getRectable().addFocusListener( new FocusListener(){ + public void focusLost(FocusEvent e){ + //super.focusLost( e ); + //System.out.println("focus lost"); + JTable aTable = aEditor.getRectable(); + if( aTable.getSelectedRow() != -1 && aTable.getSelectedColumn() != -1 ) + aTable.getCellEditor( aTable.getSelectedRow(), aTable.getSelectedColumn() ).stopCellEditing(); + updateData(); + } + public void focusGained( FocusEvent e){ + //super.focusGained( e ); + //System.out.println("focus gained"); + } + }); + //setDefaultEditor(Object.class, new transex3.view.FocusCellEditor(new JTextField())); + + aEditor.getRectable().getModel().addTableModelListener( new TableModelListener() { + public void tableChanged( TableModelEvent e ){ + //System.out.println( e ); + }}); + + + aEditor.getRectable().getSelectionModel().addListSelectionListener( new ListSelectionListener(){ + public void valueChanged( ListSelectionEvent e ){ + JTable aTable = aEditor.getRectable(); + //if( aTable.getSelectedRow() != -1 && aTable.getSelectedColumn() != -1 ) + //aTable.getCellEditor( aTable.getSelectedRow(), aTable.getSelectedColumn() ).stopCellEditing(); + + updateData(); + } + }); + + aEditor.getTable().setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); + aEditor.getTable().getSelectionModel().addListSelectionListener( new ListSelectionListener(){ + public void valueChanged( ListSelectionEvent e ){ + //System.out.println("Selected = " +e.getFirstIndex()+"\n"); + JTable table =transex3.controller.EditorController.aEditor.getTable(); + JTable recTable =transex3.controller.EditorController.aEditor.getRectable(); + SdfString aSdfString; + JTable aTable = aEditor.getRectable(); + if( aTable.getSelectedRow() != -1 && aTable.getSelectedColumn() != -1 ) + aTable.getCellEditor( aTable.getSelectedRow(), aTable.getSelectedColumn() ).stopCellEditing(); + + updateData(); + clearAllRows( recTable ); + + aSdfString = (SdfString) sdfstrings.get( table.getSelectedRow() ); + recTable.setValueAt( "en-US" , 0, 0 ); + recTable.setValueAt( aSdfString.getSourceString().getText() , 0, 1 ); + recTable.setValueAt( aSdfString.getSourceString().getHelptext() , 0, 2 ); + recTable.setValueAt( aSdfString.getSourceString().getQuickhelptext() , 0, 3 ); + recTable.setValueAt( aSdfString.getSourceString().getTitle() , 0, 4 ); + Vector values = aSdfString.getLanguageStrings(); + for( int n = 0; n < values.size() ; n++ ) + { + SdfEntity aEntity = (SdfEntity) values.get( n ); + recTable.setValueAt( aEntity.getLangid() , n+1 , 0 ); + recTable.setValueAt( aEntity.getText() , n+1 , 1 ); + recTable.setValueAt( aEntity.getHelptext() , n+1 , 2 ); + recTable.setValueAt( aEntity.getQuickhelptext() , n+1 , 3 ); + recTable.setValueAt( aEntity.getTitle() , n+1 , 4 ); + } + oldindex = table.getSelectedRow(); + } + }); + //System.out.println("initView successfully"); + } + public void initInitialStrings(){ + String rootdir = java.lang.System.getProperty("SOLARSRC"); + String sourcestringsfile = null; + Vector recList = new Vector(); + sourcestringsfile = fetchSourceStrings( rootdir ); + //findRecommandFiles( new File( rootdir ) , recList ); + readStrings( sourcestringsfile , recList ); + File sfile = new File ( sourcestringsfile ); + sfile.delete(); + initView(); + aEditor.repaint(); + } + // Connect recommand strings with source strings + public void readStrings( String sourcefiles , Vector recfiles ) { + BufferedReader aBR = null; + try { + //System.out.println("DBG: sourcefiles = " +sourcefiles); + aBR = new BufferedReader( new FileReader( sourcefiles ) ); + String current = aBR.readLine(); + SdfString aSdfString = null; + SdfEntity aSdfEntity = null; + while( current != null ){ + aSdfEntity = new SdfEntity(); + aSdfEntity.setProperties( current ); + aSdfString = new SdfString(); + aSdfString.addSourceString( aSdfEntity ); + hashedsdfstrings.put( aSdfString.getId() , aSdfString ); + //System.out.println("Put ID '"+aSdfString.getId()+"'"); + sdfstrings.add( aSdfString ); + current = aBR.readLine(); + + } + Iterator aIter=recfiles.iterator(); + File aFile; + BufferedReader aBR2 = null; + //System.out.println("Connecting strings"); + while( aIter.hasNext() ){ + aFile = (File) aIter.next(); + aBR2 = new BufferedReader( new FileReader( aFile ) ) ; + String current2 = aBR2.readLine(); + + while ( current2 != null ){ + SdfEntity aEntity = new SdfEntity(); + aEntity.setProperties( current2 ); + + if( hashedsdfstrings.containsKey( aEntity.getId() ) ) + { + aSdfString = (SdfString) hashedsdfstrings.get( aEntity.getId() ); + aSdfString.addLanguageString( aEntity ); + } + else + { + System.out.println("DBG: Can't find source string '"+aEntity.getId()+"'" ); + } + current2 = aBR2.readLine(); + } + } + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch ( IOException e){ + e.printStackTrace(); + } + + } +} diff --git a/transex3/java/receditor/java/transex3/controller/Main.java b/transex3/java/receditor/java/transex3/controller/Main.java new file mode 100644 index 000000000000..e8dd06ce9f85 --- /dev/null +++ b/transex3/java/receditor/java/transex3/controller/Main.java @@ -0,0 +1,10 @@ +package transex3.controller; + +public class Main { + + public static void main( String args[] ){ + EditorController aEditor = new EditorController(); + aEditor.initInitialStrings(); + } +} + diff --git a/transex3/java/receditor/java/transex3/model/ResourceFile.java b/transex3/java/receditor/java/transex3/model/ResourceFile.java new file mode 100644 index 000000000000..51fabb3a4b7a --- /dev/null +++ b/transex3/java/receditor/java/transex3/model/ResourceFile.java @@ -0,0 +1,77 @@ +package transex3.model; + +import java.util.*; + +public class ResourceFile { + Vector sdfStrings = new Vector(); + HashMap sdfHashMap = new HashMap(); + String filepathid = null; + String modulename = null; + String filename = null; + + + public String getModuleName(){ + return modulename; + } + public String getFilePath(){ + return filepathid; + } + public String getFileName(){ + return filename; + } +/* public List readSoureStrings( java.io.File aSdfFile ){ + List sdfList=null; + return sdfList; + };*/ + public void addString( SdfString aSdfstring ){ + sdfStrings.add( aSdfstring ); + sdfHashMap.put( aSdfstring.getFileId() , aSdfstring ); + if( filepathid == null ) + filepathid = aSdfstring.getFilePath(); + if( modulename == null ) + modulename = aSdfstring.getModuleName(); + if( filename == null ) + filename = aSdfstring.getFileName(); + } + + + public void ParseString( String aSourceString ){ + //sourceString = new SdfEntity(); + SdfEntity aSdfEntity = new SdfEntity(); + aSdfEntity.setProperties( aSourceString ); + SdfString sdfstring = null; + if( sdfHashMap.containsKey( aSdfEntity.getFileId() ) ){ + sdfstring = (SdfString) sdfHashMap.get( aSdfEntity.getFileId() ); + } + else + { + sdfstring = new SdfString(); + addString( sdfstring ); + } + sdfstring.addLanguageString( aSdfEntity ); + + + } + /*public void ParseSdfFile( java.util.Vector aSdfList ){ + ListIterator aLI = aSdfList.listIterator(); + String current; + String[] splitted; + SdfEntity aSdfEntity; + SdfString aSdfString = new SdfString(); + while( aLI.hasNext() ){ + aSdfEntity = new SdfEntity(); + aSdfEntity.setProperties( (String) aLI.next() ); + SdfString aString; + + if( sdfHashMap.containsKey( aSdfEntity.getFileId() ) ) + aString = (SdfString) sdfHashMap.get( aSdfEntity.getFileId() ); + else + { + aString = new SdfString(); + addString( aString ); + } + aString.addLanguageString( aSdfEntity ); + } + + }*/ +} diff --git a/transex3/java/receditor/java/transex3/model/SdfEntity.java b/transex3/java/receditor/java/transex3/model/SdfEntity.java new file mode 100644 index 000000000000..4b293421fd28 --- /dev/null +++ b/transex3/java/receditor/java/transex3/model/SdfEntity.java @@ -0,0 +1,211 @@ +package transex3.model; + +public class SdfEntity { + private String project; + private String source_file; + private String dummy1; + private String resource_type; + private String gid; + private String lid; + private String helpid; + private String platform; + private String dummy2; + private String langid; + private String text; + private String helptext; + private String quickhelptext; + private String title; + private String date; + + public static int PROJECT_POS = 0; + public static int SOURCE_FILE_POS = 1; + public static int DUMMY1_POS = 2; + public static int RESOURCE_TYPE_POS = 3; + public static int GID_POS = 4; + public static int LID_POS = 5; + public static int HELPID_POS = 6; + public static int PLATFORM_POS = 7; + public static int DUMMY2_POS = 8; + public static int LANGID_POS = 9; + public static int TEXT_POS = 10; + public static int HELPTEXT_POS = 11; + public static int QUICKHELPTEXT_POS = 12; + public static int TITLE_POS = 13; + public static int DATE_POS = 14; + + public SdfEntity(){} + public SdfEntity(String project, String source_file, String dummy1, String resource_type, String gid, String lid, String helpid, String platform, String dummy2, String langid, String text, String helptext, String quickhelptext, String title , String date) { + super(); + this.project = project; + this.source_file = source_file; + this.dummy1 = dummy1; + this.resource_type = resource_type; + this.gid = gid; + this.lid = lid; + this.helpid = helpid; + this.platform = platform; + this.dummy2 = dummy2; + this.langid = langid; + this.text = text; + this.helptext = helptext; + this.quickhelptext = quickhelptext; + this.title = title; + this.date = date; + } + + public void setProperties( String line ){ + + String[] splitted = line.split("\t"); + + setProject( splitted[ SdfEntity.PROJECT_POS ] ); + setSource_file( splitted[ SdfEntity.SOURCE_FILE_POS ] ); + setDummy1( splitted[ SdfEntity.DUMMY1_POS ] ); + setResource_type( splitted[ SdfEntity.RESOURCE_TYPE_POS ] ); + setGid( splitted[ SdfEntity.GID_POS ] ); + setLid( splitted[ SdfEntity.LID_POS ] ); + setHelpid( splitted[ SdfEntity.HELPID_POS ] ); + setPlatform( splitted[ SdfEntity.PLATFORM_POS ] ); + setDummy2( splitted[ SdfEntity.DUMMY2_POS ] ); + setLangid( splitted[ SdfEntity.LANGID_POS ] ); + setText( splitted[ SdfEntity.TEXT_POS ] ); + setHelptext( splitted[ SdfEntity.HELPTEXT_POS ] ); + setQuickhelptext( splitted[ SdfEntity.QUICKHELPTEXT_POS ] ); + setTitle( splitted[ SdfEntity.TITLE_POS ] ); + setDate( splitted[ SdfEntity.DATE_POS ] ); + } + + public String getFileId(){ + return project+"\\"+source_file; + } + public String getResourcePath(){ + return source_file.substring(0 , source_file.lastIndexOf( "\\" )-1 ); + } + public String toString(){ + return project+"\t"+source_file+"\t"+dummy1+"\t"+resource_type+"\t"+gid+"\t" + +lid+"\t"+helpid+"\t"+platform+"\t"+dummy2+"\t"+langid+"\t" + +text+"\t"+helptext+"\t"+quickhelptext+"\t"+title+"\t"+date; + } + public String getId(){ + return project+gid+lid+source_file+resource_type+platform+helpid; + } + + public String getDummy1() { + return dummy1; + } + + public void setDummy1(String dummy1) { + this.dummy1 = dummy1; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getDummy2() { + return dummy2; + } + + public void setDummy2(String dummy2) { + this.dummy2 = dummy2; + } + + public String getGid() { + return gid; + } + + public void setGid(String gid) { + this.gid = gid; + } + + public String getHelpid() { + return helpid; + } + + public void setHelpid(String helpid) { + this.helpid = helpid; + } + + public String getHelptext() { + return helptext; + } + + public void setHelptext(String helptext) { + this.helptext = helptext; + } + + public String getLangid() { + return langid; + } + + public void setLangid(String langid) { + this.langid = langid; + } + + public String getLid() { + return lid; + } + + public void setLid(String lid) { + this.lid = lid; + } + + public String getProject() { + return project; + } + + public void setProject(String project) { + this.project = project; + } + + public String getQuickhelptext() { + return quickhelptext; + } + + public void setQuickhelptext(String quickhelptext) { + this.quickhelptext = quickhelptext; + } + + public String getResource_type() { + return resource_type; + } + + public void setResource_type(String resource_type) { + this.resource_type = resource_type; + } + + public String getSource_file() { + return source_file; + } + + public void setSource_file(String source_file) { + this.source_file = source_file; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + public String getDate() { + return date; + } + public void setDate(String date) { + this.date = date; + } + + +} diff --git a/transex3/java/receditor/java/transex3/model/SdfString.java b/transex3/java/receditor/java/transex3/model/SdfString.java new file mode 100644 index 000000000000..7419aeb5578b --- /dev/null +++ b/transex3/java/receditor/java/transex3/model/SdfString.java @@ -0,0 +1,192 @@ +package transex3.model; +import java.util.*; +import java.io.*; +public class SdfString { + private SdfEntity sourceString = null; + //private java.util.HashMap languageStrings = new HashMap(); + private Vector languageList = new Vector(); + private String id = null; + private String fileid = null; + private String filename = null; + private String modulename = null; + private String filepath = null; + + /*public HashMap getLanguageStrings() { + return languageStrings; + }*/ + public Vector getLanguageStrings() { + return languageList; + } + + public void setLanguageStrings(Vector languageStrings) { + this.languageList = languageStrings; + } + + public void addSourceString( SdfEntity aSdfEntity ) + { + if( id == null ) + id = aSdfEntity.getId(); + if ( fileid == null ) + fileid = aSdfEntity.getFileId(); + if( modulename == null ) + modulename = aSdfEntity.getProject(); + if( filename == null ) + filename = aSdfEntity.getSource_file(); + if( filepath == null ) + filepath = aSdfEntity.getResourcePath(); + setSourceString( aSdfEntity ); + } + public void addLanguageString( SdfEntity aSdfEntity ){ + if( !aSdfEntity.getLangid().equals( "en-US" ) ) + { + if( id == null ) + id = aSdfEntity.getId(); + if ( fileid == null ) + fileid = aSdfEntity.getFileId(); + if( modulename == null ) + modulename = aSdfEntity.getProject(); + if( filename == null ) + filename = aSdfEntity.getSource_file(); + if( filepath == null ) + filepath = aSdfEntity.getResourcePath(); + + //if( aSdfEntity.getLangid().equals( "en-US" ) ) + //{ + // setSourceString( aSdfEntity ); + //} + //else + //{ + //languageStrings.put( aSdfEntity.getLangid() , aSdfEntity ); + languageList.add( aSdfEntity ); + //} + id = aSdfEntity.getId(); + } + } + + public SdfEntity getSourceString() { + return sourceString; + } + + public void setSourceString(SdfEntity sourceString) { + this.sourceString = sourceString; + id = sourceString.getId(); + } + public String getFilePath(){ + return filepath; + } + public String getId(){ + //return id; + return sourceString.getId(); + } + public String getFileId(){ + return fileid; + } + + public String getFileName() { + return filename; + } + + public void setFileName(String filename) { + this.filename = filename; + } + + public String getModuleName() { + return modulename; + } + + public void setModuleName(String modulename) { + this.modulename = modulename; + } + /* + public String getRealFileName(){ + //String srcroot = "U:\\cws01\\l10ncleanup\\SRC680\\src.m213";//java.lang.System.getProperty( "SOLARSRC"); + //String isWindows = "4nt";//java.lang.System.getProperty( "USE_SHELL"); + String srcroot = java.lang.System.getProperty( "SOLARSRC" ); + String isWindows = java.lang.System.getProperty( "USE_SHELL" ); + + //System.out.println("srcroot="+srcroot+" isWindows="+isWindows ); + //if( true ) return; + //String relpath = sourceString.getFileId().substring( sourceString.getFileId().lastIndexOf("\\") + // , sourceString.getFileId().length() ); + String filename; + if( isWindows != null && isWindows.compareTo( "4nt") == 0 ) + { + filename = srcroot + "\\" + //sourceString.getProject() + "\\" + + sourceString.getFileId() +".recommand"; + } + else + { + String filepart = sourceString.getFileId(); + filepart = filepart.replaceAll( "\\\\" , "/" ); + filename = srcroot + "/" + //sourceString.getProject() + "//" + + filepart +".recommand"; + } + return filename; + }*/ + public String getRealFileName(){ + String filepart = sourceString.getFileId(); + filepart = filepart.replaceAll( "\\\\" , "_" ); + String filename = "/so/ws/merge/In/" + java.lang.System.getProperty( "WORK_STAMP" ) + "/" + filepart + ".sdf"; + return filename; + } + public void removeFile(){ + String filename = getRealFileName(); + File aFile = new File( filename ); + if( aFile.exists() ){ + if( ! aFile.delete() ) + { + System.out.println("Can't delete File "+filename+"\nWrong access rights?\n"); + } + } + } + public void writeString(){ + String filename = getRealFileName(); + try { + if( languageList.size() > 0 ) + { + System.out.print("\nWrite to "+filename ); + BufferedWriter aBW = new BufferedWriter( new FileWriter( filename , true) ); + aBW.write( sourceString + "\n" ); + Iterator aIter = languageList.iterator(); + while( aIter.hasNext() ){ + SdfEntity aEntity = (SdfEntity)aIter.next(); + aBW.write( sourceString.getProject()+"\t" ); + aBW.write( sourceString.getSource_file()+"\t" ); + aBW.write( sourceString.getDummy1()+"\t" ); + aBW.write( sourceString.getResource_type()+"\t" ); + aBW.write( sourceString.getGid()+"\t" ); + aBW.write( sourceString.getLid()+"\t" ); + aBW.write( sourceString.getHelpid()+"\t" ); + aBW.write( sourceString.getPlatform()+"\t" ); + aBW.write( sourceString.getDummy2()+"\t" ); + if( aEntity.getLangid() == null ) + aBW.write( "\t" ); + else + aBW.write( aEntity.getLangid()+"\t" ); + if( aEntity.getText() == null ) + aBW.write( "\t" ); + else + aBW.write( aEntity.getText()+"\t" ); + if( aEntity.getHelptext() == null ) + aBW.write( "\t" ); + else + aBW.write( aEntity.getHelptext()+"\t" ); + if( aEntity.getQuickhelptext() == null ) + aBW.write( "\t" ); + else + aBW.write( aEntity.getQuickhelptext()+"\t" ); + if( aEntity.getTitle() == null ) + aBW.write( "\t" ); + else + aBW.write( aEntity.getTitle()+"\t" ); + aBW.write( "2002-02-02 02:02:02\n" ); + } + aBW.close(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + //e.printStackTrace(); + System.out.println("\nERROR: Can't write to file '"+filename+"'\nPlease contact RE/Tooling!"); + } + } +} diff --git a/transex3/java/receditor/java/transex3/view/Editor.java b/transex3/java/receditor/java/transex3/view/Editor.java new file mode 100644 index 000000000000..f46a82a11a2b --- /dev/null +++ b/transex3/java/receditor/java/transex3/view/Editor.java @@ -0,0 +1,97 @@ +package transex3.view; +import javax.swing.*; +import java.awt.*; + +public class Editor extends JFrame{ + Object[] columnnames = { "File" , "GID" , "LID" , "String" }; + Object[] stringcolnames = { "Language", "Text", "Helptext" , "Quickhelptext","Title"}; + //Object[][] data = new Object[4][1];//{ { "a " }, { "v " }, { "v " } , { "a " } }; + JTable table = null; + JTable rectable = null; + JComboBox cBox = null; + JMenuBar menubar = null; + JMenu filemenu = null; + JMenuItem miNew = null; + JMenuItem miSave = null; + JMenuItem miExit = null; + //JButton button = null; + + public Editor( Object[][] tabledata , Object[][] firstdata ){ + table = new JTable( tabledata , columnnames ); + rectable = new SdfTable( firstdata , stringcolnames ); + menubar = new JMenuBar(); + filemenu = new JMenu("File"); + //miNew = new JMenuItem("New"); + miSave = new JMenuItem("Save"); + miExit = new JMenuItem("Exit"); + //button = new JButton("Edit"); + //filemenu.add( miNew ); + filemenu.add( miSave ); + filemenu.add( miExit ); + menubar.add( filemenu ); + + Container contentPane = getContentPane(); + //contentPane.add( new ControlPanel() , BorderLayout.NORTH ); + contentPane.add( menubar , BorderLayout.NORTH ); + //JPanel aPanel = new JPanel( new FlowLayout( FlowLayout.CENTER) ); + JPanel aPanel = new JPanel( new GridLayout( 2,1 ) ); + aPanel.add( new JScrollPane( table ) ); + aPanel.add( new JScrollPane( rectable ) ); + contentPane.add( aPanel , BorderLayout.CENTER ); + //contentPane.add( button , BorderLayout.SOUTH ); + //contentPane.add( new JScrollPane( table ), BorderLayout.CENTER ); + //contentPane.add( new JScrollPane( table ), BorderLayout.SOUTH ); + //contentPane.add( new JScrollPane( rectable ), BorderLayout.SOUTH ); + //contentPane.add( new JScrollPane( rectable ), BorderLayout.SOUTH ); + this.repaint(); + + } + + public JTable getRectable() { + return rectable; + } + + public void setRectable(JTable rectable) { + this.rectable = rectable; + } + + public JTable getTable() { + return table; + } + + public void setTable(JTable table) { + this.table = table; + } + + /*public JButton getButton() { + return button; + } + + public void setButton(JButton button) { + this.button = button; + }*/ + + public JMenuItem getMiExit() { + return miExit; + } + + public void setMiExit(JMenuItem miExit) { + this.miExit = miExit; + } + + public JMenuItem getMiSave() { + return miSave; + } + + public void setMiSave(JMenuItem miSave) { + this.miSave = miSave; + } + + /*public void setTableData(){ + + }*/ + +} + +//class ControlPanel extends JPanel{} + diff --git a/transex3/java/receditor/java/transex3/view/SdfTable.java b/transex3/java/receditor/java/transex3/view/SdfTable.java new file mode 100644 index 000000000000..f0cc7bd84a34 --- /dev/null +++ b/transex3/java/receditor/java/transex3/view/SdfTable.java @@ -0,0 +1,24 @@ +package transex3.view; + +import javax.swing.JTable; + +class SdfTable extends JTable{ + //private String tableId; + public SdfTable( Object[][] obj1 , Object[] obj2){ + super(obj1,obj2); + } + //@Override + public boolean isCellEditable(int row, int col) { + if( row == 0 && col == 0 || row == 0 && col == 1 || row == 0 && col == 2 || row == 0 && col == 3 || row == 0 && col == 4 ) + return false; + else + return true; + } + /*public String getTableId() { + return tableId; + } + public void setTableId(String tableId) { + this.tableId = tableId; + }*/ + +}
\ No newline at end of file diff --git a/transex3/java/receditor/makefile.mk b/transex3/java/receditor/makefile.mk new file mode 100755 index 000000000000..e5e3921eea6b --- /dev/null +++ b/transex3/java/receditor/makefile.mk @@ -0,0 +1,39 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=../.. +PRJNAME=transex3 +TARGET=receditor + +.INCLUDE : ant.mk + +ALLTAR : ANTBUILD + diff --git a/transex3/java/receditor/receditor.MF b/transex3/java/receditor/receditor.MF new file mode 100755 index 000000000000..dced97882df9 --- /dev/null +++ b/transex3/java/receditor/receditor.MF @@ -0,0 +1 @@ +Main-Class: transex3.controller.Main diff --git a/transex3/layout/README b/transex3/layout/README new file mode 100644 index 000000000000..1838e2a94ba0 --- /dev/null +++ b/transex3/layout/README @@ -0,0 +1,27 @@ +Tralay - Extract and translate strings in Layout xml files. + +Translatable strings in layout xml files are attributes that have name +which starts with an underscore, eg + + _title="Set Zoom" + _label="Whole Page" + +Here is how it works + + * Extract: generate out.sdf + ../unxlngx6.pro/bin/tralay -l en-US zoom.xml > out.sdf + + * Translate: do: + cat out.sdf > trans.sdf + sed 's/en-US\t/de\tde:/' out.sdf >> trans.sdf + + * Merge: translate + ../unxlngx6.pro/bin/tralay -m trans.sdf -l de zoom.xml > zoom-DE.xml + +Running + + dmake test + +does something similar. + +
\ No newline at end of file diff --git a/transex3/layout/layoutparse.cxx b/transex3/layout/layoutparse.cxx new file mode 100644 index 000000000000..0f43c9a3053f --- /dev/null +++ b/transex3/layout/layoutparse.cxx @@ -0,0 +1,139 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutparse.cxx,v $ + * + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "layoutparse.hxx" + +#define STRING( str ) String( str, RTL_TEXTENCODING_UTF8 ) +#define BSTRING( str ) ByteString( str, RTL_TEXTENCODING_UTF8 ) + +LayoutXMLFile::LayoutXMLFile( bool mergeMode ) + : XMLFile() + , mMergeMode( mergeMode ) +{ +} + +void +LayoutXMLFile::SearchL10NElements( XMLParentNode* pCur, int ) +{ + if ( !pCur ) + pCur = this; + + /* Recurse int children, SearchL10NElements does not do that for us. */ + if ( XMLChildNodeList* lst = pCur->GetChildList() ) + for ( ULONG i = 0; i < lst->Count(); i++ ) + if ( lst->GetObject( i )->GetNodeType() == XML_NODE_TYPE_ELEMENT ) + HandleElement( ( XMLElement* )lst->GetObject( i ) ); + else if ( lst->GetObject( i )->GetNodeType() == XML_NODE_TYPE_COMMENT ) + lst->Remove( i-- ); +} + +std::vector<XMLAttribute*> +interestingAttributes( XMLAttributeList* lst ) +{ + std::vector<XMLAttribute*> interesting; + if ( lst ) + for ( ULONG i = 0; i < lst->Count(); i++ ) + if ( lst->GetObject( i )->Equals( STRING( "id" ) ) ) + interesting.insert( interesting.begin(), lst->GetObject( i ) ); + else if ( ! BSTRING( *lst->GetObject( i ) ).CompareTo( "_", 1 ) ) + interesting.push_back( lst->GetObject( i ) ); + return interesting; +} + +void +LayoutXMLFile::HandleElement( XMLElement* element ) +{ + std::vector<XMLAttribute*> interesting = interestingAttributes( element->GetAttributeList() ); + + if ( interesting.size() ) + { + std::vector<XMLAttribute*>::iterator i = interesting.begin(); + + ByteString id = BSTRING( (*i++)->GetValue() ); + + if ( mMergeMode ) + InsertL10NElement( id, element ); + else + for ( ; i != interesting.end(); ++i ) + { + ByteString attributeId = id; + ByteString value = BSTRING( ( *i )->GetValue() ); + XMLElement *e = new XMLElement( *element ); + e->RemoveAndDeleteAllChilds(); + /* Copy translatable text to CONTENT. */ + //new XMLData( STRING( ( *i )->GetValue() ), e, true ); + new XMLData( STRING( value ), e, true ); + attributeId += BSTRING ( **i ); + InsertL10NElement( attributeId, e ); + } + } + + SearchL10NElements( (XMLParentNode*) element ); +} + +void LayoutXMLFile::InsertL10NElement( ByteString const& id, XMLElement* element ) +{ + ByteString const language = "en-US"; + LangHashMap* languageMap = 0; + XMLHashMap::iterator pos = XMLStrings->find( id ); + if ( pos != XMLStrings->end() ) + { + languageMap = pos->second; + fprintf( stderr, "error:%s:duplicate translation found, id=%s\n", + id.GetBuffer(), BSTRING( sFileName ).GetBuffer() ); + exit( 1 ); + } + else + { + languageMap = new LangHashMap(); + XMLStrings->insert( XMLHashMap::value_type( id , languageMap ) ); + order.push_back( id ); + } + (*languageMap)[ language ] = element; +} + +BOOL LayoutXMLFile::Write( ByteString &aFilename ) +{ + + if ( aFilename.Len() ) + { + ofstream aFStream( aFilename.GetBuffer() , ios::out | ios::trunc ); + if ( !aFStream ) + fprintf( stderr, "ERROR: cannot open file:%s\n", aFilename.GetBuffer() ); + else + { + XMLFile::Write( aFStream ); + aFStream.close(); + return true; + } + } + return false; +} diff --git a/transex3/layout/layoutparse.hxx b/transex3/layout/layoutparse.hxx new file mode 100644 index 000000000000..b9cd8f6c18b2 --- /dev/null +++ b/transex3/layout/layoutparse.hxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutparse.hxx,v $ + * + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef LAYOUTPARSE_HXX +#define LAYOUTPARSE_HXX + +#include "xmlparse.hxx" + +class LayoutXMLFile : public XMLFile +{ + bool mMergeMode; + +public: + LayoutXMLFile( bool mergeMode ); + + void SearchL10NElements( XMLParentNode *pCur, int pos = 0 ); + BOOL Write( ByteString &aFilename ); + void HandleElement( XMLElement* element ); + void InsertL10NElement( ByteString const& id, XMLElement* element ); + + using XMLFile::InsertL10NElement; + using XMLFile::Write; +}; + +std::vector<XMLAttribute*> interestingAttributes( XMLAttributeList* lst ); + +#endif /* LAYOUTPARSE_HXX */ diff --git a/transex3/layout/loc.sdf b/transex3/layout/loc.sdf new file mode 100644 index 000000000000..023357adc420 --- /dev/null +++ b/transex3/layout/loc.sdf @@ -0,0 +1,24 @@ +transex3 layout\workben\zoom-1.xml 0 help FL_ZOOM 0 en-US Zoom factor 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_WHOLE_PAGE 0 en-US Whole Page 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_PAGE_WIDTH 0 en-US Page Width 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_OPTIMAL 0 en-US Optimal 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_200 0 en-US 200 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_150 0 en-US 15~0 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_100 0 en-US 100 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_75 0 en-US 75 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_50 0 en-US 50 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_USER 0 en-US Variable 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help FL_ZOOM 0 de deZoom factor 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_WHOLE_PAGE 0 de deWhole Page 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_PAGE_WIDTH 0 de dePage Width 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_OPTIMAL 0 de deOptimal 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_200 0 de de200 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_150 0 de de15~0 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_100 0 de de100 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_75 0 de de75 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_50 0 de de50 % 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_USER 0 de deVariable 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help FL_ZOOM 0 en-US Zoom factor 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_WHOLE_PAGE 0 en-US Whole Page 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help FL_ZOOM 0 de de3:Zoom factor 20080204 13:51:01 +transex3 layout\workben\zoom-1.xml 0 help BTN_WHOLE_PAGE 0 de de3:Whole Page 20080204 13:51:01 diff --git a/transex3/layout/makefile.mk b/transex3/layout/makefile.mk new file mode 100644 index 000000000000..9864b46242b2 --- /dev/null +++ b/transex3/layout/makefile.mk @@ -0,0 +1,81 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +INCPRE=$(MISC) + +PRJNAME=transex3 +TARGET=tralay +#TARGETTYPE=GUI +TARGETTYPE=CUI +LIBTARGET=no + +# --- Settings ----------------------------------------------------- + +ENABLE_EXCEPTIONS=TRUE + +.INCLUDE : settings.mk + +.IF "$(SYSTEM_EXPAT)" == "YES" +CFLAGS+=-DSYSTEM_EXPAT +.ENDIF + +# --- Files -------------------------------------------------------- + +APP1TARGET=$(TARGET) + +OBJFILES =\ + $(OBJ)/export2.obj\ + $(OBJ)/helpmerge.obj\ + $(OBJ)/layoutparse.obj\ + $(OBJ)/merge.obj\ + $(OBJ)/tralay.obj\ + $(OBJ)/xmlparse.obj + +APP1OBJS = $(OBJFILES) + +APP1STDLIBS =\ + $(TOOLSLIB)\ + $(EXPATASCII3RDLIB)\ + $(VOSLIB)\ + $(CPPULIB) \ + $(SALLIB) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +test .PHONY: + ../$(INPATH)/bin/tralay -l en-US -o out.sdf zoom.xml + cat out.sdf > trans.sdf + sed 's/en-US\t/de\tde:/' out.sdf >> trans.sdf + ../$(INPATH)/bin/tralay -m trans.sdf -l de -o zoom-DE.xml zoom.xml diff --git a/transex3/layout/tralay.cxx b/transex3/layout/tralay.cxx new file mode 100644 index 000000000000..740981674c50 --- /dev/null +++ b/transex3/layout/tralay.cxx @@ -0,0 +1,403 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tralay.cxx,v $ + * + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <transex3/vosapp.hxx> + +#include <osl/file.hxx> + +#include "export.hxx" +#include "layoutparse.hxx" +#include "helpmerge.hxx" +#include "xmlparse.hxx" + +// Convert a rtl::OUString to a byte string. +#define OUSTRING_CSTR( str ) \ + rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() + +#define STRING( str ) String( str, RTL_TEXTENCODING_UTF8 ) +#define BSTRING( str ) ByteString( str, RTL_TEXTENCODING_UTF8 ) + +using ::rtl::OUString; + +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + +class TranslateLayout : public Application +{ + ByteString mGid1; + ByteString mLanguage; + ByteString mLocalize; + ByteString mOutput; + ByteString mProject; + ByteString mRoot; + bool mMergeMode; + std::vector< ByteString > mLanguages; + std::list< ByteString > mFiles; + +public: + TranslateLayout(); + virtual ~TranslateLayout(); + ByteString GetCommandLineParam( int i ); + ByteString GetOptionArgument( int const i ); + void ExceptionalMain(); + void Main(); + void Merge(); + void MergeLanguage( ByteString const& language ); + void ParseCommandLine(); + void CreateSDF(); + + using Application::GetCommandLineParam; +}; + +static void usage() +{ + fprintf( stderr, "Usage: tralay [OPTION]... XML-FILE\n" ); + fprintf( stderr, "\nOptions:\n" ); + fprintf( stderr, " -h,--help show this help\n" ); + fprintf( stderr, " -l,--language=LANG process this language\n" ); + fprintf( stderr, " -m,--merge=DATABASE.SDF translation database\n" ); + fprintf( stderr, "\nExamples:\n" ); + fprintf( stderr, " tralay -l en-US -o localize.sdf zoom.xml # Extract\n" ); + fprintf( stderr, " tralay -m localize.sdf -l de -l nl -o out zoom.xml # Merge/translate\n" ); + exit( 2 ); +} + +static ByteString ConvertSystemPath( const ByteString& rPath ) +{ + if( rPath.CompareTo( ".", 1 ) == 0 ) + { + OUString sPath( rPath.GetBuffer(), rPath.Len(), RTL_TEXTENCODING_UTF8 ); + + ::rtl::OUString curDirPth, sURL; + osl_getProcessWorkingDir( &curDirPth.pData ); + + ::osl::FileBase::getAbsoluteFileURL( curDirPth, sPath, sURL ); + ::osl::FileBase::getSystemPathFromFileURL( sURL, sPath ); + + return ByteString( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_UTF8 ) ); + } + else + { + return rPath; + } +} + +ByteString TranslateLayout::GetCommandLineParam( int i ) +{ + return ByteString( OUSTRING_CSTR( Application::GetCommandLineParam( sal::static_int_cast< USHORT >( i ) ) ) ); +} + +ByteString TranslateLayout::GetOptionArgument( int const i ) +{ + if ( i >= GetCommandLineParamCount() ) + usage(); + ByteString arg = GetCommandLineParam( i ); + if ( !arg.CompareTo( "-", 1 ) ) + { + fprintf( stderr, "Option needs an argument: %s, found: %s\n", + GetCommandLineParam( i - 1 ).GetBuffer(), + arg.GetBuffer() ); + usage(); + } + return arg; + } + +void TranslateLayout::ParseCommandLine() +{ + for ( int i = 0; i < GetCommandLineParamCount(); i++ ) + { + ByteString aParam = GetCommandLineParam( i ); + if ( aParam.Equals( "-h" ) || aParam.Equals( "--help" ) ) + usage(); + else if ( aParam.Equals( "-l" ) || aParam.Equals( "--language" ) ) + mLanguages.push_back ( GetOptionArgument( ++i ) ); + else if ( aParam.Equals( "-m" ) || aParam.Equals( "--merge" ) ) + { + mMergeMode = true; + mLocalize = GetOptionArgument( ++i ); + } + else if ( aParam.Equals( "-o" ) || aParam.Equals( "--output" ) ) + mOutput = ConvertSystemPath( GetOptionArgument( ++i ) ); + else if ( !aParam.CompareTo( "-", 1 ) ) + { + fprintf( stderr, "error: No such option: %s\n", aParam.GetBuffer() ); + usage(); + } + else + mFiles.push_back( ConvertSystemPath( aParam ) ); + } + if ( !mFiles.size() ) + { + fprintf( stderr, "error: No XML-FILE found\n" ); + usage(); + } +} + +static XMLAttribute* +findAttribute( XMLAttributeList* lst, String const& name ) +{ + for ( ULONG i = 0; i < lst->Count(); i++ ) + if ( lst->GetObject( i )->Equals( name ) ) + return lst->GetObject( i ); + return 0; +} + +static XMLAttribute* +translateAttribute( XMLAttributeList* lst, + String const& name, String const& translation ) +{ + if ( XMLAttribute* a = findAttribute( lst, name ) ) + return lst->Replace ( new XMLAttribute( name.Copy( 1 ), translation ), a ); + return 0; +} + +static void +translateElement( XMLElement* element, ByteString const& lang, + ResData* resData, MergeDataFile& mergeData ) +{ + XMLAttributeList* attributes = element->GetAttributeList(); + std::vector<XMLAttribute*> interesting( interestingAttributes( attributes ) ); + + + if( !interesting.empty() ) + { + std::vector<XMLAttribute*>::iterator i( interesting.begin() ); + ByteString id = BSTRING( (*i++)->GetValue() ); + for ( ; i != interesting.end(); ++i ) + { + ByteString attributeId = id; + attributeId += BSTRING ( **i ); + resData->sGId = attributeId; + resData->sId = element->GetOldref(); + + if ( PFormEntrys* entry = mergeData.GetPFormEntrys( resData ) ) + { + ByteString translation; + entry->GetText( translation, STRING_TYP_TEXT, lang, true ); + // ByteString original = removeContent( element ); + if ( !translation.Len() ) +#if 0 + translation = original; +#else + translation = BSTRING( ( *i )->GetValue() ); +#endif + delete translateAttribute( attributes, **i , STRING( translation ) ); + } + } + } +} + +static bool is_dir( ByteString const& name ) +{ + DirectoryItem aItem; + OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 ); + FileBase::getFileURLFromSystemPath( sFileURL, sFileURL ); + if( DirectoryItem::get( sFileURL, aItem ) == FileBase::E_None ) + { + FileStatus aStatus(FileStatusMask_Type); + if( aItem.getFileStatus( aStatus ) == FileBase::E_None ) + { + if( aStatus.getFileType() == FileStatus::Directory ) + return true; + } + } + return false; +} + +static void make_directory( ByteString const& name ) +{ + OUString sFileURL( name.GetBuffer(), name.Len(), RTL_TEXTENCODING_UTF8 ); + FileBase::getFileURLFromSystemPath( sFileURL, sFileURL ); + Directory::create( sFileURL ); +} + +static void insertMarker( XMLParentNode *p, ByteString const& file ) +{ + if ( XMLChildNodeList* lst = p->GetChildList() ) + if ( lst->Count() ) + { + ULONG i = 1; + // Skip newline, if possible. + if ( lst->Count() > 1 + && lst->GetObject( 2 )->GetNodeType() == XML_NODE_TYPE_DEFAULT ) + i++; + OUString marker = OUString::createFromAscii( "\n NOTE: This file has been generated automagically by transex3/layout/tralay,\n from source template: " ) + + STRING( file ) + + OUString::createFromAscii( ".\n Do not edit, changes will be lost.\n" ); + lst->Insert( new XMLComment( marker, 0 ), i ); + } +} + +void TranslateLayout::MergeLanguage( ByteString const& language ) +{ + ByteString xmlFile = mFiles.front(); + + MergeDataFile mergeData( mLocalize, xmlFile, + FALSE, RTL_TEXTENCODING_MS_1252 ); + + DirEntry aFile( xmlFile ); + SimpleXMLParser aParser; + LayoutXMLFile* layoutXml = new LayoutXMLFile( mMergeMode ); + if ( !aParser.Execute( aFile.GetFull() , STRING( xmlFile ), layoutXml ) ) + { + fprintf(stderr, "error: parsing: %s\n", xmlFile.GetBuffer() ); + return; + } + + layoutXml->Extract(); + insertMarker( layoutXml, xmlFile ); + + ResData resData( "", "", "" ); + resData.sResTyp = mProject; /* mGid1 ?? */ + resData.sFilename = xmlFile; + + XMLHashMap* xmlStrings = layoutXml->GetStrings(); + for ( XMLHashMap::iterator i = xmlStrings->begin(); i != xmlStrings->end(); + ++i ) + { + if ( LangHashMap* languageMap = i->second ) + if ( XMLElement* element = ( *languageMap )[ "en-US" ] ) + translateElement( element, language, &resData, mergeData ); + } + +#ifndef WNT + ByteString outFile = "/dev/stdout"; +#else + ByteString outFile = "\\\\.\\CON"; +#endif + if ( mOutput.Len() ) + { + outFile = mOutput; + if ( is_dir( outFile ) ) + { + ByteString outDir = mOutput; + outDir.Append( "/" ).Append( language ); + if ( !is_dir( outDir ) ) + make_directory( outDir ); + outFile = outDir; + outFile.Append( "/" ).Append( xmlFile ); + } + } + layoutXml->Write( outFile ); + delete layoutXml; +} + +void TranslateLayout::Merge() +{ + if ( mLanguages.size() ) + for ( std::vector<ByteString>::iterator i = mLanguages.begin(); + i != mLanguages.end(); ++i) + MergeLanguage( *i ); + else + MergeLanguage( mLanguage ); +} + +void TranslateLayout::CreateSDF() +{ + ByteString xmlFile = mFiles.front(); +#ifndef WNT + ByteString sdf = "/dev/stdout"; +#else + ByteString sdf = "\\\\.\\CON"; +#endif + if ( mOutput.Len() ) + sdf = mOutput; + Export::SetLanguages( mLanguages ); + HelpParser::CreateSDF( sdf, mProject, mRoot, xmlFile, + new LayoutXMLFile( mMergeMode ), mGid1 ); +} + +void TranslateLayout::ExceptionalMain() +{ + ParseCommandLine(); + if ( mLanguages.size() ) + mLanguage = mLanguages.front(); + if ( mMergeMode ) + Merge(); + else + CreateSDF(); +} + +void TranslateLayout::Main() +{ + try + { + ExceptionalMain(); + } + catch ( xml::sax::SAXException& rExc ) + { + OString aStr( OUStringToOString( rExc.Message, + RTL_TEXTENCODING_ASCII_US ) ); + uno::Exception exc; + if (rExc.WrappedException >>= exc) + { + aStr += OString( " >>> " ); + aStr += OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ); + } + fprintf( stderr, "error: parsing: '%s'\n", aStr.getStr() ); + OSL_ENSURE( 0, aStr.getStr() ); + } + catch ( uno::Exception& rExc ) + { + OString aStr( OUStringToOString( rExc.Message, + RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "error: UNO: '%s'\n", aStr.getStr() ); + OSL_ENSURE( 0, aStr.getStr() ); + } +} + +TranslateLayout::TranslateLayout() + : Application() + , mGid1( "layout" ) + , mLanguage( "en-US" ) + , mLocalize( "localize.sdf" ) + , mOutput() + , mProject( "layout" ) + , mRoot() + , mMergeMode( false ) + , mLanguages() + , mFiles() +{ +} + +TranslateLayout::~TranslateLayout() +{ +} + +SAL_IMPLEMENT_MAIN() +{ + TranslateLayout t; + t.Main(); + return 0; +} diff --git a/transex3/layout/zoom.xml b/transex3/layout/zoom.xml new file mode 100644 index 000000000000..0fb3d27343ff --- /dev/null +++ b/transex3/layout/zoom.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- This is a template. i18n translation is not performed in-place; + i18n translated xml files are generated from this template by + transex3/layout/tralay. !--> + +<modaldialog xmlns="http://openoffice.org/2007/layout" + xmlns:cnt="http://openoffice.org/2007/layout/container" + id="dialog" _title="Set Zoom" _label="boe" optimumsize="true" + help-id="SID_ATTR_ZOOM" + has_border="true" sizeable="true" moveable="true"> + <vbox spacing="5" border="5"> + <fixedline id="FL_ZOOM" _text="Zoom factor" _tooltip="bah" cnt:expand="true"/> + <radiobutton radiogroup="zoom" id="BTN_WHOLE_PAGE" _label="Whole Page"/> + <radiobutton radiogroup="zoom" id="BTN_PAGE_WIDTH" _label="Page Width"/> + <radiobutton radiogroup="zoom" id="BTN_OPTIMAL" _label="Optimal"/> + <radiobutton radiogroup="zoom" id="BTN_200" _label="200 %"/> + <radiobutton radiogroup="zoom" id="BTN_150" _label="15~0 %"/> + <radiobutton radiogroup="zoom" id="BTN_100" _label="100 %"/> + <radiobutton radiogroup="zoom" id="BTN_75" _label="75 %"/> + <radiobutton radiogroup="zoom" id="BTN_50" _label="50 %"/> + <hbox cnt:expand="false" cnt:fill="true"> + <align cnt:expand="false" cnt:fill="true"> + <radiobutton cnt:v-align="0.5" cnt:v-fill="0" radiogroup="zoom" id="BTN_USER" _label="Variable"/> + </align> + <flow cnt:padding="10" cnt:expand="false"/> + <metricfield id="ED_USER" value-step="1" + repeat="true" has_border="true" spin="true" + text="100%" unit="13" custom-unit-text="%" + right="true" + cnt:expand="false"/> + </hbox> + <fixedline cnt:padding="1" id="FL_BOTTOM"/> + <dialogbuttonhbox border="5" spacing="5"> + <flow/> + <okbutton id="BTN_ZOOM_OK"/> + <cancelbutton id="BTN_ZOOM_CANCEL"/> + <helpbutton id="BTN_ZOOM_HELP"/> + </dialogbuttonhbox> + </vbox> +</modaldialog> diff --git a/transex3/prj/build.lst b/transex3/prj/build.lst new file mode 100644 index 000000000000..91a5056acce3 --- /dev/null +++ b/transex3/prj/build.lst @@ -0,0 +1,7 @@ +tr transex3 : tools NULL +tr transex3 usr1 - all tr_mkout NULL +tr transex3\inc nmake - all tr_inc NULL +tr transex3\source nmake - all tr_src tr_inc NULL +tr transex3\layout nmake - all rt_layout tr_src tr_inc NULL +tr transex3\java\l10nconv nmake - all tr_conv NULL +tr transex3\java\receditor nmake - all tr_rece NULL diff --git a/transex3/prj/d.lst b/transex3/prj/d.lst new file mode 100644 index 000000000000..7bd8e7d3e72d --- /dev/null +++ b/transex3/prj/d.lst @@ -0,0 +1,39 @@ +mkdir: %_DEST%\inc%_EXT%\transex3 + +..\%__SRC%\bin\cfgex.exe %_DEST%\bin%_EXT%\cfgex.exe +..\%__SRC%\bin\cfgex %_DEST%\bin%_EXT%\cfgex +..\%__SRC%\bin\transex3.exe %_DEST%\bin%_EXT%\transex3.exe +..\%__SRC%\bin\transex3 %_DEST%\bin%_EXT%\transex3 +..\%__SRC%\bin\lngex.exe %_DEST%\bin%_EXT%\lngex.exe +..\%__SRC%\bin\lngex %_DEST%\bin%_EXT%\lngex +..\%__SRC%\bin\localize_sl.exe %_DEST%\bin%_EXT%\localize_sl.exe +..\%__SRC%\bin\localize_sl %_DEST%\bin%_EXT%\localize_sl +..\%__SRC%\bin\xrmex.exe %_DEST%\bin%_EXT%\xrmex.exe +..\%__SRC%\bin\xrmex %_DEST%\bin%_EXT%\xrmex +..\%__SRC%\bin\gsicheck.exe %_DEST%\bin%_EXT%\gsicheck.exe +..\%__SRC%\bin\gsicheck %_DEST%\bin%_EXT%\gsicheck +..\%__SRC%\bin\helpex.exe %_DEST%\bin%_EXT%\helpex.exe +..\%__SRC%\bin\helpex %_DEST%\bin%_EXT%\helpex +..\%__SRC%\bin\ulfex.exe %_DEST%\bin%_EXT%\ulfex.exe +..\%__SRC%\bin\ulfex %_DEST%\bin%_EXT%\ulfex +..\%__SRC%\bin\txtconv.exe %_DEST%\bin%_EXT%\txtconv.exe +..\%__SRC%\bin\txtconv %_DEST%\bin%_EXT%\txtconv +..\%__SRC%\bin\tralay.exe %_DEST%\bin%_EXT%\tralay.exe +..\%__SRC%\bin\tralay %_DEST%\bin%_EXT%\tralay + +..\%__SRC%\class\converter\converter.jar %_DEST%\bin%_EXT%\converter.jar +..\%__SRC%\doc\converter_javadoc.zip %_DEST%\bin%_EXT%\converter_javadoc.zip + +..\%__SRC%\class\receditor\receditor.jar %_DEST%\bin%_EXT%\receditor.jar + +..\scripts\localize.pl %_DEST%\bin%_EXT%\localize.pl +..\scripts\localize %_DEST%\bin%_EXT%\localize + +..\inc\export.hxx %_DEST%\inc%_EXT%\transex3\export.hxx +..\inc\transex3\directory.hxx %_DEST%\inc%_EXT%\transex3\directory.hxx +..\inc\transex3\file.hxx %_DEST%\inc%_EXT%\transex3\file.hxx +..\inc\transex3\vosapp.hxx %_DEST%\inc%_EXT%\transex3\vosapp.hxx + +..\inc\utf8conv.hxx %_DEST%\inc%_EXT%\transex3\utf8conv.hxx +..\%__SRC%\lib\transex.lib %_DEST%\lib%_EXT%\transex.lib +..\%__SRC%\lib\libtransex.a %_DEST%\lib%_EXT%\libtransex.a diff --git a/transex3/scripts/keyidGen.pl b/transex3/scripts/keyidGen.pl new file mode 100644 index 000000000000..acb5137e3f7c --- /dev/null +++ b/transex3/scripts/keyidGen.pl @@ -0,0 +1,189 @@ +: +eval 'exec perl -S $0 ${1+"$@"}' + if 0; +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: keyidGen.pl,v $ +# +# $Revision: 1.3 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +# +# add keyids to sdf file +# + +use Compress::Zlib(); + +print "\nkeyidGen version 1.0 \n\n"; + +my ( $infile,$outfile,$dbimport ); +get_options(); + +print_help() if ( !defined $infile || $help ); +exit 1 if ( !defined $infile ); +if ( ! defined $outfile ) +{ + $outfile = $infile; + $outfile =~ s/\.sdf$//i; + $outfile .= "_KeyID.sdf"; +} + +$collisions = 0; +%hashcodes = (); +$count = 0; +print "writing to $outfile\n"; +open INFILE,"<$infile" || die "could not open $infile $! $^E\n"; +open OUTFILE,">$outfile" || die "could not open $outfile $! $^E\n"; + +while ( <INFILE> ) +{ + $line = $_; + chomp $line; + $hash = 0; + if ( $line =~ /^([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)$/ ) + { + $string="$1 $2 $4 $5 $6 $7 $8"; + $hashp = makeID( $string ); + + if ( defined ($hashcodes{ $hashp } ) ) + { + $collisions ++ unless $hashcodes{ $hashp } eq $string; + } + $hashcodes{ $hashp } = $string; + $count++; + if ( $dbimport ) + { + my ( $pre, $post, $old ); + $pre = "$1\t$2\t"; + $post = "\t$4\t$5\t$6\t$7\t$8\t$9\t$10\t$11\t$12\t$13\t$14\t$15\n"; + $old = $3; + $old =~ s/;{0,1}keyid:......;{0,1}//; + $old =~ s/^0$//; + if ( $old ne "" ) { $old .= ";"; } + print OUTFILE "$pre${old}keyid:$hashp$post"; + } + else + { + print OUTFILE "$1\t$2\t$3\t$4\t$5\t$6\t$7\t$8\t$9\t$10\t".makekidstr($hashp,$11)."\t".makekidstr($hashp,$12)."\t$13\t".makekidstr($hashp,$14)."\t$15\n"; + } + } +} +print "$count entries\n"; +print "$collisions collisions\n"; + +close INFILE; +close OUTFILE; + +sub makeID +{ + my ( $String ) = shift; + my ( $hash ); + # hardcoded to prevent windows installer to choke on bad directoryname :-(( + if ( $String eq "scp2 source\\ooo\\directory_ooo.ulf LngText STR_DIR_KAPITEL " ) + { + return "keyid1"; + } + + $hash = Compress::Zlib::crc32( $String, undef ); + return makenumber( $hash ); +} + +sub makenumber +{ + $h = shift; + # 1 2 3 4 + # 1234567890123456789012345678901234567890 + $symbols="0123456789abcdefghijklmnopqrstuvwxyz+-<=>"; + $order = length($symbols); + $result = ""; + while ( length( $result ) < 6 ) + { + $result .= substr( $symbols, ($h % $order), 1 ); + $h = int( $h / $order ); + } + die "makenumber failed because number is too big (this cannot be so this is a strange error)" if $h > 0; + + return reverse $result; +} + + +sub makekidstr +{ + $kid = shift; + $str = shift; + + if ( $str ne "" ) + { + # special handling for strings starting with font descriptions like {&Tahoma8} (win system integration) + if ( $str =~ s/^(\{\&[^\}]+\})// ) + { + return "$1$kid‖$str"; + } + else + { + return "$kid‖$str"; + } + } + else + { + return ""; + } +# return "default"; +} + +sub print_help +{ + print "\n\n"; + print "keyidGen 0.5 for sdf files\n"; + print "--------------------------\n"; + print "Usage:\n"; + print "keyidGen <infile> [<outfile>] [-dbimport]\n"; + print " add keyids to the entries and write them to a file with\n"; + print " _KeyID added to the name\n"; + print " -dbimport Add KeyID to a new column instead of to the strings.\n"; + print " This is needed to import the IDs into tha database.\n"; + print "\n\n"; +} + + +sub get_options { + my ($arg,$has_infile); + + while ($arg = shift @ARGV) { + $arg =~ /^-dbimport$/ and $dbimport = 1 and next; + $arg =~ /^-help$/ and $help = 1 and next; #show help + + if ( !$has_infile ) + { + $infile = $arg; + $has_infile = 1; + } + else + { + $outfile = $arg; + } + } +} diff --git a/transex3/scripts/localize b/transex3/scripts/localize new file mode 100755 index 000000000000..74a75ecc3aee --- /dev/null +++ b/transex3/scripts/localize @@ -0,0 +1,20 @@ +#!/bin/sh +if [ x${SOLARENV}x = xx ]; then + echo No environment found, please use 'setsolar' +exit 1 +fi + +# localize.pl calls localize_sl in solver bin directory which depends on dynamic +# libraries in solver lib directory but has no correct RPATH (or equivalent): +if [ "${OS?}" = MACOSX ]; then + export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH+${DYLD_LIBRARY_PATH}:}${SOLARVERSION?}/${INPATH?}/lib${UPDMINOREXT} +else + export LD_LIBRARY_PATH=${LD_LIBRARY_PATH+${LD_LIBRARY_PATH}:}${SOLARVERSION?}/${INPATH?}/lib${UPDMINOREXT} +fi + +if [ x${SOLARVER}x = xx -o x${UPDMINOR}x = xx ]; then + exec perl -w $SOLARVERSION/$INPATH/bin/localize.pl "$@" +else + exec perl -w $SOLARVERSION/$INPATH/bin.$UPDMINOR/localize.pl "$@" +fi + diff --git a/transex3/scripts/localize.pl b/transex3/scripts/localize.pl new file mode 100755 index 000000000000..b9e478ba66bd --- /dev/null +++ b/transex3/scripts/localize.pl @@ -0,0 +1,1112 @@ +: +eval 'exec perl -wS $0 ${1+"$@"}' + if 0; + + +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: localize.pl,v $ +# +# $Revision: 1.18 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +use strict; +use Getopt::Long; +use IO::Handle; +use File::Find; +use File::Temp; +use File::Copy; +use File::Glob qw(:glob csh_glob); +use Cwd; + +# ver 1.1 +# +#### module lookup +#use lib ("$ENV{SOLARENV}/bin/modules", "$ENV{COMMON_ENV_TOOLS}/modules"); + +#### module lookup +# OOo conform +my @lib_dirs; +BEGIN { + if ( !defined($ENV{SOLARENV}) ) { + die "No environment found (environment variable SOLARENV is undefined)"; + } + push(@lib_dirs, "$ENV{SOLARENV}/bin/modules"); + push(@lib_dirs, "$ENV{COMMON_ENV_TOOLS}/modules") if defined($ENV{COMMON_ENV_TOOLS}); +} +use lib (@lib_dirs); + +#### globals #### +my $sdffile = ''; +my $no_sort = ''; +my $outputfile = ''; +my $mode = ''; +my $bVerbose="0"; +my $srcpath = ''; +my $WIN; +my $languages; +#my %sl_modules; # Contains all modules where en-US and de is source language +my $use_default_date = '0'; + + # ( leftpart ) ( rightpart ) + # prj file dummy type gid lid helpid pform width lang text helptext qhelptext title timestamp +my $sdf_regex = "((([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*))\t([^\t]*)\t(([^\t]*)\t([^\t]*)\t([^\t]*)\t([^\t]*)\t)([^\t]*))"; +my $file_types = "(src|hrc|xcs|xcu|lng|ulf|xrm|xhp|xcd|xgf|xxl|xrb)"; +# Always use this date to prevent cvs conflicts +my $default_date = "2002-02-02 02:02:02"; +my @sdfparticles; + +#### main #### +parse_options(); + +if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) { + $WIN = 'TRUE'; +} + else { + $WIN = ''; +} + +#%sl_modules = fetch_sourcelanguage_dirlist(); + + +if ( $mode eq "merge" ) { + merge_gsicheck(); + splitfile( $sdffile ); + unlink $sdffile; # remove temp file! +} +elsif( $mode eq "extract" ) { + collectfiles( $outputfile ); +} +else { + usage(); +} + +exit(0); + +######################################################### +sub splitfile{ + + my $lastFile = ''; + my $currentFile = ''; + my $cur_sdffile = ''; + my $last_sdffile = ''; + my $delim; + my $badDelim; + my $start = 'TRUE'; + my %index = (); + my %block; + + STDOUT->autoflush( 1 ); + + #print STDOUT "Open File $sdffile\n"; + open MYFILE , "< $sdffile" + or die "Can't open '$sdffile'\n"; + + while( <MYFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + next if( $prj eq "binfilter" ); # Don't merge strings into binfilter module + chomp( $line ); + $currentFile = $srcpath . '\\' . $prj . '\\' . $file; + if ( $WIN ) { $currentFile =~ s/\//\\/g; } + else { $currentFile =~ s/\\/\//g; } + + $cur_sdffile = $currentFile; + #if( $cur_sdffile =~ /\.$file_types[\s]*$/ ){ + if( $WIN ) { $cur_sdffile =~ s/\\[^\\]*\.$file_types[\s]*$/\\localize.sdf/; } + else { $cur_sdffile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; } + #} + + # Set default date + if( $line =~ /(.*)\t[^\t\$]*$/ ){ + $line = $1."\t".$default_date; + } + + if( $start ){ + $start=''; + $lastFile = $currentFile; # ? + $last_sdffile = $cur_sdffile; + } + + if( $lang eq "en-US" ){} + elsif( $cur_sdffile eq $last_sdffile ) + { + $block{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line ; + } + else + { + writesdf( $lastFile , \%block ); + $lastFile = $currentFile; #? + $last_sdffile = $cur_sdffile; + %block = (); + #if( ! $lang eq "en-US" ) { + $block{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line ; + #} + + } + } #else { print STDOUT "splitfile REGEX kaputt\n";} + + } + writesdf( $lastFile , \%block ); + %block = (); + close( MYFILE ); + +} +######################################################### + +#sub fetch_sourcelanguage_dirlist +#{ +# +# my $working_path = getcwd(); +# my %sl_dirlist; +# +# chdir $srcpath; +# my @all_dirs = csh_glob( "*" ); +# +# foreach my $file ( @all_dirs ) +# { +# if( -d $file ) +# { +# my $module = $file; +# $file .= "/prj/l10n"; +# $file =~ s/\//\\/ , if( $WIN ) ; +# +# if( -f $file ) # Test file <module>/prj/l10n +# { +# $sl_dirlist{ $module } = 1; +# if( $bVerbose eq "1" ) { print STDOUT "$module: de and en-US source language detected\n"; } +# } +# } +# } +# +# chdir $working_path; +# +# return %sl_dirlist; +#} + +#sub has_two_sourcelanguages +#{ +# my $module = shift; +# return defined $sl_modules{ $module } ; +#} +sub writesdf{ + + my $lastFile = shift; + my $blockhash_ref = shift; + my $localizeFile = $lastFile; + my %index=(); + + if( $localizeFile =~ /\.$file_types[\s]*$/ ){ + if( $WIN ) { $localizeFile =~ s/\\[^\\]*\.$file_types[\s]*$/\\localize.sdf/; } + else { $localizeFile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; } + }else { + print STDERR "Strange filetype found '$localizeFile'\n"; + return; + } + if( $bVerbose ){ print STDOUT "$localizeFile\n"; } + if( open DESTFILE , "< $localizeFile" ){ + + #or die "Can't open/create '\$localizeFile'"; + + #### Build hash + while(<DESTFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + chomp( $line ); + $index{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line ; + + } #else { print STDOUT "writesdf REGEX kaputt $_\n";} + + } + close( DESTFILE ); + } + #### Copy new strings + my @mykeys = keys( %{ $blockhash_ref } ); + my $isDirty = "FALSE"; + foreach my $key( @mykeys ){ + if( ! defined $index{ $key } ){ + # Add new entry + $index{ $key } = $blockhash_ref->{ $key} ; + $isDirty = "TRUE"; + }elsif( $index{ $key } ne $blockhash_ref->{ $key } ){ + # Overwrite old entry + $index{ $key } = $blockhash_ref->{ $key }; + $isDirty = "TRUE"; + }else { + } + } + + #### Write file + + if( !$bVerbose ){ print STDOUT "."; } + if( $isDirty eq "TRUE" ){ + if( open DESTFILE , "+> $localizeFile" ){ + print DESTFILE get_license_header(); + @mykeys = sort keys( %index ); + foreach my $key( @mykeys ){ + print DESTFILE ( $index{ $key } , "\n" ); + } + close DESTFILE; + }else { + print STDOUT "WARNING: File $localizeFile is not writable , try to merge ...\n"; + my ( $TMPFILE , $tmpfile ) = File::Temp::tempfile(); + if( open DESTFILE , "+> $tmpfile " ){ + @mykeys = keys( %index ); + foreach my $key( @mykeys ){ + print DESTFILE ( $index{ $key } , "\n" ); + } + close DESTFILE; + if( move( $localizeFile , $localizeFile.".backup" ) ){ + if( copy( $tmpfile , $localizeFile ) ){ + unlink $localizeFile.".backup"; + } else { print STDERR "Can't open/create '$localizeFile', original file is renamed to $localizeFile.backup\n"; } + } else { print STDERR "Can't open/create '$localizeFile'\n"; } + }else{ + print STDERR "WARNING: Can't open/create '$localizeFile'\n"; + } + unlink $tmpfile; + } + } +# if( $no_sort eq '' ){ +# sort_outfile( $localizeFile ); +# } +} + +sub get_license_header{ + return +"#\n". +"# #### ### # # ### ##### ##### #### ##### ##### \n". +"# # # # # ## # # # # # # # # # \n". +"# # # # # # # # # # # ### # # # # \n". +"# # # # # # ## # # # # # # # # \n". +"# #### ### # # ### # ##### #### ##### # \n". +"#\n". +"# DO NOT EDIT! This file will be overwritten by localisation process\n". +"#\n". +"#*************************************************************************\n". +"#\n". +"# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n". +"# \n". +"# Copyright 2008 by Sun Microsystems, Inc.\n". +"#\n". +"# OpenOffice.org - a multi-platform office productivity suite\n". +"#\n". +"# \$RCSfile:". +"localize.pl,v \$\n". +"#\n". +"# \$Revision: ". +"1.17.4.1 \$\n". +"#\n". +"# This file is part of OpenOffice.org.\n". +"#\n". +"# OpenOffice.org is free software: you can redistribute it and/or modify\n". +"# it under the terms of the GNU Lesser General Public License version 3\n". +"# only, as published by the Free Software Foundation.\n". +"#\n". +"# OpenOffice.org is distributed in the hope that it will be useful,\n". +"# but WITHOUT ANY WARRANTY; without even the implied warranty of\n". +"# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n". +"# GNU Lesser General Public License version 3 for more details\n". +"# (a copy is included in the LICENSE file that accompanied this code).\n". +"#\n". +"# You should have received a copy of the GNU Lesser General Public License\n". +"# version 3 along with OpenOffice.org. If not, see\n". +"# <http://www.openoffice.org/license.html>\n". +"# for a copy of the LGPLv3 License.\n". +"#\n". +"#*************************************************************************\n"; +} +######## Check input sdf file and use only the correct part +sub merge_gsicheck{ + my $command = ''; + my ( $TMPHANDLE , $tmpfile ) = File::Temp::tempfile(); + close ( $TMPHANDLE ); + + if( $ENV{WRAPCMD} ){ + $command = "$ENV{WRAPCMD} gsicheck"; + }else{ + $command = "gsicheck"; + } + my $errfile = $sdffile.".err"; + $command .= " -k -c -wcf $tmpfile -wef $errfile -l \"\" $sdffile"; + #my $rc = system( $command ); + my $output = `$command`; + my $rc = $? << 8; + if ( $output ne "" ){ + print STDOUT "### gsicheck ###\n"; + print STDOUT "### The file $errfile have been written containing the errors in your sdf file. Those lines will not be merged: ###\n\n"; + print STDOUT "$output\n"; + print STDOUT "################\n"; + + }else{ + # Remove the 0 Byte file + unlink $errfile; + } + $sdffile = $tmpfile; +} +######################################################### +# find search function +sub wanted +{ + my $file = $File::Find::name; + if( -f $file && $file =~ /.*localize.sdf$/ && !( $file =~ /.*\.svn.*/ ) ) { + push @sdfparticles , $file; + if( $bVerbose eq "1" ) { print STDOUT "$file\n"; } + else { print "."; } + } +} + +sub collectfiles{ + print STDOUT "### Localize\n"; + my $localizehash_ref; + my ( $bAll , $bUseLocalize, $langhash_ref , $bHasSourceLanguage , $bFakeEnglish ) = parseLanguages(); + + # Enable autoflush on STDOUT + # $| = 1; + STDOUT->autoflush( 1 ); + + ### Search sdf particles + print STDOUT "### Searching sdf particles\n"; + my $working_path = getcwd(); + chdir $srcpath; + find ( { wanted => \&wanted , follow => 1 }, getcwd() ); + chdir $working_path; + + my $nFound = $#sdfparticles +1; + print "\n $nFound files found !\n"; + + my ( $LOCALIZEPARTICLE , $localizeSDF ) = File::Temp::tempfile(); + close( $LOCALIZEPARTICLE ); + + my ( $ALLPARTICLES_MERGED , $particleSDF_merged ) = File::Temp::tempfile(); + close( $ALLPARTICLES_MERGED ); + my ( $LOCALIZE_LOG , $my_localize_log ) = File::Temp::tempfile(); + close( $LOCALIZE_LOG ); + + ## Get the localize de,en-US extract + if( $bAll || $bUseLocalize ){ + print "### Fetching source language strings\n"; + my $command = ""; + my $args = ""; + + if( $ENV{WRAPCMD} ){ + $command = "$ENV{WRAPCMD} localize_sl"; + }else{ + $command = "localize_sl"; + } + + # -e + # if ( -x $command ){ + if( $command ){ + if( !$bVerbose ){ $args .= " -QQ "; } + $args .= " -e -f $localizeSDF -l "; + my $bFlag=""; + if( $bAll ) {$args .= " en-US";} + else{ + my @list; + foreach my $isokey ( keys( %{ $langhash_ref } ) ){ + push @list , $isokey; + if( $langhash_ref->{ $isokey } ne "" ){ + push @list , $langhash_ref->{ $isokey }; + } + } + remove_duplicates( \@list ); + foreach my $isokey ( @list ){ + switch :{ + ( $isokey=~ /^en-US$/i ) + && do{ + if( $bFlag eq "TRUE" ){ $args .= ",en-US"; } + else { + $args .= "en-US"; $bFlag = "TRUE"; + } + }; + + } #switch + } #foreach + } # if + } # if +# if ( !$bVerbose ){ +# if ( $WIN eq "TRUE" ) { $args .= " > $my_localize_log"; } +# else { $args .= " >& $my_localize_log"; } +# } + if ( $bVerbose ) { print STDOUT $command.$args."\n"; } + + my $rc = system( $command.$args ); + + if( $rc < 0 ){ print STDERR "ERROR: localize rc = $rc\n"; exit( -1 ); } + ( $localizehash_ref ) = read_file( $localizeSDF , $langhash_ref ); + + } + ## Get sdf particles + open ALLPARTICLES_MERGED , "+>> $particleSDF_merged" + or die "Can't open $particleSDF_merged"; + + ## Fill fackback hash + my( $fallbackhashhash_ref ) = fetch_fallback( \@sdfparticles , $localizeSDF , $langhash_ref ); + my %block; + my $cur_fallback; + if( !$bAll) { + foreach my $cur_lang ( keys( %{ $langhash_ref } ) ){ + #print STDOUT "DBG: G1 cur_lang=$cur_lang\n"; + $cur_fallback = $langhash_ref->{ $cur_lang }; + if( $cur_fallback ne "" ){ + # Insert fallback strings + #print STDOUT "DBG: Renaming $cur_fallback to $cur_lang in fallbackhash\n"; + rename_language( $fallbackhashhash_ref , $cur_fallback , $cur_lang ); + } + foreach my $currentfile ( @sdfparticles ){ + if ( open MYFILE , "< $currentfile" ) { + while(<MYFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + chomp( $line ); + + if ( $lang eq $cur_lang ){ + # Overwrite fallback strings with collected strings + #if( ( !has_two_sourcelanguages( $cur_lang) && $cur_lang eq "de" ) || $cur_lang ne "en-US" ){ + $fallbackhashhash_ref->{ $cur_lang }{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } = $line ; + #} + + } + } + } + }else { print STDERR "WARNING: Can't open file $currentfile"; } + } + + foreach my $line ( keys( %{$fallbackhashhash_ref->{ $cur_lang } } )) { + if( #$cur_lang ne "de" && + $cur_lang ne "en-US" ){ + print ALLPARTICLES_MERGED ( $fallbackhashhash_ref->{ $cur_lang }{ $line }, "\n" ); + } + } + } + } else { + foreach my $currentfile ( @sdfparticles ){ + if ( open MYFILE , "< $currentfile" ) { + while( <MYFILE> ){ + print ALLPARTICLES_MERGED ( $_, "\n" ); # recheck de / en-US ! + } + } + else { print STDERR "WARNING: Can't open file $currentfile"; } + } + } + close ALLPARTICLES_MERGED; + + + # Hash of array + my %output; + my @order; + + ## Join both + if( $outputfile ){ + if( open DESTFILE , "+> $outputfile" ){ + if( !open LOCALIZEPARTICLE , "< $localizeSDF" ) { print STDERR "ERROR: Can't open file $localizeSDF\n"; } + if( !open ALLPARTICLES_MERGED , "< $particleSDF_merged" ) { print STDERR "ERROR: Can't open file $particleSDF_merged\n"; } + + # Insert localize + my $extract_date=""; + while ( <LOCALIZEPARTICLE> ){ + if( /$sdf_regex/ ){ + my $leftpart = defined $2 ? $2 : ''; + my $lang = defined $12 ? $12 : ''; + my $rightpart = defined $13 ? $13 : ''; + my $timestamp = defined $18 ? $18 : ''; + + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + #my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + + if( $use_default_date ) + { + $extract_date = "$default_date\n" ; + } + elsif( $extract_date eq "" ) { + $extract_date = $timestamp ; + $extract_date =~ tr/\r\n//d; + $extract_date .= "\n"; + } + + if( $bAll ){ print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date ; } + else { + foreach my $sLang ( keys( %{ $langhash_ref } ) ){ + if( $sLang=~ /all/i ) { + push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } , $leftpart."\t".$lang."\t".$rightpart.$extract_date ; + #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date; + } + #if( $sLang eq "de" && $lang eq "de" ) { + # push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } , $leftpart."\t".$lang."\t".$rightpart.$extract_date ; + #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date; + #} + if( $sLang eq "en-US" && $lang eq "en-US" ) { + push @order , $prj.$gid.$lid.$file.$type.$plattform.$helpid; + if( !$bFakeEnglish ){ push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } , $leftpart."\t".$lang."\t".$rightpart.$extract_date ; } + #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date; + } + + } + } + } + } + # Insert particles + while ( <ALLPARTICLES_MERGED> ){ + if( /$sdf_regex/ ){ + my $leftpart = defined $2 ? $2 : ''; + my $prj = defined $3 ? $3 : ''; + my $lang = defined $12 ? $12 : ''; + my $rightpart = defined $13 ? $13 : ''; + my $timestamp = defined $18 ? $18 : ''; + + #my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + #my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + + if( $use_default_date ) + { + $extract_date = "$default_date\n" ; + } + elsif( $extract_date eq "" ) + { + $extract_date = $timestamp; + } + + if( ! ( $prj =~ /binfilter/i ) ) { + push @{ $output{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } } , $leftpart."\t".$lang."\t".$rightpart.$extract_date ; + #print DESTFILE $leftpart."\t".$lang."\t".$rightpart.$extract_date ; + } + } + } + + # Write! + foreach my $curkey ( @order ){ + foreach my $curlist ( $output{ $curkey } ){ + foreach my $line ( @{$curlist} ){ + print DESTFILE $line; + } + } + } + + }else { print STDERR "Can't open $outputfile";} + } + close DESTFILE; + close LOCALIZEPARTICLE; + close ALLPARTICLES_MERGED; + + #print STDOUT "DBG: \$localizeSDF $localizeSDF \$particleSDF_merged $particleSDF_merged\n"; + unlink $localizeSDF , $particleSDF_merged , $my_localize_log; + + #sort_outfile( $outputfile ); + #remove_obsolete( $outputfile ) , if $bHasSourceLanguage ne ""; + } + +######################################################### +sub remove_obsolete{ + my $outfile = shift; + my @lines; + my $enusleftpart; + my @good_lines; + + print STDOUT "### Removing obsolete strings\n"; + + # Kick out all strings without en-US reference + if ( open ( SORTEDFILE , "< $outfile" ) ){ + while( <SORTEDFILE> ){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $language = defined $12 ? $12 : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + my $leftpart = $prj.$gid.$lid.$file.$type.$plattform.$helpid; + + if( $language eq "en-US" ){ # source string found, 1. entry + $enusleftpart = $leftpart; + push @good_lines , $line; + }else{ + if( !defined $enusleftpart or !defined $leftpart ){ + print STDERR "BADLINE: $line\n"; + print STDERR "\$enusleftpart = $enusleftpart\n"; + print STDERR "\$leftpart = $leftpart\n"; + } + if( $enusleftpart eq $leftpart ){ # matching language + push @good_lines , $line; + } + #else{ + # print STDERR "OUT: \$enusleftpart=$enusleftpart \$leftpart=$leftpart \$line=$line\n"; + #} + } + } + } + close SORTEDFILE; + } else { print STDERR "ERROR: Can't open file $outfile\n";} + + # Write file + if ( open ( SORTEDFILE , "> $outfile" ) ){ + foreach my $newline ( @good_lines ) { + print SORTEDFILE $newline; + } + close SORTEDFILE; + } else { print STDERR "ERROR: Can't open file $outfile\n";} + +} +######################################################### +sub sort_outfile{ + my $outfile = shift; + print STDOUT "### Sorting ... $outfile ..."; + my @lines; + my @sorted_lines; + + + #if ( open ( SORTEDFILE , "< $outputfile" ) ){ + if ( open ( SORTEDFILE , "< $outfile" ) ){ + my $line; + while ( <SORTEDFILE> ){ + $line = $_; + if( $line =~ /^[^\#]/ ){ + push @lines , $line; + } + } + close SORTEDFILE; + @sorted_lines = sort { + my $xa_lang = ""; + my $xa_left_part = ""; + my $xa_right_part = ""; + my $xa_timestamp = ""; + my $xb_lang = ""; + my $xb_left_part = ""; + my $xb_right_part = ""; + my $xb_timestamp = ""; + my $xa = ""; + my $xb = ""; + my @alist; + my @blist; + + if( $a=~ /$sdf_regex/ ){ + $xa_left_part = defined $2 ? $2 : ''; + $xa_lang = defined $12 ? $12 : ''; + $xa_right_part = defined $13 ? $13 : ''; + $xa_left_part = remove_last_column( $xa_left_part ); + + } + if( $b=~ /$sdf_regex/ ){ + $xb_left_part = defined $2 ? $2 : ''; + $xb_lang = defined $12 ? $12 : ''; + $xb_right_part = defined $13 ? $13 : ''; + $xb_left_part = remove_last_column( $xb_left_part ); + + + } + if( ( $xa_left_part cmp $xb_left_part ) == 0 ){ # Left part equal + if( ( $xa_lang cmp $xb_lang ) == 0 ){ # Lang equal + return ( $xa_right_part cmp $xb_right_part ); # Right part compare + } + elsif( $xa_lang eq "en-US" ) { return -1; } # en-US wins + elsif( $xb_lang eq "en-US" ) { return 1; } # en-US wins + else { return $xa_lang cmp $xb_lang; } # lang compare + } + else { + return $xa_left_part cmp $xb_left_part; # Left part compare + } + } @lines; + + if ( open ( SORTEDFILE , "> $outfile" ) ){ + print SORTEDFILE get_license_header(); + foreach my $newline ( @sorted_lines ) { + print SORTEDFILE $newline; + #print STDOUT $newline; + } + } + close SORTEDFILE; + } else { print STDERR "WARNING: Can't open file $outfile\n";} + print "done\n"; + +} +######################################################### +sub remove_last_column{ + my $string = shift; + my @alist = split ( "\t" , $string ); + pop @alist; + return join( "\t" , @alist ); +} + +######################################################### +sub rename_language{ + my $fallbackhashhash_ref = shift; + my $cur_fallback = shift; + my $cur_lang = shift; + my $line; + + foreach my $key( keys ( %{ $fallbackhashhash_ref->{ $cur_fallback } } ) ){ + $line = $fallbackhashhash_ref->{ $cur_fallback }{ $key }; + if( $line =~ /$sdf_regex/ ){ + my $leftpart = defined $2 ? $2 : ''; + my $lang = defined $12 ? $12 : ''; + my $rightpart = defined $13 ? $13 : ''; + + $fallbackhashhash_ref->{ $cur_lang }{ $key } = $leftpart."\t".$cur_lang."\t".$rightpart; + } + } +} + +############################################################ +sub remove_duplicates{ + my $list_ref = shift; + my %tmphash; + foreach my $key ( @{ $list_ref } ){ $tmphash{ $key } = '' ; } + @{$list_ref} = keys( %tmphash ); +} + +############################################################## +sub fetch_fallback{ + my $sdfparticleslist_ref = shift; + my $localizeSDF = shift; + my $langhash_ref = shift; + my %fallbackhashhash; + my $cur_lang; + my @langlist; + + foreach my $key ( keys ( %{ $langhash_ref } ) ){ + $cur_lang = $langhash_ref->{ $key }; + if ( $cur_lang ne "" ) { + push @langlist , $cur_lang; + } + } + remove_duplicates( \@langlist ); + foreach $cur_lang ( @langlist ){ + if( $cur_lang eq "en-US" ){ + read_fallbacks_from_source( $localizeSDF , $cur_lang , \%fallbackhashhash ); + } + } + + # remove de / en-US + my @tmplist; + foreach $cur_lang( @langlist ){ + if( $cur_lang ne "en-US" ){ + push @tmplist , $cur_lang; + + } + } + @langlist = @tmplist; + if ( $#langlist +1 ){ + read_fallbacks_from_particles( $sdfparticleslist_ref , \@langlist , \%fallbackhashhash ); + + } + return (\%fallbackhashhash); +} + +######################################################### +sub write_file{ + + my $localizeFile = shift; + my $index_ref = shift; + + if( open DESTFILE , "+> $localizeFile" ){ + foreach my $key( %{ $index_ref } ){ + print DESTFILE ($index_ref->{ $key }, "\n" ); + } + close DESTFILE; + }else { + print STDERR "Can't open/create '$localizeFile'"; + } +} + +######################################################### +sub read_file{ + + my $sdffile = shift; + my $langhash_ref = shift; + my %block = (); + + open MYFILE , "< $sdffile" + or die "Can't open '$sdffile'\n"; + while( <MYFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $plattform = defined $10 ? $10 : ''; + my $lang = defined $12 ? $12 : ''; + my $helpid = defined $9 ? $9 : ''; + + foreach my $isolang ( keys ( %{ $langhash_ref } ) ){ + if( $isolang=~ /$lang/i || $isolang=~ /all/i ) { $block{$prj.$gid.$lid.$file.$type.$plattform.$helpid } = $line ; } + } + } + } + return (\%block); +} + +######################################################### +sub read_fallbacks_from_particles{ + + my $sdfparticleslist_ref = shift; + my $isolanglist_ref = shift; + my $fallbackhashhash_ref = shift; + my $block_ref; + foreach my $currentfile ( @{ $sdfparticleslist_ref } ){ + if ( open MYFILE , "< $currentfile" ) { + while(<MYFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + + chomp( $line ); + + foreach my $isolang ( @{$isolanglist_ref} ){ + if( $isolang=~ /$lang/i ) { + $fallbackhashhash_ref->{ $isolang }{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } = $line ; + } + } + } + } + }else { print STDERR "WARNING: Can't open file $currentfile"; } + } +} + +######################################################### +sub read_fallbacks_from_source{ + + my $sdffile = shift; + my $isolang = shift; + my $fallbackhashhash_ref = shift; + my $block_ref; + # read fallback for single file + open MYFILE , "< $sdffile" + or die "Can't open '$sdffile'\n"; + + while( <MYFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $helpid = defined $9 ? $9 : ''; + my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + + chomp( $line ); + if( $isolang=~ /$lang/i ) { $fallbackhashhash_ref->{ $isolang }{ $prj.$gid.$lid.$file.$type.$plattform.$helpid } = $line ; + } + } + } +} + +######################################################### +sub parseLanguages{ + + my $bAll; + my $bUseLocalize; + my $bHasSourceLanguage=""; + my $bFakeEnglish=""; + my %langhash; + my $iso=""; + my $fallback=""; + + #### -l all + if( $languages=~ /all/ ){ + $bAll = "TRUE"; + $bHasSourceLanguage = "TRUE"; + } + ### -l fr=de,de + elsif( $languages=~ /.*,.*/ ){ + my @tmpstr = split "," , $languages; + for my $lang ( @tmpstr ){ + if( $lang=~ /([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)(=([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*))?/ ){ + $iso = $1; + $fallback = $4; + + if( ( $iso && $iso=~ /(en-US)/i ) || ( $fallback && $fallback=~ /(en-US)/i ) ) { + $bUseLocalize = "TRUE"; + } + if( ( $iso && $iso=~ /(en-US)/i ) ) { + $bHasSourceLanguage = "TRUE"; + } + if( $fallback ) { $langhash{ $iso } = $fallback; } + else { $langhash{ $iso } = ""; } + } + } + } + ### -l de + else{ + if( $languages=~ /([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)(=([a-zA-Z]{2,3}(-[a-zA-Z\-]*)*))?/ ){ + $iso = $1; + $fallback = $4; + + if( ( $iso && $iso=~ /(en-US)/i ) || ( $fallback && $fallback=~ /(en-US)/i ) ) { + $bUseLocalize = "TRUE"; + + } + if( ( $iso && $iso=~ /(en-US)/i ) ) { + $bHasSourceLanguage = "TRUE"; + } + + if( $fallback ) { $langhash{ $iso } = $fallback; } + else { $langhash{ $iso } = ""; } + } + } + # HACK en-US always needed! + if( !$bHasSourceLanguage ){ + #$bHasSourceLanguage = "TRUE"; + $bUseLocalize = "TRUE"; + $bFakeEnglish = "TRUE"; + $langhash{ "en-US" } = ""; + } + return ( $bAll , $bUseLocalize , \%langhash , $bHasSourceLanguage, $bFakeEnglish); +} + +######################################################### +sub parse_options{ + + my $help; + my $merge; + my $extract; + my $success = GetOptions('f=s' => \$sdffile , 'l=s' => \$languages , 's=s' => \$srcpath , 'h' => \$help , 'v' => \$bVerbose , + 'm' => \$merge , 'e' => \$extract , 'x' => \$no_sort , 'd' => \$use_default_date ); + $outputfile = $sdffile; + + #print STDOUT "DBG: lang = $languages\n"; + if( !$srcpath ){ + $srcpath = "$ENV{SRC_ROOT}"; + if( !$srcpath ){ + print STDERR "No path to the source root found!\n\n"; + usage(); + exit(1); + } + } + if( $help || !$success || $#ARGV > 1 || ( !$sdffile ) ){ + usage(); + exit(1); + } + if( $merge && $sdffile && ! ( -r $sdffile)){ + print STDERR "Can't open file '$sdffile'\n"; + exit(1); + } + if( !( $languages=~ /[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*(=[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)?(,[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*(=[a-zA-Z]{2,3}(-[a-zA-Z\-]*)*)?)*/ ) ){ + print STDERR "Please check the -l iso code\n"; + exit(1); + } + if( ( !$merge && !$extract ) || ( $merge && $extract ) ){ usage();exit( -1 );} + if( $extract ){ $mode = "extract"; } + else { $mode = "merge"; } +} + +######################################################### +sub usage{ + + print STDERR "Usage: localize.pl\n"; + print STDERR "Split or collect SDF files\n"; + print STDERR " merge: -m -f <sdffile> -l l1[=f1][,l2[=f2]][...] [ -s <sourceroot> ]\n"; + print STDERR " extract: -e -f <outputfile> -l <lang> [ -s <sourceroot> ] [-d]\n"; + print STDERR "Options:\n"; + print STDERR " -h help\n"; + print STDERR " -m Merge mode\n"; + print STDERR " -e Extract mode\n"; + print STDERR " -f <sdffile> To split a big SDF file into particles\n"; + print STDERR " <outputfile> To collect and join all particles to one big file\n"; + print STDERR " -s <sourceroot> Path to the modules, if no \$SRC_ROOT is set\n"; + print STDERR " -l ( all | <isocode> | <isocode>=fallback ) comma seperated languages\n"; + print STDERR " -d Use default date in extracted sdf file\n"; + print STDERR " -v Verbose\n"; + print STDERR "\nExample:\n"; + print STDERR "\nlocalize -e -l en-US,pt-BR=en-US -f my.sdf\n( Extract en-US and pt-BR with en-US fallback )\n"; + print STDERR "\nlocalize -m -l cs -f my.sdf\n( Merge cs translation into the sourcecode ) \n"; +} + +# my $line = defined $_ ? $_ : ''; +# my $leftpart = defined $2 ? $2 : ''; +# my $prj = defined $3 ? $3 : ''; +# my $file = defined $4 ? $4 : ''; +# my $dummy = defined $5 ? $5 : ''; +# my $type = defined $6 ? $6 : ''; +# my $gid = defined $7 ? $7 : ''; +# my $lid = defined $8 ? $8 : ''; +# my $helpid = defined $9 ? $9 : ''; +# my $plattform = defined $10 ? $10 : ''; +# my $width = defined $11 ? $11 : ''; +# my $lang = defined $12 ? $12 : ''; +# my $rightpart = defined $13 ? $13 : ''; +# my $text = defined $14 ? $14 : ''; +# my $helptext = defined $15 ? $15 : ''; +# my $quickhelptext = defined $16 ? $16 : ''; +# my $title = defined $17 ? $17 : ''; +# my $timestamp = defined $18 ? $18 : ''; + diff --git a/transex3/source/cfg_yy_wrapper.c b/transex3/source/cfg_yy_wrapper.c new file mode 100644 index 000000000000..ac678d17f399 --- /dev/null +++ b/transex3/source/cfg_yy_wrapper.c @@ -0,0 +1,2 @@ +// Helper to suppress warnings in lex generated c code, see #i57362# +#include "cfg_yy.c" diff --git a/transex3/source/cfglex.l b/transex3/source/cfglex.l new file mode 100644 index 000000000000..dd2d9a45ab59 --- /dev/null +++ b/transex3/source/cfglex.l @@ -0,0 +1,232 @@ +%{ +/* + * lexer for parsing cfg source files + * + */ + + +/* enlarge token buffer to tokenize whole strings */ +#undef YYLMAX +#define YYLMAX 64000 + +/* to enable debug output define LEXDEBUG */ +#define LEXDEBUG 1 +#ifdef LEXDEBUG +#define OUTPUT fprintf +#else +#define OUTPUT(Par1,Par2); +#endif + +/* table of possible token ids */ +#include "tokens.h" +#include <stdlib.h> +#include <stdio.h> + +#if defined __GNUC__ +#pragma GCC system_header +#elif defined __SINPRO_CC +#pragma disable_warn +#elif defined _MSC_VER +#pragma warning(push, 1) +#endif + +/* external functions (C++ code, declared as extren "C" */ +extern int WorkOnTokenSet( int, char* ); +extern int InitCfgExport( char * , char *); +extern int EndCfgExport(); +extern int GetError(); +extern int SetError(); +extern char *GetOutputFile( int argc, char* argv[]); +extern FILE *GetCfgFile(); +extern int isQuiet(); +extern void removeTempFile(); +extern char* getFilename(); +/* forwards */ +void YYWarning(); + +int bText=0; +%} + +%p 24000 +%e 1200 +%n 500 + +%% + +\<[^\>]*"xml:lang="\""x-no-translate"\"[^\<]*\/\> { + bText = 0; + WorkOnTokenSet( CFG_TOKEN_NO_TRANSLATE, yytext ); +} + +\<.*\/\> { + bText = 0; + WorkOnTokenSet( ANYTOKEN, yytext ); +} + +\<[^\>]*"xml:lang="\".*\"[^\<]*\> { + bText = 1; + WorkOnTokenSet( CFG_TEXT_START, yytext ); +} + + +\<[^\/\!][^\>]*\> { + bText = 0; + WorkOnTokenSet( CFG_TAG, yytext ); +} + +"<!"DOCTYPE[^\>]*\> { + bText = 0; + WorkOnTokenSet( CFG_TAG, yytext ); +} + + +\<\!\-\- { + char c1 = 0, c2 = 0, c3 = input(); + char pChar[2]; + pChar[1] = 0x00; + pChar[0] = c3; + + WorkOnTokenSet( COMMEND, yytext ); + WorkOnTokenSet( COMMEND, pChar ); + + for(;;) { + if ( c3 == EOF ) + break; + if ( c1 == '-' && c2 == '-' && c3 == '>' ) + break; + c1 = c2; + c2 = c3; + c3 = input(); + pChar[0] = c3; + WorkOnTokenSet( COMMEND, pChar ); + } +} + +\<\/[^\>]*\> { + bText = 0; + WorkOnTokenSet( CFG_CLOSETAG, yytext ); +} + +\<[^\>\!]*\> { + bText = 0; + if ( yytext[ 1 ] == '!' && yytext[ 2 ] == '-' && yytext[ 3 ] == '-' ) + WorkOnTokenSet( COMMEND, yytext ); + else + WorkOnTokenSet( CFG_UNKNOWNTAG, yytext ); +} + +.|\n { + if ( bText == 1 ) + WorkOnTokenSet( CFG_TEXTCHAR, yytext ); + else + WorkOnTokenSet( UNKNOWNCHAR, yytext ); +} + + +%% + +/*****************************************************************************/ +int yywrap(void) +/*****************************************************************************/ +{ + return 1; +} + +/*****************************************************************************/ +void YYWarning( char *s ) +/*****************************************************************************/ +{ + /* write warning to stderr */ + fprintf( stderr, + "Warning: \"%s\" in line %d: \"%s\"\n", s, yylineno, yytext ); +} + +/*****************************************************************************/ +#ifdef GCC +void yyerror ( char *s, ... ) +#else +void yyerror ( char *s ) +#endif +/*****************************************************************************/ +{ + /* write error to stderr */ + fprintf( stderr, + "Error: \"%s\" in line %d: \"%s\"\n", s, yylineno, yytext ); + SetError(); +} + +/*****************************************************************************/ +int +#ifdef WNT +_cdecl +#endif +main( int argc, char* argv[]) +/*****************************************************************************/ +{ + /* error level */ + int nRetValue = 0; + char *pOutput; + FILE *pFile; + + pOutput = GetOutputFile( argc, argv ); + if( !isQuiet() ){ + fprintf( stdout, "\nCfgEx 0.9 Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.\n" ); + fprintf( stdout, "======================================================================\n" ); + } + + if ( !pOutput ) { + fprintf( stdout, "Syntax: CFGEX[-p Prj][-r PrjRoot]-i FileIn [-o FileOut][-m DataBase][-e][-b][-u][-f][-d DoneFile][-g[:dtd] ][-L l1,l2,...]\n" ); + fprintf( stdout, " Prj: Project\n" ); + fprintf( stdout, " PrjRoot: Path to project root (..\\.. etc.)\n" ); + fprintf( stdout, " FileIn: Source files (*.src)\n" ); + fprintf( stdout, " FileOut: Destination file (*.*)\n" ); + fprintf( stdout, " DataBase: Mergedata (*.sdf)\n" ); + fprintf( stdout, " -QQ: quiet output\n" ); + fprintf( stdout, " -e: Disable writing errorlog\n" ); + fprintf( stdout, " -b: Break when Token \"HelpText\" found in source\n" ); + fprintf( stdout, " -u: [english] and [german] are allowed, Id is Taken from DataBase \n" ); + fprintf( stdout, " -f: force extraction and merge even if only one language is existent\n" ); + fprintf( stdout, " -g[:dtd]: enables generation of properties (dtds if :dtd is set) - in this case FileOut is the output path\n" ); + fprintf( stdout, " -d: enables generation of *.don if work is done\n" ); + fprintf( stdout, " -L: Restrict the handled languages. l1,l2,... are elements of (de,en-US...)\n" ); + fprintf( stdout, " A fallback language can be defined like this: l1=f1.\n" ); + fprintf( stdout, " f1, f2,... are also elements of (de,en-US...)\n" ); + fprintf( stdout, " Example: -L de,es=en-US\n" ); + fprintf( stdout, " Restriction to de and es, en-US will be fallback for es\n" ); + return 1; + } + + pFile = GetCfgFile(); + InitCfgExport( pOutput , getFilename() ); + if ( !pFile ) + return 1; + + yyin = pFile; + + /* create global instance of class CfgExport */ + //InitCfgExport( pOutput ); + + /* start parser */ + yylex(); + + /* get error info. and end export */ + nRetValue = GetError(); + EndCfgExport(); + + if( !isQuiet() ){ + fprintf( stdout, "\n===================================\n\n" ); + } + + removeTempFile(); +/* return error level */ + return nRetValue; +} + +/*"<!--"[^"-->"]*"-->" { + bText = 0; + WorkOnTokenSet( COMMEND, yytext ); +}*/ +/*"<!"[^\-].*\> { + bText = 0; + WorkOnTokenSet( CFG_TAG, yytext ); +}*/ diff --git a/transex3/source/cfgmerge.cxx b/transex3/source/cfgmerge.cxx new file mode 100644 index 000000000000..21b4aeff185d --- /dev/null +++ b/transex3/source/cfgmerge.cxx @@ -0,0 +1,890 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: cfgmerge.cxx,v $ + * $Revision: 1.46 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <tools/string.hxx> +#include <tools/fsys.hxx> + +// local includes +#include "export.hxx" +#include "cfgmerge.hxx" +#include "tokens.h" +#include "utf8conv.hxx" + +extern "C" { int yyerror( char * ); } +extern "C" { int YYWarning( char * ); } + +// defines to parse command line +#define STATE_NON 0x0001 +#define STATE_INPUT 0x0002 +#define STATE_OUTPUT 0x0003 +#define STATE_PRJ 0x0004 +#define STATE_ROOT 0x0005 +#define STATE_MERGESRC 0x0006 +#define STATE_ERRORLOG 0x0007 +#define STATE_UTF8 0x0008 +#define STATE_LANGUAGES 0X0009 +#define STATE_ISOCODE99 0x000A +#define STATE_FORCE 0x000B + +// set of global variables +BOOL bEnableExport; +BOOL bMergeMode; +BOOL bErrorLog; +BOOL bForce; +BOOL bUTF8; +bool bQuiet; +ByteString sPrj; +ByteString sPrjRoot; +ByteString sInputFileName; +ByteString sActFileName; +ByteString sFullEntry; +ByteString sOutputFile; +ByteString sMergeSrc; +String sUsedTempFile; + +CfgParser *pParser; + +extern "C" { +// the whole interface to lexer is in this extern "C" section + +/*****************************************************************************/ +extern char *GetOutputFile( int argc, char* argv[]) +/*****************************************************************************/ +{ + bEnableExport = FALSE; + bMergeMode = FALSE; + bErrorLog = TRUE; + bForce = FALSE; + bUTF8 = TRUE; + bQuiet = false; + sPrj = ""; + sPrjRoot = ""; + sInputFileName = ""; + sActFileName = ""; + + USHORT nState = STATE_NON; + BOOL bInput = FALSE; + + // parse command line + for( int i = 1; i < argc; i++ ) { + ByteString sSwitch( argv[ i ] ); + sSwitch.ToUpperAscii(); + + if ( sSwitch == "-I" ) { + nState = STATE_INPUT; // next token specifies source file + } + else if ( sSwitch == "-O" ) { + nState = STATE_OUTPUT; // next token specifies the dest file + } + else if ( sSwitch == "-P" ) { + nState = STATE_PRJ; // next token specifies the cur. project + } + else if ( sSwitch == "-R" ) { + nState = STATE_ROOT; // next token specifies path to project root + } + else if ( sSwitch == "-M" ) { + nState = STATE_MERGESRC; // next token specifies the merge database + } + else if ( sSwitch == "-E" ) { + nState = STATE_ERRORLOG; + bErrorLog = FALSE; + } + else if ( sSwitch == "-UTF8" ) { + nState = STATE_UTF8; + bUTF8 = TRUE; + } + else if ( sSwitch == "-NOUTF8" ) { + nState = STATE_UTF8; + bUTF8 = FALSE; + } + else if ( sSwitch == "-F" ) { + nState = STATE_FORCE; + bForce = TRUE; + } + else if ( sSwitch == "-QQ" ) { + bQuiet = true; + } + else if ( sSwitch == "-L" ) { + nState = STATE_LANGUAGES; + } + else if ( sSwitch.ToUpperAscii() == "-ISO99" ) { + nState = STATE_ISOCODE99; + } + else { + switch ( nState ) { + case STATE_NON: { + return NULL; // no valid command line + } + case STATE_INPUT: { + sInputFileName = argv[ i ]; + bInput = TRUE; // source file found + } + break; + case STATE_OUTPUT: { + sOutputFile = argv[ i ]; // the dest. file + } + break; + case STATE_PRJ: { + sPrj = ByteString( argv[ i ]); +// sPrj.ToLowerAscii(); // the project + } + break; + case STATE_ROOT: { + sPrjRoot = ByteString( argv[ i ]); // path to project root + } + break; + case STATE_MERGESRC: { + sMergeSrc = ByteString( argv[ i ]); + bMergeMode = TRUE; // activate merge mode, cause merge database found + } + break; + case STATE_LANGUAGES: { + Export::sLanguages = ByteString( argv[ i ]); + } + break; + case STATE_ISOCODE99: { + Export::sIsoCode99 = ByteString( argv[ i ]); + } + break; + } + } + } + + if ( bInput ) { + // command line is valid + bEnableExport = TRUE; + char *pReturn = new char[ sOutputFile.Len() + 1 ]; + strcpy( pReturn, sOutputFile.GetBuffer()); // #100211# - checked + return pReturn; + } + + // command line is not valid + return NULL; +} +int isQuiet(){ + if( bQuiet ) return 1; + else return 0; +} +/*****************************************************************************/ +int InitCfgExport( char *pOutput , char* pFilename ) +/*****************************************************************************/ +{ + // instanciate Export + ByteString sOutput( pOutput ); + ByteString sFilename( pFilename ); + Export::InitLanguages(); + + if ( bMergeMode ) + pParser = new CfgMerge( sMergeSrc, sOutputFile, sFilename ); + else if ( sOutputFile.Len()) + pParser = new CfgExport( sOutputFile, sPrj, sActFileName ); + + return 1; +} + +/*****************************************************************************/ +int EndCfgExport() +/*****************************************************************************/ +{ + delete pParser; + + return 1; +} + +void removeTempFile(){ + if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){ + DirEntry aTempFile( sUsedTempFile ); + aTempFile.Kill(); + } +} +extern const char* getFilename() +{ + return sInputFileName.GetBuffer(); +} +/*****************************************************************************/ +extern FILE *GetCfgFile() +/*****************************************************************************/ +{ + FILE *pFile = 0; + // look for valid filename + if ( sInputFileName.Len()) { + if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){ + DirEntry aTempFile = Export::GetTempFile(); + DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) ); + aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE ); + String sTempFile = aTempFile.GetFull(); + Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) ); + pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" ); + sUsedTempFile = sTempFile; + }else{ + // able to open file? + pFile = fopen( sInputFileName.GetBuffer(), "r" ); + sUsedTempFile = String::CreateFromAscii(""); + } + if ( !pFile ){ + fprintf( stderr, "Error: Could not open file %s\n", + sInputFileName.GetBuffer()); + exit( 13 ); + } + else { + // this is a valid file which can be opened, so + // create path to project root + DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US )); + aEntry.ToAbs(); + sFullEntry= ByteString( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( sPrjRoot ); + ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + // create file name, beginnig with project root + // (e.g.: source\ui\src\menue.src) +// printf("sFullEntry = %s\n",sFullEntry.GetBuffer()); + sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 ); +// printf("sActFileName = %s\n",sActFileName.GetBuffer()); + if( !bQuiet ) + fprintf( stdout, "\nProcessing File %s ...\n", sInputFileName.GetBuffer()); + + sActFileName.SearchAndReplaceAll( "/", "\\" ); + + return pFile; + } + } + // this means the file could not be opened + return NULL; +} + +/*****************************************************************************/ +int WorkOnTokenSet( int nTyp, char *pTokenText ) +/*****************************************************************************/ +{ + pParser->Execute( nTyp, pTokenText ); + + return 1; +} + + +/*****************************************************************************/ +int SetError() +/*****************************************************************************/ +{ + return 1; +} + +/*****************************************************************************/ +int GetError() +/*****************************************************************************/ +{ + return 0; +} +} + +// +// class CfgStackData +// + +CfgStackData* CfgStack::Push( const ByteString &rTag, const ByteString &rId ) +{ + CfgStackData *pD = new CfgStackData( rTag, rId ); + Insert( pD, LIST_APPEND ); + return pD; +} + +// +// class CfgStack +// + +/*****************************************************************************/ +CfgStack::~CfgStack() +/*****************************************************************************/ +{ + for ( ULONG i = 0; i < Count(); i++ ) + delete GetObject( i ); +} + +/*****************************************************************************/ +ByteString CfgStack::GetAccessPath( ULONG nPos ) +/*****************************************************************************/ +{ + if ( nPos == LIST_APPEND ) + nPos = Count() - 1; + + ByteString sReturn; + for ( ULONG i = 0; i <= nPos; i++ ) { + if ( i ) + sReturn += "."; + sReturn += GetStackData( i )->GetIdentifier(); + } + + return sReturn; +} + +/*****************************************************************************/ +CfgStackData *CfgStack::GetStackData( ULONG nPos ) +/*****************************************************************************/ +{ + if ( nPos == LIST_APPEND ) + nPos = Count() - 1; + + return GetObject( nPos ); +} + +// +// class CfgParser +// + +/*****************************************************************************/ +CfgParser::CfgParser() +/*****************************************************************************/ + : pStackData( NULL ), + bLocalize( FALSE ) +{ +} + +/*****************************************************************************/ +CfgParser::~CfgParser() +/*****************************************************************************/ +{ +} + + +/*****************************************************************************/ +BOOL CfgParser::IsTokenClosed( const ByteString &rToken ) +/*****************************************************************************/ +{ + return rToken.GetChar( rToken.Len() - 2 ) == '/'; +} + +/*****************************************************************************/ +void CfgParser::AddText( + ByteString &rText, + const ByteString &rIsoLang, + const ByteString &rResTyp +) +/*****************************************************************************/ +{ + USHORT nTextLen = 0; + while ( rText.Len() != nTextLen ) { + nTextLen = rText.Len(); + rText.SearchAndReplaceAll( "\n", " " ); + rText.SearchAndReplaceAll( "\r", " " ); + rText.SearchAndReplaceAll( "\t", " " ); + rText.SearchAndReplaceAll( " ", " " ); + } + pStackData->sResTyp = rResTyp; + WorkOnText( rText, rIsoLang ); + + pStackData->sText[ rIsoLang ] = rText; +} + + +/*****************************************************************************/ +void CfgParser::WorkOnRessourceEnd() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +int CfgParser::ExecuteAnalyzedToken( int nToken, char *pToken ) +/*****************************************************************************/ +{ + ByteString sToken( pToken ); + + if ( sToken == " " || sToken == "\t" ) + sLastWhitespace += sToken; + + ByteString sTokenName; + ByteString sTokenId; + + BOOL bOutput = TRUE; + + switch ( nToken ) { + case CFG_TOKEN_PACKAGE: + case CFG_TOKEN_COMPONENT: + case CFG_TOKEN_TEMPLATE: + case CFG_TOKEN_CONFIGNAME: + case CFG_TOKEN_OORNAME: + case CFG_TOKEN_OORVALUE: + case CFG_TAG: + case ANYTOKEN: + case CFG_TEXT_START: + { + sTokenName = sToken.GetToken( 1, '<' ).GetToken( 0, '>' ).GetToken( 0, ' ' ); + + if ( !IsTokenClosed( sToken )) { + ByteString sSearch; + switch ( nToken ) { + case CFG_TOKEN_PACKAGE: + sSearch = "package-id="; + break; + case CFG_TOKEN_COMPONENT: + sSearch = "component-id="; + break; + case CFG_TOKEN_TEMPLATE: + sSearch = "template-id="; + break; + case CFG_TOKEN_CONFIGNAME: + sSearch = "cfg:name="; + break; + case CFG_TOKEN_OORNAME: + sSearch = "oor:name="; + bLocalize = TRUE; + break; + case CFG_TOKEN_OORVALUE: + sSearch = "oor:value="; + break; + case CFG_TEXT_START: { + if ( sCurrentResTyp != sTokenName ) { + WorkOnRessourceEnd(); + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + pStackData->sText[ sCur ] = ByteString(""); + } + } + sCurrentResTyp = sTokenName; + + ByteString sTemp = sToken.Copy( sToken.Search( "xml:lang=" )); + sCurrentIsoLang = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' ); + + if ( sCurrentIsoLang == NO_TRANSLATE_ISO ) + bLocalize = FALSE; + + pStackData->sTextTag = sToken; + + sCurrentText = ""; + } + break; + } + if ( sSearch.Len()) { + ByteString sTemp = sToken.Copy( sToken.Search( sSearch )); + sTokenId = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' ); + } + pStackData = aStack.Push( sTokenName, sTokenId ); + + if ( sSearch == "cfg:name=" ) { + ByteString sTemp( sToken ); + sTemp.ToUpperAscii(); + bLocalize = (( sTemp.Search( "CFG:TYPE=\"STRING\"" ) != STRING_NOTFOUND ) && + ( sTemp.Search( "CFG:LOCALIZED=\"TRUE\"" ) != STRING_NOTFOUND )); + } + } + else if ( sTokenName == "label" ) { + if ( sCurrentResTyp != sTokenName ) { + WorkOnRessourceEnd(); + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + pStackData->sText[ sCur ] = ByteString(""); + } + } + sCurrentResTyp = sTokenName; + } + } + break; + case CFG_CLOSETAG: + sTokenName = sToken.GetToken( 1, '/' ).GetToken( 0, '>' ).GetToken( 0, ' ' ); + if ( aStack.GetStackData() && ( aStack.GetStackData()->GetTagType() == sTokenName )) { + if ( ! sCurrentText.Len()) + WorkOnRessourceEnd(); + aStack.Pop(); + pStackData = aStack.GetStackData(); + } + else { + ByteString sError( "Missplaced close tag: " ); + ByteString sInFile(" in file "); + sError += sToken; + sError += sInFile; + sError += sFullEntry; + Error( sError ); + exit ( 13 ); + } + break; + + case CFG_TEXTCHAR: + sCurrentText += sToken; + bOutput = FALSE; + break; + + case CFG_TOKEN_NO_TRANSLATE: + bLocalize = FALSE; + break; + } + + if ( sCurrentText.Len() && nToken != CFG_TEXTCHAR ) { + AddText( sCurrentText, sCurrentIsoLang, sCurrentResTyp ); + Output( sCurrentText ); + sCurrentText = ""; + pStackData->sEndTextTag = sToken; + } + + if ( bOutput ) + Output( sToken ); + + if ( sToken != " " && sToken != "\t" ) + sLastWhitespace = ""; + + return 1; +} + +/*****************************************************************************/ +void CfgExport::Output( const ByteString& rOutput ) +/*****************************************************************************/ +{ + // Dummy operation to suppress warnings caused by poor class design + ByteString a( rOutput ); +} + +/*****************************************************************************/ +int CfgParser::Execute( int nToken, char * pToken ) +/*****************************************************************************/ +{ + ByteString sToken( pToken ); + + switch ( nToken ) { + case CFG_TAG: + if ( sToken.Search( "package-id=" ) != STRING_NOTFOUND ) + return ExecuteAnalyzedToken( CFG_TOKEN_PACKAGE, pToken ); + else if ( sToken.Search( "component-id=" ) != STRING_NOTFOUND ) + return ExecuteAnalyzedToken( CFG_TOKEN_COMPONENT, pToken ); + else if ( sToken.Search( "template-id=" ) != STRING_NOTFOUND ) + return ExecuteAnalyzedToken( CFG_TOKEN_TEMPLATE, pToken ); + else if ( sToken.Search( "cfg:name=" ) != STRING_NOTFOUND ) + return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken ); + else if ( sToken.Search( "oor:name=" ) != STRING_NOTFOUND ) + return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken ); + else if ( sToken.Search( "oor:value=" ) != STRING_NOTFOUND ) + return ExecuteAnalyzedToken( CFG_TOKEN_OORVALUE, pToken ); + break; + } + return ExecuteAnalyzedToken( nToken, pToken ); +} + + +/*****************************************************************************/ +void CfgParser::Error( const ByteString &rError ) +/*****************************************************************************/ +{ +// ByteString sError( rError ); +// sError.Append("Error: In file "); +// sError.Append( sActFileName ); + yyerror(( char * ) rError.GetBuffer()); +} + + +// +// class CfgOutputParser +// + +/*****************************************************************************/ +CfgOutputParser::CfgOutputParser( const ByteString &rOutputFile ) +/*****************************************************************************/ +{ + pOutputStream = + new SvFileStream( + String( rOutputFile, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_WRITE | STREAM_TRUNC + ); + pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); + + if ( !pOutputStream->IsOpen()) { + ByteString sError( "ERROR: Unable to open output file: " ); + sError += rOutputFile; + Error( sError ); + delete pOutputStream; + pOutputStream = NULL; + exit( 13 ); + } +} + +/*****************************************************************************/ +CfgOutputParser::~CfgOutputParser() +/*****************************************************************************/ +{ + if ( pOutputStream ) { + pOutputStream->Close(); + delete pOutputStream; + } +} + +// +// class CfgExport +// + +/*****************************************************************************/ +CfgExport::CfgExport( + const ByteString &rOutputFile, + const ByteString &rProject, + const ByteString &rFilePath +) +/*****************************************************************************/ + : CfgOutputParser( rOutputFile ), + sPrj( rProject ), + sPath( rFilePath ) +{ + Export::InitLanguages( false ); + aLanguages = Export::GetLanguages(); +} + +/*****************************************************************************/ +CfgExport::~CfgExport() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +void CfgExport::WorkOnRessourceEnd() +/*****************************************************************************/ +{ + if ( pOutputStream && bLocalize ) { + if (( pStackData->sText[ ByteString("en-US") ].Len() + ) || + ( bForce && + ( pStackData->sText[ ByteString("de") ].Len() || + pStackData->sText[ ByteString("en-US") ].Len() ))) + { + ByteString sFallback = pStackData->sText[ ByteString("en-US") ]; + + //if ( pStackData->sText[ ByteString("en-US") ].Len()) + // sFallback = pStackData->sText[ ByteString("en-US") ]; + + ByteString sLocalId = pStackData->sIdentifier; + ByteString sGroupId; + if ( aStack.Count() == 1 ) { + sGroupId = sLocalId; + sLocalId = ""; + } + else { + sGroupId = aStack.GetAccessPath( aStack.Count() - 2 ); + } + + ByteString sTimeStamp( Export::GetTimeStamp()); + + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sText = pStackData->sText[ sCur ]; + if ( !sText.Len()) + sText = sFallback; + + Export::UnquotHTML( sText ); + + ByteString sOutput( sPrj ); sOutput += "\t"; + sOutput += sPath; + sOutput += "\t0\t"; + sOutput += pStackData->sResTyp; sOutput += "\t"; + sOutput += sGroupId; sOutput += "\t"; + sOutput += sLocalId; sOutput += "\t\t\t0\t"; + sOutput += sCur; + sOutput += "\t"; + + sOutput += sText; sOutput += "\t\t\t\t"; + sOutput += sTimeStamp; + + //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) ) + pOutputStream->WriteLine( sOutput ); + } + } + } +} + +/*****************************************************************************/ +void CfgExport::WorkOnText( + ByteString &rText, + const ByteString &rIsoLang +) +/*****************************************************************************/ +{ + if( rIsoLang.Len() ) Export::UnquotHTML( rText ); +} + + +// +// class CfgMerge +// + +/*****************************************************************************/ +CfgMerge::CfgMerge( + const ByteString &rMergeSource, const ByteString &rOutputFile, + ByteString &rFilename ) +/*****************************************************************************/ + : CfgOutputParser( rOutputFile ), + pMergeDataFile( NULL ), + pResData( NULL ), + bGerman( FALSE ), + sFilename( rFilename ), + bEnglish( FALSE ) +{ + if ( rMergeSource.Len()){ + pMergeDataFile = new MergeDataFile( + rMergeSource, sInputFileName , bErrorLog, RTL_TEXTENCODING_MS_1252, true ); + if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){ + Export::SetLanguages( pMergeDataFile->GetLanguages() ); + aLanguages = pMergeDataFile->GetLanguages(); + } + else aLanguages = Export::GetLanguages(); + }else + aLanguages = Export::GetLanguages(); +} + +/*****************************************************************************/ +CfgMerge::~CfgMerge() +/*****************************************************************************/ +{ + delete pMergeDataFile; + delete pResData; +} + +/*****************************************************************************/ +void CfgMerge::WorkOnText( + ByteString &rText, + const ByteString& nLangIndex +) +/*****************************************************************************/ +{ + + if ( pMergeDataFile && bLocalize ) { + if ( !pResData ) { + ByteString sLocalId = pStackData->sIdentifier; + ByteString sGroupId; + if ( aStack.Count() == 1 ) { + sGroupId = sLocalId; + sLocalId = ""; + } + else { + sGroupId = aStack.GetAccessPath( aStack.Count() - 2 ); + } + + ByteString sPlatform( "" ); + + pResData = new ResData( sPlatform, sGroupId , sFilename ); + pResData->sId = sLocalId; + pResData->sResTyp = pStackData->sResTyp; + } + + //if ( nLangIndex.EqualsIgnoreCaseAscii("de") ) + // bGerman = TRUE; + if (( nLangIndex.EqualsIgnoreCaseAscii("en-US") )) + bEnglish = TRUE; + + PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData ); + if ( pEntrys ) { + ByteString sContent; + pEntrys->GetText( sContent, STRING_TYP_TEXT, nLangIndex ); + + if ( Export::isAllowed( nLangIndex ) && + ( sContent != "-" ) && ( sContent.Len())) + { +#ifdef MERGE_SOURCE_LANGUAGES + if( nLangIndex.EqualsIgnoreCaseAscii("de") || nLangIndex.EqualsIgnoreCaseAscii("en-US") ) + rText = sContent; +#endif + Export::QuotHTML( rText ); + } + } + } +} + +/*****************************************************************************/ +void CfgMerge::Output( const ByteString& rOutput ) +/*****************************************************************************/ +{ + if ( pOutputStream ) + pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len()); +} + +ULONG CfgStack::Push( CfgStackData *pStackData ) +{ + Insert( pStackData, LIST_APPEND ); + return Count() - 1; +} + +/*****************************************************************************/ +void CfgMerge::WorkOnRessourceEnd() +/*****************************************************************************/ +{ + + if ( pMergeDataFile && pResData && bLocalize && (( bEnglish ) || bForce )) { + PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData ); + if ( pEntrys ) { + ByteString sCur; + + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sContent; + pEntrys->GetText( sContent, STRING_TYP_TEXT, sCur , TRUE ); + if ( + // (!sCur.EqualsIgnoreCaseAscii("de") ) && + ( !sCur.EqualsIgnoreCaseAscii("en-US") ) && + + ( sContent != "-" ) && ( sContent.Len())) + { + + ByteString sText = sContent; + Export::QuotHTML( sText ); + + ByteString sAdditionalLine( "\t" ); + + ByteString sTextTag = pStackData->sTextTag; + ByteString sTemp = sTextTag.Copy( sTextTag.Search( "xml:lang=" )); + + ByteString sSearch = sTemp.GetToken( 0, '\"' ); + sSearch += "\""; + sSearch += sTemp.GetToken( 1, '\"' ); + sSearch += "\""; + + ByteString sReplace = sTemp.GetToken( 0, '\"' ); + sReplace += "\""; + sReplace += sCur; + sReplace += "\""; + + sTextTag.SearchAndReplace( sSearch, sReplace ); + + sAdditionalLine += sTextTag; + sAdditionalLine += sText; + sAdditionalLine += pStackData->sEndTextTag; + + sAdditionalLine += "\n"; + sAdditionalLine += sLastWhitespace; + + Output( sAdditionalLine ); + } + } + } + } + delete pResData; + pResData = NULL; + bGerman = FALSE; + bEnglish = FALSE; +} diff --git a/transex3/source/directory.cxx b/transex3/source/directory.cxx new file mode 100644 index 000000000000..a4a2abc70e0f --- /dev/null +++ b/transex3/source/directory.cxx @@ -0,0 +1,265 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: directory.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <transex3/directory.hxx> +#include "tools/string.hxx" +#include <iostream> +#include <vector> +#include <algorithm> + +namespace transex +{ + +Directory::Directory( const rtl::OUString sFullpath ) : bSkipLinks( false ) +{ + sFullName = sFullpath; +} + +Directory::Directory( const rtl::OUString sFullPath , const rtl::OUString sEntry ) : bSkipLinks( false ) +{ + sFullName = sFullPath; + sDirectoryName = sEntry; +} + + +Directory::Directory( const ByteString sFullPath ) : bSkipLinks( false ) +{ + sDirectoryName = rtl::OUString( sFullPath.GetBuffer() , RTL_TEXTENCODING_UTF8 , sFullPath.Len() ); +} + +bool Directory::lessDir ( const Directory& rKey1, const Directory& rKey2 ) +{ + rtl::OUString sName1( ( static_cast< Directory >( rKey1 ) ).getDirectoryName() ); + rtl::OUString sName2( ( static_cast< Directory >( rKey2 ) ).getDirectoryName() ); + + return sName1.compareTo( sName2 ) < 0 ; +} + + +void Directory::dump() +{ + + for( std::vector< transex::File >::iterator iter = aFileVec.begin() ; iter != aFileVec.end() ; ++iter ) + { + std::cout << "FILE " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n"; + } + + for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() ; ++iter ) + { + std::cout << "DIR " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n"; + } + +} + +void Directory::scanSubDir( int nLevels ) +{ + readDirectory( sFullName ); + dump(); + if( nLevels > 0 ) { + for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() || nLevels > 0 ; ++iter , nLevels-- ) + { + ( *iter ).scanSubDir(); + } + } +} + +void Directory::setSkipLinks( bool is_skipped ) +{ + bSkipLinks = is_skipped; +} + +void Directory::readDirectory() +{ + readDirectory( sFullName ); +} + +#ifdef WNT +#include <tools/prewin.h> +#include <windows.h> +#include <tools/postwin.h> + +void Directory::readDirectory ( const rtl::OUString& sFullpath ) +{ + BOOL fFinished; + HANDLE hList; + TCHAR szDir[MAX_PATH+1]; + TCHAR szSubDir[MAX_PATH+1]; + WIN32_FIND_DATA FileData; + + rtl::OString sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() ); + const char *dirname = sFullpathext.getStr(); + + // Get the proper directory path + sprintf(szDir, "%s\\*", dirname); + + // Get the first file + hList = FindFirstFile(szDir, &FileData); + if (hList == INVALID_HANDLE_VALUE) + { + //FindClose(hList); + //printf("No files found %s\n", szDir ); return; + } + else + { + fFinished = FALSE; + while (!fFinished) + { + + sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName); + rtl::OString myfile( FileData.cFileName ); + rtl::OString mydir( szSubDir ); + + if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if ( (strcmp(FileData.cFileName, ".") != 0 ) && + (strcmp(FileData.cFileName, "..") != 0 ) ) + { + //sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName); + transex::Directory aDir( rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ), + rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) ); + aDirVec.push_back( aDir ); + } + } + else + { + transex::File aFile( rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ), + rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) ); + aFileVec.push_back( aFile ); + } + if (!FindNextFile(hList, &FileData)) + { + if (GetLastError() == ERROR_NO_MORE_FILES) + { + fFinished = TRUE; + } + } + } + } + + FindClose(hList); + + ::std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile ); + ::std::sort( aDirVec.begin() , aDirVec.end() , Directory::lessDir ); +} + +#else + +void Directory::readDirectory( const rtl::OUString& sFullpath ) +{ + struct stat statbuf; + struct stat statbuf2; + struct dirent *dirp; + DIR *dir; + //int ret; + //char *ptr; + + if( sFullpath.getLength() < 1 ) return; + + rtl::OString sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() ).getStr(); + //printf("%s\n",sFullpathext.getStr()); + const char* path = sFullpathext.getStr(); + + // stat + if( stat( path , &statbuf ) < 0 ){ printf("warning: Can not stat %s" , path ); return; }// error } + + if( S_ISDIR(statbuf.st_mode ) == 0 ) { return; }// error } return; // not dir + + if( (dir = opendir( path ) ) == NULL ) {printf("readerror 2 in %s \n",path); return; } // error } return; // error + + sFullpathext += rtl::OString( "/" ); + + const rtl::OString sDot ( "." ) ; + const rtl::OString sDDot( ".." ); + + chdir( path ); + + while( ( dirp = readdir( dir ) ) != NULL ) + { + rtl::OString sEntryName( dirp->d_name ); + + if( sEntryName.equals( sDot ) || sEntryName.equals( sDDot ) ) + continue; + + // add dir entry + rtl::OString sEntity = sFullpathext; + sEntity += sEntryName; + + // stat new entry + if( lstat( sEntity.getStr() , &statbuf2 ) < 0 ) + { + printf("error on entry %s\n" , sEntity.getStr() ) ; // error + continue; + } + + // add file / dir to vector + switch( statbuf2.st_mode & S_IFMT ) + { + case S_IFREG: + { + rtl::OString sFile = sFullpathext; + sFile += sEntryName ; + transex::File aFile( rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) , + rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() ) + ); + + aFileVec.push_back( aFile ) ; + break; + } + case S_IFLNK: + { + if( bSkipLinks ) break; + } + case S_IFDIR: + { + rtl::OString sDir = sFullpathext; + sDir += sEntryName ; + + transex::Directory aDir( + rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) , + rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() ) + ) ; + aDirVec.push_back( aDir ) ; + break; + } + } + } + chdir( ".." ); + if( closedir( dir ) < 0 ) return ; // error + + std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile ); + std::sort( aDirVec.begin() , aDirVec.end() , Directory::lessDir ); + +} + +#endif +} diff --git a/transex3/source/export.cxx b/transex3/source/export.cxx new file mode 100644 index 000000000000..5294d902d2ee --- /dev/null +++ b/transex3/source/export.cxx @@ -0,0 +1,2660 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: export.cxx,v $ + * $Revision: 1.57 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <stdlib.h> +#include <tools/fsys.hxx> +#include "export.hxx" +#include "tokens.h" +#include "utf8conv.hxx" +#include <iostream> + +extern "C" { int yyerror( char * ); } +extern "C" { int YYWarning( char * ); } + +Export *pExport = 0L; + +// defines to parse command line +#define STATE_NON 0x0001 +#define STATE_INPUT 0x0002 +#define STATE_OUTPUT 0x0003 +#define STATE_PRJ 0x0004 +#define STATE_ROOT 0x0005 +#define STATE_MERGESRC 0x0006 +#define STATE_ERRORLOG 0x0007 +#define STATE_BREAKHELP 0x0008 +#define STATE_UNMERGE 0x0009 +#define STATE_UTF8 0x000A +#define STATE_LANGUAGES 0X000B + +// set of global variables +DECLARE_LIST( FileList, ByteString * ) +FileList aInputFileList; +BOOL bEnableExport; +BOOL bMergeMode; +BOOL bErrorLog; +BOOL bBreakWhenHelpText; +BOOL bUnmerge; +BOOL bUTF8; +bool bQuiet; +ByteString sPrj; +ByteString sPrjRoot; +ByteString sActFileName; +ByteString sOutputFile; +ByteString sMergeSrc; +ByteString sTempFile; +ByteString sFile; +MergeDataFile *pMergeDataFile; +FILE *pTempFile; + + +ByteString sStrBuffer; +bool bMarcro = false; + +extern "C" { +// the whole interface to lexer is in this extern "C" section + + +/*****************************************************************************/ +extern char *GetOutputFile( int argc, char* argv[]) +/*****************************************************************************/ +{ + bEnableExport = FALSE; + bMergeMode = FALSE; + bErrorLog = TRUE; + bBreakWhenHelpText = FALSE; + bUnmerge = FALSE; + bUTF8 = TRUE; + sPrj = ""; + sPrjRoot = ""; + sActFileName = ""; + Export::sLanguages = ""; + Export::sForcedLanguages = ""; + sTempFile = ""; + pTempFile = NULL; + bQuiet = false; + USHORT nState = STATE_NON; + BOOL bInput = FALSE; + + // parse command line + for( int i = 1; i < argc; i++ ) { + ByteString sSwitch( argv[ i ] ); + + if (sSwitch == "-i" || sSwitch == "-I" ) { + nState = STATE_INPUT; // next tokens specifies source files + } + else if (sSwitch == "-o" || sSwitch == "-O" ) { + nState = STATE_OUTPUT; // next token specifies the dest file + } + else if (sSwitch == "-p" || sSwitch == "-P" ) { + nState = STATE_PRJ; // next token specifies the cur. project + } + else if (sSwitch == "-qq" || sSwitch == "-QQ" ) { + bQuiet = true; + } + + else if (sSwitch == "-r" || sSwitch == "-R" ) { + nState = STATE_ROOT; // next token specifies path to project root + } + else if (sSwitch == "-m" || sSwitch == "-M" ) { + nState = STATE_MERGESRC; // next token specifies the merge database + } + else if (sSwitch == "-e" || sSwitch == "-E" ) { + nState = STATE_ERRORLOG; + bErrorLog = FALSE; + } + else if (sSwitch == "-b" || sSwitch == "-B" ) { + nState = STATE_BREAKHELP; + bBreakWhenHelpText = TRUE; + } + else if (sSwitch == "-u" || sSwitch == "-U" ) { + nState = STATE_UNMERGE; + bUnmerge = TRUE; + bMergeMode = TRUE; + } + else if ( sSwitch.ToUpperAscii() == "-UTF8" ) { + nState = STATE_UTF8; + bUTF8 = TRUE; + } + else if ( sSwitch.ToUpperAscii() == "-NOUTF8" ) { + nState = STATE_UTF8; + bUTF8 = FALSE; + } + else if ( sSwitch == "-l" || sSwitch == "-L" ) { + nState = STATE_LANGUAGES; + } + else { + switch ( nState ) { + case STATE_NON: { + return NULL; // no valid command line + } + case STATE_INPUT: { + aInputFileList.Insert( new ByteString( argv[ i ]), LIST_APPEND ); + bInput = TRUE; // min. one source file found + } + break; + case STATE_OUTPUT: { + sOutputFile = ByteString( argv[ i ]); // the dest. file + } + break; + case STATE_PRJ: { + sPrj = ByteString( argv[ i ]); + } + break; + case STATE_ROOT: { + sPrjRoot = ByteString( argv[ i ]); // path to project root + } + break; + case STATE_MERGESRC: { + sMergeSrc = ByteString( argv[ i ]); + bMergeMode = TRUE; // activate merge mode, cause merge database found + } + break; + case STATE_LANGUAGES: { + Export::sLanguages = ByteString( argv[ i ]); + } + break; + } + } + } + if( bUnmerge ) sMergeSrc = ByteString(); + if ( bInput ) { + // command line is valid + bEnableExport = TRUE; + char *pReturn = new char[ sOutputFile.Len() + 1 ]; + strcpy( pReturn, sOutputFile.GetBuffer()); // #100211# - checked + return pReturn; + } + + // command line is not valid + return NULL; +} +/*****************************************************************************/ +int isQuiet(){ +/*****************************************************************************/ + if( bQuiet ) return 1; + else return 0; +} +/*****************************************************************************/ +int InitExport( char *pOutput , char* pFilename ) +/*****************************************************************************/ +{ + // instanciate Export + ByteString sOutput( pOutput ); + ByteString sFilename( pFilename ); + + if ( bMergeMode && !bUnmerge ) { + // merge mode enabled, so read database + pExport = new Export(sOutput, bEnableExport, sPrj, sPrjRoot, sMergeSrc , sFilename ); + } + else + // no merge mode, only export + pExport = new Export( sOutput, bEnableExport, sPrj, sPrjRoot , sFilename ); + return 1; +} + +/*****************************************************************************/ +int EndExport() +/*****************************************************************************/ +{ + delete pExport; + return 1; +} + +extern const char* getFilename() +{ + return (*(aInputFileList.GetObject( 0 ))).GetBuffer(); +} +/*****************************************************************************/ +extern FILE *GetNextFile() +/*****************************************************************************/ +{ + // look for next valid filename in input file list + if ( sTempFile.Len()) { + fclose( pTempFile ); + String sTemp( sTempFile, RTL_TEXTENCODING_ASCII_US ); + DirEntry aTemp( sTemp ); + aTemp.Kill(); + } + + while ( aInputFileList.Count()) { + ByteString sFileName( *(aInputFileList.GetObject( 0 ))); + + ByteString sOrigFile( sFileName ); + + sFileName = Export::GetNativeFile( sFileName ); + delete aInputFileList.GetObject(( ULONG ) 0 ); + aInputFileList.Remove(( ULONG ) 0 ); + + if ( sFileName == "" ) { + fprintf( stderr, "ERROR: Could not precompile File %s\n", + sOrigFile.GetBuffer()); + return GetNextFile(); + } + + sTempFile = sFileName; + Export::RemoveUTF8ByteOrderMarkerFromFile( sFileName ); + + // able to open file? + FILE *pFile = fopen( sFileName.GetBuffer(), "r" ); + if ( !pFile ) + fprintf( stderr, "Error: Could not open File %s\n", + sFileName.GetBuffer()); + else { + pTempFile = pFile; + + // this is a valid file which can be opened, so + // create path to project root + DirEntry aEntry( String( sOrigFile, RTL_TEXTENCODING_ASCII_US )); + aEntry.ToAbs(); + ByteString sFullEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( sPrjRoot ); + ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + // create file name, beginnig with project root + // (e.g.: source\ui\src\menue.src) + sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 ); + + if( !bQuiet ) fprintf( stdout, "\nProcessing File %s ...\n", sOrigFile.GetBuffer()); + + sActFileName.SearchAndReplaceAll( "/", "\\" ); + sFile = sActFileName; + + if ( pExport ) { + // create instance of class export + pExport->Init(); + } + // return the valid file handle + return pFile; + } + } + // this means the file could not be opened + return NULL; +} + +int Parse( int nTyp, const char *pTokenText ){ + pExport->Execute( nTyp , pTokenText ); + return 1; +} +void Close(){ + pExport->pParseQueue->Close(); +} +/*****************************************************************************/ +int WorkOnTokenSet( int nTyp, char *pTokenText ) +/*****************************************************************************/ +{ + + pExport->pParseQueue->Push( QueueEntry( nTyp , ByteString( pTokenText ) ) ); + return 1; +} + +} // extern + +extern "C" { +/*****************************************************************************/ +int SetError() +/*****************************************************************************/ +{ + // set error at global instance of class Export + pExport->SetError(); + return 1; +} +} + +extern "C" { +/*****************************************************************************/ +int GetError() +/*****************************************************************************/ +{ + // get error at global instance of class Export + if ( pExport->GetError()) + return 1; + return FALSE; +} +} + +// +// class ResData +// + +void ResData::Dump(){ + printf("**************\nResData\n"); + printf("sPForm = %s , sResTyp = %s , sId = %s , sGId = %s , sHelpId = %s\n",sPForm.GetBuffer() + ,sResTyp.GetBuffer(),sId.GetBuffer(),sGId.GetBuffer(),sHelpId.GetBuffer()); + + ByteString a("*pStringList"); + ByteString b("*pUIEntries"); + ByteString c("*pFilterList"); + ByteString d("*pItemList"); + ByteString e("*pPairedList"); + ByteString f("sText"); + + Export::DumpMap( f , sText ); + + if( pStringList ) Export::DumpExportList( a , *pStringList ); + if( pUIEntries ) Export::DumpExportList( b , *pUIEntries ); + if( pFilterList ) Export::DumpExportList( c , *pFilterList ); + if( pItemList ) Export::DumpExportList( d , *pItemList ); + if( pPairedList ) Export::DumpExportList( e , *pPairedList ); + printf("\n"); +} + +void ResData::addFallbackData( ByteString& sId_in , const ByteString& sText_in ){ + //printf(" ResData::addFallbackData ( sId = %s , sText = %s )\n", sId_in.GetBuffer() , sText_in.GetBuffer() ); + aFallbackData[ sId_in ] = sText_in; +} +bool ResData::getFallbackData( ByteString& sId_in , ByteString& sText_inout ){ + sText_inout = aFallbackData[ sId_in ]; + //printf("ResData::getFallbackData( sId = %s , return sText = %s \n" , sId_in.GetBuffer(), sText_inout.GetBuffer()); + return sText_inout.Len() > 0; +} + +void ResData::addMergedLanguage( ByteString& sLang ){ + aMergedLanguages[ sLang ]=ByteString("1"); +} +bool ResData::isMerged( ByteString& sLang ){ + return aMergedLanguages[ sLang ].Equals("1"); +} + +/*****************************************************************************/ +BOOL ResData::SetId( const ByteString &rId, USHORT nLevel ) +/*****************************************************************************/ +{ + if ( nLevel > nIdLevel ) + { + nIdLevel = nLevel; + sId = rId; + + if ( bChild && bChildWithText ) { + ByteString sError( "ResId after child definition" ); + yyerror( sError.GetBufferAccess()); + sError.ReleaseBufferAccess(); + SetError(); + } + + if ( sId.Len() > 255 ) { + ByteString sWarning( "LocalId > 255 chars, truncating..." ); + YYWarning( sWarning.GetBufferAccess()); + sWarning.ReleaseBufferAccess(); + sId.Erase( 255 ); + sId.EraseTrailingChars( ' ' ); + sId.EraseTrailingChars( '\t' ); + } + + return TRUE; + } + + return FALSE; +} + +// +// class Export +// + +/*****************************************************************************/ +Export::Export( const ByteString &rOutput, BOOL bWrite, + const ByteString &rPrj, const ByteString &rPrjRoot , const ByteString& rFile ) +/*****************************************************************************/ + : + pWordTransformer( NULL ), + aCharSet( RTL_TEXTENCODING_MS_1252 ), + bDefine( FALSE ), + bNextMustBeDefineEOL( FALSE ), + nLevel( 0 ), + nList( LIST_NON ), + nListIndex( 0 ), + nListLevel( 0 ), + bSkipFile( false ), + sProject( sPrj ), + sRoot( sPrjRoot ), + bEnableExport( bWrite ), + bMergeMode( bUnmerge ), + bError( FALSE ), + bReadOver( FALSE ), + bDontWriteOutput( FALSE ), + sFilename( rFile ) +{ + pParseQueue = new ParserQueue( *this ); + (void) rPrj; + (void) rPrjRoot; + (void) rFile; + + if( !isInitialized ) InitLanguages(); + // used when export is enabled + + // open output stream + if ( bEnableExport ) { + aOutput.Open( String( rOutput, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); + if( !aOutput.IsOpen() ) { + printf("ERROR : Can't open file %s\n",rOutput.GetBuffer()); + exit ( -1 ); + } + aOutput.SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); + + aOutput.SetLineDelimiter( LINEEND_CRLF ); + } +} + +/*****************************************************************************/ +Export::Export( const ByteString &rOutput, BOOL bWrite, + const ByteString &rPrj, const ByteString &rPrjRoot, + const ByteString &rMergeSource , const ByteString& rFile ) +/*****************************************************************************/ + : + pWordTransformer( NULL ), + aCharSet( RTL_TEXTENCODING_MS_1252 ), + bDefine( FALSE ), + bNextMustBeDefineEOL( FALSE ), + nLevel( 0 ), + nList( LIST_NON ), + nListIndex( 0 ), + nListLevel( 0 ), + bSkipFile( false ), + sProject( sPrj ), + sRoot( sPrjRoot ), + bEnableExport( bWrite ), + bMergeMode( TRUE ), + sMergeSrc( rMergeSource ), + bError( FALSE ), + bReadOver( FALSE ), + bDontWriteOutput( FALSE ), + sFilename( rFile ) +{ + (void) rPrj; + (void) rPrjRoot; + (void) rFile; + pParseQueue = new ParserQueue( *this ); + if( !isInitialized ) InitLanguages( bMergeMode ); + // used when merge is enabled + + // open output stream + if ( bEnableExport ) { + aOutput.Open( String( rOutput, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); + aOutput.SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); + aOutput.SetLineDelimiter( LINEEND_CRLF ); + } + +} + +/*****************************************************************************/ +void Export::Init() +/*****************************************************************************/ +{ + // resets the internal status, used before parseing another file + sActPForm = ""; + bDefine = FALSE; + bNextMustBeDefineEOL = FALSE; + nLevel = 0; + nList = LIST_NON; + nListLang = ByteString( String::CreateFromAscii(""),RTL_TEXTENCODING_ASCII_US ); + nListIndex = 0; + while ( aResStack.Count()) { + delete aResStack.GetObject(( ULONG ) 0 ); + aResStack.Remove(( ULONG ) 0 ); + } +} + +/*****************************************************************************/ +Export::~Export() +/*****************************************************************************/ +{ + if( pParseQueue ) + delete pParseQueue; + // close output stream + if ( bEnableExport ) + aOutput.Close(); + while ( aResStack.Count()) { + delete aResStack.GetObject(( ULONG ) 0 ); + aResStack.Remove(( ULONG ) 0 ); + } + + if ( bMergeMode && !bUnmerge ) { + if ( !pMergeDataFile ) + pMergeDataFile = new MergeDataFile( sMergeSrc,sFile , bErrorLog, aCharSet);//, bUTF8 ); + + //pMergeDataFile->WriteErrorLog( sActFileName ); + delete pMergeDataFile; + } +} + +/*****************************************************************************/ +int Export::Execute( int nToken, const char * pToken ) +/*****************************************************************************/ +{ + + ByteString sToken( pToken ); + ByteString sOrig( sToken ); +/* printf("+---------------\n"); + printf("sToken = %s\n",sToken.GetBuffer()); + printf("nToken = %d\n",nToken); + printf("+---------------\n"); */ + BOOL bWriteToMerged = bMergeMode; + + if ( nToken == CONDITION ) { + ByteString sTestToken( pToken ); + sTestToken.EraseAllChars( '\t' ); + sTestToken.EraseAllChars( ' ' ); + if (( !bReadOver ) && ( sTestToken.Search( "#ifndef__RSC_PARSER" ) == 0 )) + bReadOver = TRUE; + else if (( bReadOver ) && ( sTestToken.Search( "#endif" ) == 0 )) + bReadOver = FALSE; + } + if ((( nToken < FILTER_LEVEL ) || ( bReadOver )) && + (!(( bNextMustBeDefineEOL ) && ( sOrig == "\n" )))) { + // this tokens are not mandatory for parsing, so ignore them ... + if ( bMergeMode ) + WriteToMerged( sOrig , false ); // ... ore whrite them directly to dest. + return 0; + } + + ResData *pResData = NULL; + if ( nLevel ) { + // res. exists at cur. level + pResData = aResStack.GetObject( nLevel-1 ); + } + else if (( nToken != RESSOURCE ) && + ( nToken != RESSOURCEEXPR ) && + ( nToken != SMALRESSOURCE ) && + ( nToken != LEVELUP ) && + ( nToken != NORMDEFINE ) && + ( nToken != RSCDEFINE ) && + ( nToken != CONDITION ) && + ( nToken != PRAGMA )) + { + // no res. exists at cur. level so return + if ( bMergeMode ) + WriteToMerged( sOrig , false ); + return 0; + } + // #define NO_LOCALIZE_EXPORT + if( bSkipFile ){ + if ( bMergeMode ) { + WriteToMerged( sOrig , false ); + } + return 1; + } + + + if ( bDefine ) { + if (( nToken != EMPTYLINE ) && ( nToken != LEVELDOWN ) && ( nToken != LEVELUP )) { + // cur. res. defined in macro + if ( bNextMustBeDefineEOL ) { + if ( nToken != RSCDEFINELEND ) { + // end of macro found, so destroy res. + bDefine = FALSE; + if ( bMergeMode ) { + /*if ( bDontWriteOutput && bUnmerge ) { + bDontWriteOutput = FALSE; + bNextMustBeDefineEOL = FALSE; + bDefine = TRUE; + }*/ + MergeRest( pResData ); + } + bNextMustBeDefineEOL = FALSE; + Execute( LEVELDOWN, "" ); + } + else { + // next line also in macro definition + bNextMustBeDefineEOL = FALSE; + if ( bMergeMode ) + WriteToMerged( sOrig , false ); + return 1; + } + } + else if (( nToken != LISTASSIGNMENT ) && ( nToken != UIENTRIES )){ + // cur. line has macro line end + ByteString sTmpLine( sToken ); + sTmpLine.EraseAllChars( '\t' ); sTmpLine.EraseAllChars( ' ' ); + #if 0 + // impossible, unsigned is never negative + if( sTmpLine.Len() < 0 ){ + if ( sTmpLine.GetChar(( USHORT )( sTmpLine.Len() - 1 )) != '\\' ) + bNextMustBeDefineEOL = TRUE; + } + #endif + } + } + } + + BOOL bExecuteDown = FALSE; + if ( nToken != LEVELDOWN ) { + USHORT nOpen = 0; + USHORT nClose = 0; + BOOL bReadOver1 = FALSE; + USHORT i = 0; + for ( i = 0; i < sToken.Len(); i++ ) { + if ( sToken.GetChar( i ) == '\"' ) + bReadOver1 = !bReadOver1; + if ( !bReadOver1 && ( sToken.GetChar( i ) == '{' )) + nOpen++; + } + + bReadOver1 = FALSE; + for ( i = 0; i < sToken.Len(); i++ ) { + if ( sToken.GetChar( i ) == '\"' ) + bReadOver1 = !bReadOver1; + if ( !bReadOver1 && ( sToken.GetChar( i ) == '}' )) + nClose++; + } + + if ( nOpen < nClose ) + bExecuteDown = TRUE; + } + switch ( nToken ) { + + case NORMDEFINE: + //printf("sToken = '%s'",sToken.GetBuffer()); + while( sToken.SearchAndReplace( "\r", " " ) != STRING_NOTFOUND ) {}; + while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {}; + while( sToken.SearchAndReplace( " ", " " ) != STRING_NOTFOUND ) {}; + if( sToken.EqualsIgnoreCaseAscii( "#define NO_LOCALIZE_EXPORT" ) ){ + bSkipFile = true; + return 0; + } + if ( bMergeMode ) + WriteToMerged( sOrig , false ); + + return 0; + + + case RSCDEFINE: + bDefine = TRUE; // res. defined in macro + + case RESSOURCE: + case RESSOURCEEXPR: { + bDontWriteOutput = FALSE; + if ( nToken != RSCDEFINE ) + bNextMustBeDefineEOL = FALSE; + // this is the beginning of a new res. + nLevel++; + if ( nLevel > 1 ) { + aResStack.GetObject( nLevel - 2 )->bChild = TRUE; + } + + // create new instance for this res. and fill mandatory fields + + pResData = new ResData( sActPForm, FullId() , sFilename ); + aResStack.Insert( pResData, LIST_APPEND ); + ByteString sBackup( sToken ); + sToken.EraseAllChars( '\n' ); + sToken.EraseAllChars( '\r' ); + sToken.EraseAllChars( '{' ); + while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {}; + sToken.EraseTrailingChars( ' ' ); + ByteString sT = sToken.GetToken( 0, ' ' ); + pResData->sResTyp = sT.ToLowerAscii(); + ByteString sId( sToken.Copy( pResData->sResTyp.Len() + 1 )); + ByteString sCondition; + if ( sId.Search( "#" ) != STRING_NOTFOUND ) { + // between ResTyp, Id and paranthes is a precomp. condition + sCondition = "#"; + sCondition += sId.GetToken( 1, '#' ); + sId = sId.GetToken( 0, '#' ); + } + sId = sId.GetToken( 0, '/' ); + CleanValue( sId ); + sId = sId.EraseAllChars( '\t' ); + pResData->SetId( sId, ID_LEVEL_IDENTIFIER ); + if ( sCondition.Len()) { + ByteString sEmpty( "" ); + Execute( CONDITION, sEmpty.GetBufferAccess()); // execute the + // precomp. + // condition + sEmpty.ReleaseBufferAccess(); + } + } + break; + case SMALRESSOURCE: { + bDontWriteOutput = FALSE; + // this is the beginning of a new res. + bNextMustBeDefineEOL = FALSE; + nLevel++; + if ( nLevel > 1 ) { + aResStack.GetObject( nLevel - 2 )->bChild = TRUE; + } + + // create new instance for this res. and fill mandatory fields + + pResData = new ResData( sActPForm, FullId() , sFilename ); + aResStack.Insert( pResData, LIST_APPEND ); + sToken.EraseAllChars( '\n' ); + sToken.EraseAllChars( '\r' ); + sToken.EraseAllChars( '{' ); + sToken.EraseAllChars( '\t' ); + sToken.EraseAllChars( ' ' ); + sToken.EraseAllChars( '\\' ); + pResData->sResTyp = sToken.ToLowerAscii(); + } + break; + case LEVELUP: { + // push + if ( nList ) + nListLevel++; + if ( nList ) + break; + + bDontWriteOutput = FALSE; + ByteString sLowerTyp; + if ( pResData ) + sLowerTyp = "unknown"; + nLevel++; + if ( nLevel > 1 ) { + aResStack.GetObject( nLevel - 2 )->bChild = TRUE; + } + + ResData *pNewData = new ResData( sActPForm, FullId() , sFilename ); + pNewData->sResTyp = sLowerTyp; + aResStack.Insert( pNewData, LIST_APPEND ); + } + break; + case LEVELDOWN: { + // pop + if ( !nList ) { + bDontWriteOutput = FALSE; + if ( nLevel ) { + if ( bDefine && (nLevel == 1 )) { + bDefine = FALSE; + bNextMustBeDefineEOL = FALSE; + } + WriteData( pResData ); + delete aResStack.GetObject( nLevel - 1 ); + aResStack.Remove( nLevel - 1 ); + nLevel--; + } + } + else { + if ( bDefine ) + bNextMustBeDefineEOL = TRUE; + if ( !nListLevel ) { + if ( bMergeMode ) + MergeRest( pResData, MERGE_MODE_LIST ); + nList = LIST_NON; + } + else + nListLevel--; + } + } + break; + case ASSIGNMENT: { + bDontWriteOutput = FALSE; + // interpret different types of assignement + ByteString sKey = sToken.GetToken( 0, '=' ); + sKey.EraseAllChars( ' ' ); + sKey.EraseAllChars( '\t' ); + ByteString sValue = sToken.GetToken( 1, '=' ); + CleanValue( sValue ); + if ( sKey.ToUpperAscii() == "IDENTIFIER" ) { + ByteString sId( sValue.EraseAllChars( '\t' )); + pResData->SetId( sId.EraseAllChars( ' ' ), ID_LEVEL_IDENTIFIER ); + } + else if ( sKey == "HELPID" ) { + pResData->sHelpId = sValue; + } + else if ( sKey == "STRINGLIST" ) { + //if ( bUnmerge ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + //} + + pResData->bList = TRUE; + nList = LIST_STRING; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + else if ( sKey == "FILTERLIST" ) { + //if ( bUnmerge ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + //} + pResData->bList = TRUE; + nList = LIST_FILTER; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + else if ( sKey == "UIENTRIES" ) { + //if ( bUnmerge ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" ));} + pResData->bList = TRUE; + nList = LIST_UIENTRIES; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + if (( sToken.Search( "{" ) != STRING_NOTFOUND ) && + ( sToken.GetTokenCount( '{' ) > sToken.GetTokenCount( '}' ))) + { + //WorkOnTokenSet( LEVELUP, pTkn ); + Parse( LEVELUP, "" ); + } + //if ( bUnmerge && ( nListLang.EqualsIgnoreCaseAscii("de") || nListLang.EqualsIgnoreCaseAscii("en-US") ) && ListExists( pResData, nList )) + // bDontWriteOutput = TRUE; + } + break; + case UIENTRIES: + case LISTASSIGNMENT: { + bDontWriteOutput = FALSE; + ByteString sTmpToken( sToken); + sTmpToken.EraseAllChars(' '); + USHORT nPos = 0; + //nPos = sTmpToken.ToLowerAscii().Search("[de]="); + nPos = sTmpToken.ToLowerAscii().Search("[en-us]="); + if( nPos != STRING_NOTFOUND ) { + //if ( bUnmerge ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + //} + ByteString sKey = sTmpToken.Copy( 0 , nPos ); + sKey.EraseAllChars( ' ' ); + sKey.EraseAllChars( '\t' ); + ByteString sValue = sToken.GetToken( 1, '=' ); + CleanValue( sValue ); + if ( sKey.ToUpperAscii() == "STRINGLIST" ) { + pResData->bList = TRUE; + nList = LIST_STRING; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + else if ( sKey == "FILTERLIST" ) { + pResData->bList = TRUE; + nList = LIST_FILTER; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + // PairedList + else if ( sKey == "PAIREDLIST" ) { + pResData->bList = TRUE; + nList = LIST_PAIRED; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + + else if ( sKey == "ITEMLIST" ) { + pResData->bList = TRUE; + nList = LIST_ITEM; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + else if ( sKey == "UIENTRIES" ) { + pResData->bList = TRUE; + nList = LIST_UIENTRIES; + //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US ); + nListLang = SOURCE_LANGUAGE; + nListIndex = 0; + nListLevel = 0; + } + /*if ( bUnmerge && ( nListLang.EqualsIgnoreCaseAscii( "de" ) + || nListLang.EqualsIgnoreCaseAscii("en-US" ) ) + && ListExists( pResData, nList )) + bDontWriteOutput = TRUE;*/ + } + else { + // new res. is a String- or FilterList + ByteString sKey = sToken.GetToken( 0, '[' ); + sKey.EraseAllChars( ' ' ); + sKey.EraseAllChars( '\t' ); + if ( sKey.ToUpperAscii() == "STRINGLIST" ) + nList = LIST_STRING; + else if ( sKey == "FILTERLIST" ) + nList = LIST_FILTER; + else if ( sKey == "PAIREDLIST" ) + nList = LIST_PAIRED; // abcd + else if ( sKey == "ITEMLIST" ) + nList = LIST_ITEM; + else if ( sKey == "UIENTRIES" ) + nList = LIST_UIENTRIES; + if ( nList ) { + ByteString sLang=sToken.GetToken( 1, '[' ).GetToken( 0, ']' ); + CleanValue( sLang ); + nListLang = sLang; + /*if (( bUnmerge ) && ( !nListLang.EqualsIgnoreCaseAscii("de")) && ( !nListLang.EqualsIgnoreCaseAscii("en-US"))) + bDontWriteOutput = TRUE;*/ + nListIndex = 0; + nListLevel = 0; + /*if ( bUnmerge && nListLang.EqualsIgnoreCaseAscii("de") && ListExists( pResData, nList ) ) + bDontWriteOutput = TRUE;*/ + } + } + } + break; + case TEXT: + case _LISTTEXT: + case LISTTEXT: { + // this is an entry for a String- or FilterList + if ( nList ) { + SetChildWithText(); + ByteString sEntry( sToken.GetToken( 1, '\"' )); + if ( sToken.GetTokenCount( '\"' ) > 3 ) + sEntry += "\""; + if ( sEntry == "\\\"" ) + sEntry = "\""; + //sEntry = sEntry.Convert( aCharSet, RTL_TEXTENCODING_MS_1252 ); + //sEntry = sEntry.Convert( RTL_TEXTENCODING_MS_1252, RTL_TEXTENCODING_UTF8 ); + InsertListEntry( sEntry, sOrig ); + if ( bMergeMode && ( sEntry != "\"" )) { + PrepareTextToMerge( sOrig, nList, nListLang, pResData ); + } + } + } + break; + case LONGTEXTLINE: + case TEXTLINE: + bDontWriteOutput = FALSE; + if ( nLevel ) { + CutComment( sToken ); + + // this is a text line!!! + ByteString sKey = sToken.GetToken( 0, '=' ).GetToken( 0, '[' ); + sKey.EraseAllChars( ' ' ); + sKey.EraseAllChars( '\t' ); + ByteString sText( GetText( sToken, nToken )); + if ( !bMergeMode ) + sText = sText.Convert( aCharSet, RTL_TEXTENCODING_MS_1252 ); + ByteString sLang; + if ( sToken.GetToken( 0, '=' ).Search( "[" ) != STRING_NOTFOUND ) { + sLang = sToken.GetToken( 0, '=' ).GetToken( 1, '[' ).GetToken( 0, ']' ); + CleanValue( sLang ); + } + ByteString nLangIndex = sLang; + ByteString sOrigKey = sKey; + if ( sText.Len() && sLang.Len() ) { + if (( sKey.ToUpperAscii() == "TEXT" ) || + ( sKey == "MESSAGE" ) || + ( sKey == "CUSTOMUNITTEXT" ) || + ( sKey == "SLOTNAME" ) || + ( sKey == "UINAME" )) + { + //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ) + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + + SetChildWithText(); + //if ( nLangIndex.EqualsIgnoreCaseAscii("en-US") ) + if ( Export::isSourceLanguage( nLangIndex ) ) + pResData->SetId( sText, ID_LEVEL_TEXT ); + + pResData->bText = TRUE; + pResData->sTextTyp = sOrigKey; + if ( bMergeMode ) { + PrepareTextToMerge( sOrig, STRING_TYP_TEXT, nLangIndex, pResData ); + //if ( bUnmerge ) + // pResData->sText[ nLangIndex ] = sText; + } + else { + if ( pResData->sText[ nLangIndex ].Len()) { + ByteString sError( "Language " ); + sError += nLangIndex; + sError += " defined twice"; + } + pResData->sText[ nLangIndex ] = sText; + } + } + else if ( sKey == "HELPTEXT" ) { + //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + // } + SetChildWithText(); + pResData->bHelpText = TRUE; + if ( bBreakWhenHelpText ) { + ByteString sError( "\"HelpText\" found in source\n" ); + YYWarning( sError.GetBufferAccess()); + sError.ReleaseBufferAccess(); + SetError(); + } + if ( bMergeMode ) + PrepareTextToMerge( sOrig, STRING_TYP_HELPTEXT, nLangIndex, pResData ); + //if ( bUnmerge ) + // pResData->sHelpText[ nLangIndex ] = sText; + else { + if ( pResData->sHelpText[ nLangIndex ].Len()) { + ByteString sError( "Language " ); + sError += nLangIndex; + sError += " defined twice"; + } + pResData->sHelpText[ nLangIndex ] = sText; + } + } + else if ( sKey == "QUICKHELPTEXT" ) { + //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + // } + SetChildWithText(); + pResData->bQuickHelpText = TRUE; + if ( bMergeMode ) + PrepareTextToMerge( sOrig, STRING_TYP_QUICKHELPTEXT, nLangIndex, pResData ); + //if ( bUnmerge ) + // pResData->sQuickHelpText[ nLangIndex ] = sText; + else { + if ( pResData->sQuickHelpText[ nLangIndex ].Len()) { + ByteString sError( "Language " ); + sError += nLangIndex; + sError += " defined twice"; + } + pResData->sQuickHelpText[ nLangIndex ] = sText; + } + } + else if ( sKey == "TITLE" ) { + //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ){ + // ( sOrig.SearchAndReplace( "=", "[ de ] =" )); + // } + SetChildWithText(); + pResData->bTitle = TRUE; + if ( bMergeMode ) + PrepareTextToMerge( sOrig, STRING_TYP_TITLE, nLangIndex, pResData ); + //if ( bUnmerge ) + // pResData->sTitle[ nLangIndex ] = sText; + else { + if ( pResData->sTitle[ nLangIndex ].Len()) { + ByteString sError( "Language " ); + sError += nLangIndex; + sError += " defined twice"; + } + pResData->sTitle[ nLangIndex ] = sText; + } + } + else if ( sKey == "ACCESSPATH" ) { + pResData->SetId( sText, ID_LEVEL_ACCESSPATH ); + } + else if ( sKey == "FIELDNAME" ) { + pResData->SetId( sText, ID_LEVEL_FIELDNAME ); + } + } + } + break; + case NEWTEXTINRES: { + bDontWriteOutput = TRUE; + // this means something like // ### Achtung : Neuer Text ... + /*ByteString sLang( "GERMAN" ); + ByteString sText = sToken.GetToken( 2, ':' ).GetToken( 0, '*' ); + CleanValue( sText ); + if ( sText.Len()) + pResData->sText[ sLang ] = sText;*/ + } + break; + case APPFONTMAPPING: { + bDontWriteOutput = FALSE; + // this is a AppfontMapping, so look if its a definition + // of field size + ByteString sKey = sToken.GetToken( 0, '=' ); + sKey.EraseAllChars( ' ' ); + sKey.EraseAllChars( '\t' ); + ByteString sMapping = sToken.GetToken( 1, '=' ); + sMapping = sMapping.GetToken( 1, '(' ); + sMapping = sMapping.GetToken( 0, ')' ); + sMapping.EraseAllChars( ' ' ); + sMapping.EraseAllChars( '\t' ); + if ( sKey.ToUpperAscii() == "SIZE" ) { + pResData->nWidth = ( USHORT ) sMapping.GetToken( 0, ',' ).ToInt64(); + } + else if ( sKey == "POSSIZE" ) { + pResData->nWidth = ( USHORT ) sMapping.GetToken( 2, ',' ).ToInt64(); + } + } + break; + case RSCDEFINELEND: + bDontWriteOutput = FALSE; + break; + case CONDITION: { + bDontWriteOutput = FALSE; + while( sToken.SearchAndReplace( "\r", " " ) != STRING_NOTFOUND ) {}; + while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {}; + while( sToken.SearchAndReplace( " ", " " ) != STRING_NOTFOUND ) {}; + ByteString sCondition = sToken.GetToken( 0, ' ' ); + if ( sCondition == "#ifndef" ) { + sActPForm = "!defined "; + sActPForm += sToken.GetToken( 1, ' ' ); + } + else if ( sCondition == "#ifdef" ) { + sActPForm = "defined "; + sActPForm += sToken.GetToken( 1, ' ' ); + } + else if ( sCondition == "#if" ) { + sActPForm = sToken.Copy( 4 ); + while ( sActPForm.SearchAndReplace( "||", "\\or" ) != STRING_NOTFOUND ) {}; + } + else if ( sCondition == "#elif" ) { + sActPForm = sToken.Copy( 6 ); + while ( sActPForm.SearchAndReplace( "||", "\\or" ) != STRING_NOTFOUND ) {}; + } + else if ( sCondition == "#else" ) { + sActPForm = sCondition; + } + else if ( sCondition == "#endif" ) { + sActPForm = ""; + } + else break; + if ( nLevel ) { + WriteData( pResData, TRUE ); + pResData->sPForm = sActPForm; + } + } + break; + case EMPTYLINE : { + bDontWriteOutput = FALSE; + if ( bDefine ) { + bNextMustBeDefineEOL = FALSE; + bDefine = FALSE; + while ( nLevel ) + Parse( LEVELDOWN, "" ); + //WorkOnTokenSet( LEVELDOWN, pTkn ); + } + } + break; + case PRAGMA : { + bDontWriteOutput = FALSE; + while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {}; + while( sToken.SearchAndReplace( " ", " " ) != STRING_NOTFOUND ) {}; + sToken.EraseLeadingChars( ' ' ); + sToken.EraseTrailingChars( ' ' ); + + ByteString sCharset = sToken.GetToken( 1, ' ' ); + ByteString sSet = sToken.GetToken( 2, ' ' ); + if (( sCharset.ToUpperAscii() == "CHARSET_IBMPC" ) || + ( sCharset == "RTL_TEXTENCODING_IBM_850" ) || + (( sCharset == "CHARSET" ) && ( sSet.ToUpperAscii() == "IBMPC" ))) + { + aCharSet = RTL_TEXTENCODING_IBM_850; + } + else if (( sCharset == "CHARSET_ANSI" ) || + ( sCharset == "RTL_TEXTENCODING_MS_1252" ) || + (( sCharset == "CHARSET" ) && ( sSet.ToUpperAscii() == "ANSI" ))) + { + aCharSet = RTL_TEXTENCODING_MS_1252; + } + } + break; + case TEXTREFID : { + bDontWriteOutput = TRUE; + /*ByteString sK = sToken.GetToken( 0, '=' ); + ByteString sKey = sK.EraseAllChars( '\t' ).EraseAllChars( ' ' ); + ByteString sT = sToken.GetToken( 1, '=' ).GetToken( 0, ';' ); + USHORT nRefId = ( USHORT ) sT.EraseAllChars( '\t' ).EraseAllChars( ' ' ).ToInt32(); + if (( sKey.ToUpperAscii() == "TEXT" ) || + ( sKey == "MESSAGE" ) || + ( sKey == "CUSTOMUNITTEXT" ) || + ( sKey == "SLOTNAME" ) || + ( sKey == "UINAME" )) + pResData->nTextRefId = nRefId; + else if ( sKey == "HELPTEXT" ) + pResData->nHelpTextRefId = nRefId; + else if ( sKey == "QUICKHELPTEXT" ) + pResData->nQuickHelpTextRefId = nRefId; + else if ( sKey == "TITLE" ) + pResData->nTitleRefId = nRefId;*/ + } + } + if ( bWriteToMerged ) { + // the current token must be written to dest. without merging + + if( bDefine && sOrig.Len() > 2 ){ + for( USHORT n = 0 ; n < sOrig.Len() ; n++ ){ + if( sOrig.GetChar( n ) == '\n' && sOrig.GetChar( n-1 ) != '\\'){ + sOrig.Insert('\\' , n++ ); + } + } + } + WriteToMerged( sOrig , false); + } + + if ( bExecuteDown ) { + Parse( LEVELDOWN, "" ); + //WorkOnTokenSet( LEVELDOWN, pTkn ); + } + + return 1; +} + +/*****************************************************************************/ +void Export::CutComment( ByteString &rText ) +/*****************************************************************************/ +{ + if ( rText.Search( "//" ) != STRING_NOTFOUND ) { + ByteString sWork( rText ); + sWork.SearchAndReplaceAll( "\\\"", "XX" ); + USHORT i = 0; + BOOL bInner = FALSE; + + while ( i < sWork.Len() - 1 ) { + if ( sWork.GetChar( i ) == '\"' ) + bInner = !bInner; + else if + (( sWork.GetChar( i ) == '/' ) && + ( !bInner ) && + ( sWork.GetChar( i + 1 ) == '/' )) + { + rText.Erase( i ); + return; + } + i++; + } + } +} + +void Export::UnmergeUTF8( ByteString& sOrig ){ + USHORT nPos1 = sOrig.Search('\"'); + USHORT nPos2 = sOrig.SearchBackward('\"'); + if( nPos1 > 0 && nPos2 > 0 && nPos1 < nPos2){ + ByteString sPart = sOrig.Copy(nPos1+1 , nPos2-1); + ByteString sPartUTF8 = sPart; + sPartUTF8.Convert( RTL_TEXTENCODING_MS_1252 , RTL_TEXTENCODING_UTF8 ); + sOrig.SearchAndReplace( sPart , sPartUTF8 ); + } +} + +/*****************************************************************************/ +BOOL Export::ListExists( ResData *pResData, USHORT nLst ) +/*****************************************************************************/ +{ + switch ( nLst ) { + case LIST_STRING: return pResData->pStringList != NULL; + case LIST_FILTER: return pResData->pFilterList != NULL; + case LIST_ITEM: return pResData->pItemList != NULL; + case LIST_PAIRED: return pResData->pPairedList != NULL; + case LIST_UIENTRIES: return pResData->pUIEntries != NULL; + } + return FALSE; +} + +/*****************************************************************************/ +BOOL Export::WriteData( ResData *pResData, BOOL bCreateNew ) +/*****************************************************************************/ +{ + if ( bMergeMode ) { + MergeRest( pResData ); + return TRUE; + } + + if ( bUnmerge ) + return TRUE; + +/* ByteStringHashMap::iterator pos3 = pResData->sText.begin(); + ByteStringHashMap::iterator end3 = pResData->sText.end(); + for(;pos3!=end3;++pos3){ + + printf("[%s]=%s\n", pos3->first.GetBuffer(), pos3->second.GetBuffer() ); + }*/ + // mandatory to export: en-US + + if (( //pResData->sText[ ByteString("de") ].Len() && + ( pResData->sText[ SOURCE_LANGUAGE ].Len())) + || + ( //pResData->sHelpText[ ByteString("de") ].Len() && + ( pResData->sHelpText[ SOURCE_LANGUAGE ].Len())) + || + ( //pResData->sQuickHelpText[ ByteString("de") ].Len() && + ( pResData->sQuickHelpText[ SOURCE_LANGUAGE ].Len())) + || + ( //pResData->sTitle[ ByteString("de") ].Len() && + ( pResData->sTitle[ SOURCE_LANGUAGE ].Len()))) + + { + FillInFallbacks( pResData ); + + ByteString sGID = pResData->sGId; + ByteString sLID; + if ( !sGID.Len()) + sGID = pResData->sId; + else + sLID = pResData->sId; + + ByteString sXText; + ByteString sXHText; + ByteString sXQHText; + ByteString sXTitle; + + ByteString sTimeStamp( Export::GetTimeStamp()); + ByteString sCur; + + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + if ( !sCur.EqualsIgnoreCaseAscii("x-comment") ){ + if ( pResData->sText[ sCur ].Len()) + sXText = pResData->sText[ sCur ]; + else { + sXText = pResData->sText[ SOURCE_LANGUAGE ]; + /*if ( !sXText.Len()) + sXText = pResData->sText[ ByteString("en") ]; + if ( !sXText.Len()) + sXText = pResData->sText[ ByteString("de") ];*/ + } + + if ( pResData->sHelpText[ sCur ].Len()) + sXHText = pResData->sHelpText[ sCur ]; + else { + sXHText = pResData->sHelpText[ SOURCE_LANGUAGE ]; + /*if ( !sXHText.Len()) + sXHText = pResData->sHelpText[ ByteString("en") ]; + if ( !sXText.Len()) + sXHText = pResData->sHelpText[ ByteString("de") ];*/ + } + + if ( pResData->sQuickHelpText[ sCur ].Len()) + sXQHText = pResData->sQuickHelpText[ sCur ]; + else { + sXQHText = pResData->sQuickHelpText[ SOURCE_LANGUAGE ]; + /*if ( !sXQHText.Len()) + sXQHText = pResData->sQuickHelpText[ ByteString("en") ]; + if ( !sXQHText.Len()) + sXQHText = pResData->sQuickHelpText[ ByteString("de") ];*/ + } + + if ( pResData->sTitle[ sCur ].Len()) + sXTitle = pResData->sTitle[ sCur ]; + else { + sXTitle = pResData->sTitle[ SOURCE_LANGUAGE ]; + /*if ( !sXTitle.Len()) + sXTitle = pResData->sTitle[ ByteString("en") ]; + if ( !sXTitle.Len()) + sXTitle = pResData->sTitle[ ByteString("de") ];*/ + } + + if ( !sXText.Len()) + sXText = "-"; + + if ( !sXHText.Len()) { + /*if ( pResData->sHelpText[ ByteString("de") ].Len()) + sXHText = pResData->sHelpText[ ByteString("de") ];*/ + if ( pResData->sHelpText[ SOURCE_LANGUAGE ].Len()) + sXHText = pResData->sHelpText[ SOURCE_LANGUAGE ]; + /*else if ( pResData->sHelpText[ ByteString("en") ].Len()) + sXHText = pResData->sHelpText[ ByteString("en") ];*/ + } + } + else + sXText = pResData->sText[ sCur ]; + + if ( bEnableExport ) { + ByteString sOutput( sProject ); sOutput += "\t"; + if ( sRoot.Len()) + sOutput += sActFileName; + sOutput += "\t0\t"; + sOutput += pResData->sResTyp; sOutput += "\t"; + sOutput += sGID; sOutput += "\t"; + sOutput += sLID; sOutput += "\t"; + sOutput += pResData->sHelpId; sOutput += "\t"; + sOutput += pResData->sPForm; sOutput += "\t"; + sOutput += ByteString::CreateFromInt64( pResData->nWidth ); sOutput += "\t"; + sOutput += sCur; sOutput += "\t"; + + + sOutput += sXText; sOutput += "\t"; + sOutput += sXHText; sOutput += "\t"; + sOutput += sXQHText; sOutput+= "\t"; + sOutput += sXTitle; sOutput += "\t"; + sOutput += sTimeStamp; + + // if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sProject ) ) ) + aOutput.WriteLine( sOutput ); + } + + if ( bCreateNew ) { + pResData->sText[ sCur ] = ""; + pResData->sHelpText[ sCur ] = ""; + pResData->sQuickHelpText[ sCur ]= ""; + pResData->sTitle[ sCur ] = ""; + } + } + } + FillInFallbacks( pResData ); + if ( pResData->pStringList ) { + ByteString sList( "stringlist" ); + WriteExportList( pResData, pResData->pStringList, sList, bCreateNew ); + if ( bCreateNew ) + pResData->pStringList = 0; + } + if ( pResData->pFilterList ) { + ByteString sList( "filterlist" ); + WriteExportList( pResData, pResData->pFilterList, sList, bCreateNew ); + if ( bCreateNew ) + pResData->pFilterList = 0; + } + if ( pResData->pItemList ) { + ByteString sList( "itemlist" ); + WriteExportList( pResData, pResData->pItemList, sList, bCreateNew ); + if ( bCreateNew ) + pResData->pItemList = 0; + } + if ( pResData->pPairedList ) { + ByteString sList( "pairedlist" ); + WriteExportList( pResData, pResData->pPairedList, sList, bCreateNew ); + if ( bCreateNew ) + pResData->pItemList = 0; + } + if ( pResData->pUIEntries ) { + ByteString sList( "uientries" ); + WriteExportList( pResData, pResData->pUIEntries, sList, bCreateNew ); + if ( bCreateNew ) + pResData->pUIEntries = 0; + } + return TRUE; +} +ByteString Export::GetPairedListID( const ByteString& sText ){ +// < "STRING" ; IDENTIFIER ; > ; + ByteString sIdent = sText.GetToken( 1, ';' ); + sIdent.ToUpperAscii(); + while( sIdent.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {}; + sIdent.EraseTrailingChars( ' ' ); + sIdent.EraseLeadingChars( ' ' ); + return sIdent; +} +ByteString Export::GetPairedListString( const ByteString& sText ){ +// < "STRING" ; IDENTIFIER ; > ; + ByteString sString = sText.GetToken( 0, ';' ); + while( sString.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {}; + sString.EraseTrailingChars( ' ' ); + ByteString s1 = sString.Copy( sString.Search( '\"' )+1 ); + sString = s1.Copy( 0 , s1.SearchBackward( '\"' ) ); + sString.EraseTrailingChars( ' ' ); + sString.EraseLeadingChars( ' ' ); + return sString; +} +ByteString Export::StripList( const ByteString& sText ){ + ByteString s1 = sText.Copy( sText.Search( '\"' ) + 1 ); + return s1.Copy( 0 , s1.SearchBackward( '\"' ) ); +} + +/*****************************************************************************/ +BOOL Export::WriteExportList( ResData *pResData, ExportList *pExportList, + const ByteString &rTyp, BOOL bCreateNew ) +/*****************************************************************************/ +{ + ByteString sGID = pResData->sGId; + if ( !sGID.Len()) + sGID = pResData->sId; + else { + sGID += "."; + sGID += pResData->sId; + sGID.EraseTrailingChars( '.' ); + } + + ByteString sTimeStamp( Export::GetTimeStamp()); + ByteString sCur; + for ( ULONG i = 0; pExportList != NULL && i < pExportList->Count(); i++ ) { + ExportListEntry *pEntry = pExportList->GetObject( i ); + // mandatory for export: german and eng. and/or enus + //ByteString a("Export::WriteExportList::pEntry"); + //Export::DumpMap( a, *pEntry ); + + ByteString sLID( ByteString::CreateFromInt64( i + 1 )); + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + if ( //1 ) + //(*pEntry)[ ByteString("de") ].Len() && + (*pEntry)[ SOURCE_LANGUAGE ].Len() ) + //|| + // (*pEntry)[ ByteString("en") ].Len())) + { + if ( bEnableExport ) + { + ByteString sText((*pEntry)[ SOURCE_LANGUAGE ] ); + + // Strip PairList Line String + if( rTyp.EqualsIgnoreCaseAscii("pairedlist") ){ + sLID = GetPairedListID( sText ); + if ((*pEntry)[ sCur ].Len()) + sText = (*pEntry)[ sCur ]; + sText = GetPairedListString( sText ); + } + else{ + //if ((*pEntry)[ sCur ].Len()){ + // if( sCur.EqualsIgnoreCaseAscii("de") ){ + // sText = StripList( (*pEntry)[ sCur ] ); + // } + // else + sText = StripList( (*pEntry)[ sCur ] ); + if( sText == "\\\"" ) + sText = "\""; + //} + } + + ByteString sOutput( sProject ); sOutput += "\t"; + if ( sRoot.Len()) + sOutput += sActFileName; + sOutput += "\t0\t"; + sOutput += rTyp; sOutput += "\t"; + sOutput += sGID; sOutput += "\t"; + sOutput += sLID; sOutput += "\t\t"; + sOutput += pResData->sPForm; sOutput += "\t0\t"; + sOutput += sCur; sOutput += "\t"; + + sOutput += sText; sOutput += "\t\t\t\t"; + sOutput += sTimeStamp; + + //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sProject ) ) ) + aOutput.WriteLine( sOutput ); + + } + } + } + if ( bCreateNew ) + delete [] pEntry; + } + if ( bCreateNew ) + delete pExportList; + + return TRUE; +} + +/*****************************************************************************/ +ByteString Export::FullId() +/*****************************************************************************/ +{ + ByteString sFull; + if ( nLevel > 1 ) { + sFull = aResStack.GetObject( 0 )->sId; + for ( USHORT i = 1; i < nLevel - 1; i++ ) { + ByteString sToAdd = aResStack.GetObject( i )->sId; + if ( sToAdd.Len()) { + sFull += "."; + sFull += sToAdd; + } + } + } + if ( sFull.Len() > 255 ) { + ByteString sError( "GroupId > 255 chars" ); + printf("GroupID = %s\n",sFull.GetBuffer()); + yyerror( sError.GetBufferAccess()); + sError.ReleaseBufferAccess(); + } + + return sFull; +} + +/*****************************************************************************/ +void Export::InsertListEntry( const ByteString &rText, const ByteString &rLine ) +/*****************************************************************************/ +{ + ResData *pResData = aResStack.GetObject( nLevel-1 ); + + ExportList *pList = NULL; + if ( nList == LIST_STRING ) { + pList = pResData->pStringList; + if ( !pList ) { + pResData->pStringList = new ExportList(); + pList = pResData->pStringList; + nListIndex = 0; + } + } + else if ( nList == LIST_FILTER ) { + pList = pResData->pFilterList; + if ( !pList ) { + pResData->pFilterList = new ExportList(); + pList = pResData->pFilterList; + nListIndex = 0; + } + } + else if ( nList == LIST_ITEM ) { + pList = pResData->pItemList; + if ( !pList ) { + pResData->pItemList = new ExportList(); + pList = pResData->pItemList; + nListIndex = 0; + } + } + else if ( nList == LIST_PAIRED ) { + pList = pResData->pPairedList; + if ( !pList ) { + pResData->pPairedList = new ExportList(); + pList = pResData->pPairedList; + nListIndex = 0; + } + } + else if ( nList == LIST_UIENTRIES ) { + pList = pResData->pUIEntries; + if ( !pList ) { + pResData->pUIEntries = new ExportList(); + pList = pResData->pUIEntries; + nListIndex = 0; + } + } + else + return; + + if ( nListIndex + 1 > pList->Count()) { + ExportListEntry *pNew = new ExportListEntry(); + (*pNew)[ LIST_REFID ] = ByteString::CreateFromInt32( REFID_NONE ); + pList->Insert( pNew, LIST_APPEND ); + } + ExportListEntry *pCurEntry = pList->GetObject( nListIndex ); + + // For paired list use the line to set proper lid + if( nList == LIST_PAIRED ){ + (*pCurEntry)[ nListLang ] = rLine; + }else + (*pCurEntry)[ nListLang ] = rText; + + // Remember en-US fallback string, so each list has the same amount of elements + //if ( nListLang.EqualsIgnoreCaseAscii("en-US") ) { + if ( Export::isSourceLanguage( nListLang ) ) { + if( nList == LIST_PAIRED ){ + const ByteString sPlist("pairedlist"); + ByteString sKey = MergeDataFile::CreateKey( sPlist , pResData->sId , GetPairedListID( rLine ) , sFilename ); + pResData->addFallbackData( sKey , rText ); + } + // new fallback + else{ + const ByteString sPlist("list"); + ByteString a( pResData->sGId ); + a.Append( "." ); + a.Append( pResData->sId ); + sal_Int64 x = nListIndex+1; + ByteString b( ByteString::CreateFromInt64( x ) ); + ByteString sKey = MergeDataFile::CreateKey( sPlist , a , b , sFilename ); + pResData->addFallbackData( sKey , rText ); + } + // new fallback + } + + //if ( nListLang.EqualsIgnoreCaseAscii("en-US") ) { + if ( Export::isSourceLanguage( nListLang ) ) { + if( nList == LIST_PAIRED ){ + (*pCurEntry)[ SOURCE_LANGUAGE ] = rLine; + } + else + (*pCurEntry)[ SOURCE_LANGUAGE ] = rLine; + + pList->NewSourceLanguageListEntry(); + } + + //printf("Export::InsertListEntry ResData.id = %s ResData.ListData = %s\n",pResData->sId.GetBuffer() ,(*pCurEntry)[ nListLang ].GetBuffer()); + nListIndex++; +} + +/*****************************************************************************/ +void Export::CleanValue( ByteString &rValue ) +/*****************************************************************************/ +{ + while ( rValue.Len()) { + if (( rValue.GetChar( 0 ) == ' ' ) || ( rValue.GetChar( 0 ) == '\t' )) + rValue = rValue.Copy( 1 ); + else + break; + } + + if ( rValue.Len()) { + for ( USHORT i = rValue.Len() - 1; i > 0; i-- ) { + if (( rValue.GetChar( i ) == ' ' ) || ( rValue.GetChar( i ) == '\t' ) || + ( rValue.GetChar( i ) == '\n' ) || ( rValue.GetChar( i ) == ';' ) || + ( rValue.GetChar( i ) == '{' ) || ( rValue.GetChar( i ) == '\\' ) || + ( rValue.GetChar( i ) == '\r' )) + rValue.Erase( i ); + else + break; + } + } +} + + +/*****************************************************************************/ +ByteString Export::GetText( const ByteString &rSource, int nToken ) +/*****************************************************************************/ +#define TXT_STATE_NON 0x000 +#define TXT_STATE_TEXT 0x001 +#define TXT_STATE_MACRO 0x002 +{ + ByteString sReturn; + switch ( nToken ) { + case TEXTLINE: + case LONGTEXTLINE: { + ByteString sTmp( rSource.Copy( rSource.Search( "=" ))); + CleanValue( sTmp ); + sTmp.EraseAllChars( '\n' ); + sTmp.EraseAllChars( '\r' ); + + while ( sTmp.SearchAndReplace( "\\\\\"", "-=<[BSlashBSlashHKom]>=-\"" ) + != STRING_NOTFOUND ) {}; + while ( sTmp.SearchAndReplace( "\\\"", "-=<[Hochkomma]>=-" ) + != STRING_NOTFOUND ) {}; + while ( sTmp.SearchAndReplace( "\\", "-=<[0x7F]>=-" ) + != STRING_NOTFOUND ) {}; + while ( sTmp.SearchAndReplace( "\\0x7F", "-=<[0x7F]>=-" ) + != STRING_NOTFOUND ) {}; + + USHORT nStart = 0; + USHORT nState = TXT_STATE_MACRO; + + nState = TXT_STATE_TEXT; + nStart = 1; + + + for ( USHORT i = nStart; i < sTmp.GetTokenCount( '\"' ); i++ ) { + ByteString sToken = sTmp.GetToken( i, '\"' ); + if ( sToken.Len()) { + if ( nState == TXT_STATE_TEXT ) { + sReturn += sToken; + nState = TXT_STATE_MACRO; + } + else { + while( sToken.SearchAndReplace( "\t", " " ) != + STRING_NOTFOUND ) {}; + while( sToken.SearchAndReplace( " ", " " ) != + STRING_NOTFOUND ) {}; + sToken.EraseLeadingChars( ' ' ); + sToken.EraseTrailingChars( ' ' ); + if ( sToken.Len()) { + sReturn += "\\\" "; + sReturn += sToken; + sReturn += " \\\""; + } + nState = TXT_STATE_TEXT; + } + } + } + + while ( sReturn.SearchAndReplace( "-=<[0x7F]>=-", "" ) + != STRING_NOTFOUND ) {}; + while ( sReturn.SearchAndReplace( "-=<[Hochkomma]>=-", "\"" ) + != STRING_NOTFOUND ) {}; + while ( sReturn.SearchAndReplace( "-=<[BSlashBSlashHKom]>=-", "\\\\" ) + != STRING_NOTFOUND ) {}; + + + while ( sReturn.SearchAndReplace( "\\\\", "-=<[BSlashBSlash]>=-" ) + != STRING_NOTFOUND ) {}; + while ( sReturn.SearchAndReplace( "-=<[BSlashBSlash]>=-", "\\" ) + != STRING_NOTFOUND ) {}; + + } + break; + } + return sReturn; +} + +/*****************************************************************************/ +void Export::WriteToMerged( const ByteString &rText , bool bSDFContent ) +/*****************************************************************************/ +{ + static ByteString SLASH ('\\'); + static ByteString RETURN ('\n'); + //printf("%s\n",rText.GetBuffer() ); + + #if 0 + // statement has no effect + if( pParseQueue->bMflag && !bSDFContent ) pParseQueue->bMflag; + #endif + + if ( !bDontWriteOutput || !bUnmerge ) { + ByteString sText( rText ); + while ( sText.SearchAndReplace( " \n", "\n" ) != STRING_NOTFOUND ) {}; + if( pParseQueue->bNextIsM && bSDFContent && sText.Len() > 2 ){ + for( USHORT n = 0 ; n < sText.Len() ; n++ ){ + if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){ + sText.Insert('\\' , n++ ); + + } + } + } + else if( pParseQueue->bLastWasM && sText.Len() > 2 ){ + for( USHORT n = 0 ; n < sText.Len() ; n++ ){ + if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){ + sText.Insert('\\' , n++ ); + } + if( sText.GetChar( n ) == '\n' )pParseQueue->bMflag=true; + } + } + else if( pParseQueue->bCurrentIsM && bSDFContent && sText.Len() > 2 ){ + for( USHORT n = 0 ; n < sText.Len() ; n++ ){ + if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){ + sText.Insert('\\' , n++ ); + pParseQueue->bMflag=true; + } + } + } + else if( pParseQueue->bMflag ){ + for( USHORT n = 1 ; n < sText.Len() ; n++ ){ + if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){ + sText.Insert('\\' , n++ ); + } + } + } + for ( USHORT i = 0; i < sText.Len(); i++ ) { + if ( sText.GetChar( i ) != '\n' ){ + aOutput.Write( ByteString( sText.GetChar( i )).GetBuffer(), 1 ); + + } + else{ + aOutput.WriteLine( ByteString()); + } + + } + } +} + +/*****************************************************************************/ +void Export::ConvertMergeContent( ByteString &rText ) +/*****************************************************************************/ +{ + BOOL bNoOpen = ( rText.Search( "\\\"" ) != 0 ); + ByteString sClose( rText.Copy( rText.Len() - 2 )); + BOOL bNoClose = ( sClose != "\\\"" ); + ByteString sNew; + for ( USHORT i = 0; i < rText.Len(); i++ ) { + ByteString sChar( rText.GetChar( i )); + if ( sChar == "\\" ) { + if (( i + 1 ) < rText.Len()) { + ByteString sNext( rText.GetChar( i + 1 )); + if ( sNext == "\"" ) { + sChar = "\""; + i++; + } + else if ( sNext == "n" ) { + sChar = "\\n"; + i++; + } + else if ( sNext == "t" ) { + sChar = "\\t"; + i++; + } + else if ( sNext == "\'" ) { + sChar = "\\\'"; + i++; + } + else + sChar = "\\\\"; + } + else { + sChar = "\\\\"; + } + } + else if ( sChar == "\"" ) { + sChar = "\\\""; + } + else if ( sChar == "" ) { + sChar = "\\0x7F"; + } + sNew += sChar; + } + + rText = sNew; + + if ( bNoOpen ) { + ByteString sTmp( rText ); + rText = "\""; + rText += sTmp; + } + if ( bNoClose ) + rText += "\""; +} + +/*****************************************************************************/ +BOOL Export::PrepareTextToMerge( ByteString &rText, USHORT nTyp, + ByteString &nLangIndex, ResData *pResData ) +/*****************************************************************************/ +{ + // position to merge in: + USHORT nStart = 0; + USHORT nEnd = 0; + ByteString sOldId = pResData->sId; + ByteString sOldGId = pResData->sGId; + ByteString sOldTyp = pResData->sResTyp; + + ByteString sOrigText( rText ); + + switch ( nTyp ) { + case LIST_STRING : + case LIST_UIENTRIES : + case LIST_FILTER : + case LIST_PAIRED: + case LIST_ITEM : + { + if ( bUnmerge ) + return TRUE; + + ExportList *pList = NULL; + switch ( nTyp ) { + case LIST_STRING : { + pResData->sResTyp = "stringlist"; + pList = pResData->pStringList; + } + break; + case LIST_UIENTRIES : { + pResData->sResTyp = "uientries"; + pList = pResData->pUIEntries; + } + break; + case LIST_FILTER : { + pResData->sResTyp = "filterlist"; + pList = pResData->pFilterList; + } + break; + case LIST_ITEM : { + pResData->sResTyp = "itemlist"; + pList = pResData->pItemList; + } + break; + case LIST_PAIRED : { + pResData->sResTyp = "pairedlist"; + pList = pResData->pPairedList; + } + break; + + } + if ( pList ) { + ExportListEntry *pCurEntry = pList->GetObject( nListIndex - 1 ); + if ( pCurEntry ) { + //printf("%s\n",Export::DumpMap( "pCurEntry", *pCurEntry ).GetBuffer() ); + //ByteString a("pCurEntry"); + //Export::DumpMap( a , *pCurEntry ); + rText = (*pCurEntry)[ SOURCE_LANGUAGE ]; + if( nTyp == LIST_PAIRED ){ + pResData->addMergedLanguage( nLangIndex ); + } + } + } + + nStart = rText.Search( "\"" ); + if ( nStart == STRING_NOTFOUND ) { + rText = sOrigText; + return FALSE; + } + + BOOL bFound = FALSE; + for ( nEnd = nStart + 1; nEnd < rText.Len() && !bFound; nEnd++ ) { + if ( rText.GetChar( nEnd ) == '\"' ) + bFound = TRUE; + } + if ( !bFound ) { + rText = sOrigText; + return FALSE; + } + + nEnd --; + sLastListLine = rText; + if (( sLastListLine.Search( ">" ) != STRING_NOTFOUND ) && + ( sLastListLine.Search( "<" ) == STRING_NOTFOUND )) + { + ByteString sTmp = sLastListLine; + sLastListLine = "<"; + sLastListLine += sTmp; + } + if ( pResData->sResTyp.EqualsIgnoreCaseAscii( "pairedlist" ) ){ + pResData->sId = GetPairedListID( sLastListLine ); + } + else pResData->sId = ByteString::CreateFromInt32( nListIndex ); + + if ( pResData->sGId.Len()) + pResData->sGId += "."; + pResData->sGId += sOldId; + nTyp = STRING_TYP_TEXT; + } + break; + case STRING_TYP_TEXT : + case STRING_TYP_HELPTEXT : + case STRING_TYP_QUICKHELPTEXT : + case STRING_TYP_TITLE : + { + /*if ( bUnmerge ) { + if (( nLangIndex != ByteString("de") ) && + ( nLangIndex != ByteString("en-US") )) + { + bDontWriteOutput = TRUE; + } + return TRUE; + }*/ + + nStart = rText.Search( "=" ); + if ( nStart == STRING_NOTFOUND ) { + rText = sOrigText; + return FALSE; + } + + nStart++; + BOOL bFound = FALSE; + while(( nStart < rText.Len()) && !bFound ) { + if (( rText.GetChar( nStart ) != ' ' ) && ( rText.GetChar( nStart ) != '\t' )) + bFound = TRUE; + else + nStart ++; + } + + // no start position found + if ( !bFound ) { + rText = sOrigText; + return FALSE; + } + + // position to end mergeing in + nEnd = rText.Len() - 1; + bFound = FALSE; + + while (( nEnd > nStart ) && !bFound ) { + if (( rText.GetChar( nEnd ) != ' ' ) && ( rText.GetChar( nEnd ) != '\t' ) && + ( rText.GetChar( nEnd ) != '\n' ) && ( rText.GetChar( nEnd ) != ';' ) && + ( rText.GetChar( nEnd ) != '{' ) && ( rText.GetChar( nEnd ) != '\\' )) + { + bFound = TRUE; + } + else + nEnd --; + } + } + break; + } + + // search for merge data + if ( !pMergeDataFile ){ + pMergeDataFile = new MergeDataFile( sMergeSrc, sFile , bErrorLog, aCharSet);//, bUTF8 ); + + // Init Languages + ByteString sTmp = Export::sLanguages; + if( sTmp.ToUpperAscii().Equals("ALL") ) + SetLanguages( pMergeDataFile->GetLanguages() ); + else if( !isInitialized )InitLanguages(); + + } +// printf("*************DUMPING****************\n"); +// printf("%s\n",pMergeDataFile->Dump().GetBuffer()); +// printf("*************DUMPING****************\n"); + +// printf("Dumping ResData\n"); +// pResData->Dump(); + PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); + //printf("Dumping pEntrys\n"); + //if( pEntrys ) pEntrys->Dump(); + pResData->sId = sOldId; + pResData->sGId = sOldGId; + pResData->sResTyp = sOldTyp; + + if ( !pEntrys ) { + rText = sOrigText; + return FALSE; // no data found + } + + ByteString sContent; + pEntrys->GetText( sContent, nTyp, nLangIndex ); + //if ( !sContent.Len() && ( ! nLangIndex.EqualsIgnoreCaseAscii("en-US") )) { + if ( !sContent.Len() && ( ! Export::isSourceLanguage( nLangIndex ) )) { + rText = sOrigText; + return FALSE; // no data found + } + + //if ( nLangIndex.EqualsIgnoreCaseAscii("en-US") ) { + if ( Export::isSourceLanguage( nLangIndex ) ) { + return FALSE; + } + + ByteString sPostFix( rText.Copy( ++nEnd )); + rText.Erase( nStart ); + + //ConvertMergeContent( sContent, nTyp ); + ConvertMergeContent( sContent ); + + + + //printf("Merged %s\n",nLangIndex.GetBuffer()); + // merge new res. in text line + rText += sContent; + rText += sPostFix; + + return TRUE; +} + +/*****************************************************************************/ +void Export::MergeRest( ResData *pResData, USHORT nMode ) +/*****************************************************************************/ +{ + //if ( bUnmerge ) { return;} + + //pResData->Dump(); + + if ( !pMergeDataFile ){ + pMergeDataFile = new MergeDataFile( sMergeSrc, sFile ,bErrorLog, aCharSet);//, bUTF8 ); + + // Init Languages + ByteString sTmp = Export::sLanguages; + if( sTmp.ToUpperAscii().Equals("ALL") ) + SetLanguages( pMergeDataFile->GetLanguages() ); + else if( !isInitialized )InitLanguages(); + + } + switch ( nMode ) { + case MERGE_MODE_NORMAL : { + PFormEntrys *pEntry = pMergeDataFile->GetPFormEntrys( pResData ); + + bool bWriteNoSlash = false; + if ( pEntry && pResData->bText ) { + + BOOL bAddSemikolon = FALSE; + BOOL bFirst = TRUE; + ByteString sCur; + ByteString sTmp = Export::sLanguages; + + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sText; + BOOL bText = pEntry->GetText( sText, STRING_TYP_TEXT, sCur , TRUE ); + if ( bText && sText.Len() && sText != "-" ) { + ByteString sOutput; + if ( bNextMustBeDefineEOL) { + if ( bFirst ) + sOutput += "\t\\\n"; + else + sOutput += ";\t\\\n"; + } + bFirst=FALSE; + sOutput += "\t"; + sOutput += pResData->sTextTyp; + //if ( !sCur.EqualsIgnoreCaseAscii("en-US")) { + if ( ! Export::isSourceLanguage( sCur ) ) { + sOutput += "[ "; + sOutput += sCur; + sOutput += " ] "; + } + sOutput += "= "; + ConvertMergeContent( sText ); + sOutput += sText; + + if ( bDefine && bWriteNoSlash ) + sOutput += ";\n"; + + if ( bDefine ) + sOutput += ";\\\n"; + else if ( !bNextMustBeDefineEOL ) + sOutput += ";\n"; + else + bAddSemikolon = TRUE; + for ( USHORT j = 1; j < nLevel; j++ ) + sOutput += "\t"; + WriteToMerged( sOutput , true ); + } + } + + + if ( bAddSemikolon ) { + ByteString sOutput( ";" ); + WriteToMerged( sOutput , false ); + } + } + + if ( pEntry && pResData->bQuickHelpText ) { + BOOL bAddSemikolon = FALSE; + BOOL bFirst = TRUE; + ByteString sCur; + + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sText; + BOOL bText = pEntry->GetText( sText, STRING_TYP_QUICKHELPTEXT, sCur, TRUE ); + if ( bText && sText.Len() && sText != "-" ) { + ByteString sOutput; + if ( bNextMustBeDefineEOL) { + if ( bFirst ) + sOutput += "\t\\\n"; + else + sOutput += ";\t\\\n"; + } + bFirst=FALSE; + sOutput += "\t"; + sOutput += "QuickHelpText"; + //if ( !sCur.EqualsIgnoreCaseAscii("en-US") ) { + if ( ! Export::isSourceLanguage( sCur ) ) { + sOutput += "[ "; + sOutput += sCur; + sOutput += " ] "; + } + sOutput += "= "; + ConvertMergeContent( sText ); + sOutput += sText; + if ( bDefine ) + sOutput += ";\\\n"; + else if ( !bNextMustBeDefineEOL ) + sOutput += ";\n"; + else + bAddSemikolon = TRUE; + for ( USHORT j = 1; j < nLevel; j++ ) + sOutput += "\t"; + WriteToMerged( sOutput ,true ); + } + } + if ( bAddSemikolon ) { + ByteString sOutput( ";" ); + WriteToMerged( sOutput , false ); + } + } + + if ( pEntry && pResData->bTitle ) { + BOOL bAddSemikolon = FALSE; + BOOL bFirst = TRUE; + ByteString sCur; + + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sText; + BOOL bText = pEntry->GetText( sText, STRING_TYP_TITLE, sCur, TRUE ); + if ( bText && sText.Len() && sText != "-" ) { + ByteString sOutput; + if ( bNextMustBeDefineEOL) { + if ( bFirst ) + sOutput += "\t\\\n"; + else + sOutput += ";\t\\\n"; + } + bFirst=FALSE; + sOutput += "\t"; + sOutput += "Title"; + //if ( !sCur.EqualsIgnoreCaseAscii("en-US") ) { + if ( ! Export::isSourceLanguage( sCur ) ) { + sOutput += "[ "; + sOutput += sCur; + sOutput += " ] "; + } + sOutput += "= "; + ConvertMergeContent( sText ); + sOutput += sText; + if ( bDefine ) + sOutput += ";\\\n"; + else if ( !bNextMustBeDefineEOL ) + sOutput += ";\n"; + else + bAddSemikolon = TRUE; + for ( USHORT j = 1; j < nLevel; j++ ) + sOutput += "\t"; + WriteToMerged( sOutput ,true ); + } + } + if ( bAddSemikolon ) { + ByteString sOutput( ";" ); + WriteToMerged( sOutput ,false); + } + } + // Merge Lists + + if ( pResData->bList ) { + //printf("Dumping ResData\n"); + //pResData->Dump(); + + bool bPairedList = false; + ByteString sOldId = pResData->sId; + ByteString sOldGId = pResData->sGId; + ByteString sOldTyp = pResData->sResTyp; + if ( pResData->sGId.Len()) + pResData->sGId += "."; + pResData->sGId += sOldId; + ByteString sSpace; + for ( USHORT i = 1; i < nLevel-1; i++ ) + sSpace += "\t"; + for ( USHORT nT = LIST_STRING; nT <= LIST_UIENTRIES; nT++ ) { + ExportList *pList = NULL; + switch ( nT ) { + case LIST_STRING : pResData->sResTyp = "stringlist"; pList = pResData->pStringList; bPairedList = false; break; + case LIST_FILTER : pResData->sResTyp = "filterlist"; pList = pResData->pFilterList; bPairedList = false; break; + case LIST_UIENTRIES : pResData->sResTyp = "uientries"; pList = pResData->pUIEntries;bPairedList = false; break; + case LIST_ITEM : pResData->sResTyp = "itemlist"; pList = pResData->pItemList; bPairedList = false; break; + case LIST_PAIRED : pResData->sResTyp = "pairedlist"; pList = pResData->pPairedList; bPairedList = true; break; + } + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + USHORT nIdx = 1; + + // Set matching pairedlist identifier + if( bPairedList && pResData->pPairedList && ( nIdx == 1 ) ){ + ExportListEntry* pListE = ( ExportListEntry* ) pResData->pPairedList->GetObject( nIdx-1 ); + pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] ); + } + else + pResData->sId = ByteString("1"); + + PFormEntrys *pEntrys; + ULONG nLIndex = 0; + ULONG nMaxIndex = 0; + if ( pList ) + nMaxIndex = pList->GetSourceLanguageListEntryCount(); + pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); + while( pEntrys && ( nLIndex < nMaxIndex )) { + //printf("Lang %s, List Index %d\n",sCur.GetBuffer(),(int)nLIndex); + ByteString sText; + BOOL bText; + bText = pEntrys->GetText( sText, STRING_TYP_TEXT, sCur, TRUE ); + if( !bText ) + bText = pEntrys->GetText( sText , STRING_TYP_TEXT, SOURCE_LANGUAGE , FALSE ); + + // Use fallback, if data is missing in sdf file + //if( !bText && pResData->sResTyp.Equals( "pairedlist" ) ){ + if( !bText && bPairedList ){ + if( pResData->isMerged( sCur ) ) break; + const ByteString sPlist("pairedlist"); + ByteString sKey = MergeDataFile::CreateKey( sPlist , pResData->sGId , pResData->sId , sFilename ); + bText = pResData->getFallbackData( sKey , sText ); + }else if ( !bText ){// new fallback + if( pResData->isMerged( sCur ) ) break; + const ByteString sPlist("list"); + ByteString sKey = MergeDataFile::CreateKey( sPlist , pResData->sGId , pResData->sId , sFilename ); + bText = pResData->getFallbackData( sKey , sText ); + } // new fallback + + if ( bText && sText.Len()) { + //if( pEntrys ) pEntrys->Dump(); + if ( nIdx == 1 ) { + ByteString sHead; + if ( bNextMustBeDefineEOL ) + sHead = "\\\n\t"; + sHead += sSpace; + switch ( nT ) { + case LIST_STRING : sHead += "StringList "; break; + case LIST_FILTER : sHead += "FilterList "; break; + case LIST_ITEM : sHead += "ItemList "; break; + case LIST_PAIRED : sHead += "PairedList "; break; + case LIST_UIENTRIES : sHead += "UIEntries "; break; + } + sHead += "[ "; + sHead += sCur; + sHead += " ] "; + //} + if ( bDefine || bNextMustBeDefineEOL ) { + sHead += "= \\\n"; + sHead += sSpace; + sHead += "\t{\\\n\t"; + } + else { + sHead += "= \n"; + sHead += sSpace; + sHead += "\t{\n\t"; + } + WriteToMerged( sHead , true); + } + ByteString sLine; + if ( pList && pList->GetObject( nLIndex )) + sLine = ( *pList->GetObject( nLIndex ))[ SOURCE_LANGUAGE ]; + if ( !sLine.Len()) + sLine = sLastListLine; + + if ( sLastListLine.Search( "<" ) != STRING_NOTFOUND ) { + if (( nT != LIST_UIENTRIES ) && + (( sLine.Search( "{" ) == STRING_NOTFOUND ) || + ( sLine.Search( "{" ) >= sLine.Search( "\"" ))) && + (( sLine.Search( "<" ) == STRING_NOTFOUND ) || + ( sLine.Search( "<" ) >= sLine.Search( "\"" )))) + { + sLine.SearchAndReplace( "\"", "< \"" ); + } + } + + USHORT nStart, nEnd; + nStart = sLine.Search( "\"" ); + + ByteString sPostFix; + if( !bPairedList ){ + nEnd = sLine.SearchBackward( '\"' ); + sPostFix = ByteString( sLine.Copy( ++nEnd )); + sLine.Erase( nStart ); + } + + + ConvertMergeContent( sText ); + + // merge new res. in text line + if( bPairedList ){ + sLine = MergePairedList( sLine , sText ); + } + else{ + sLine += sText; + sLine += sPostFix; + } + + ByteString sText1( "\t" ); + sText1 += sLine; + if ( bDefine || bNextMustBeDefineEOL ) + sText1 += " ;\\\n"; + else + sText1 += " ;\n"; + sText1 += sSpace; + sText1 += "\t"; + //printf("Writing '%s'\n",sText1.GetBuffer()); + WriteToMerged( sText1 ,true ); + + // Set matching pairedlist identifier + if ( bPairedList ){ + nIdx++; + ExportListEntry* pListE = ( ExportListEntry* ) pResData->pPairedList->GetObject( ( nIdx ) -1 ); + if( pListE ){ + pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] ); + } + } + else + pResData->sId = ByteString::CreateFromInt32( ++nIdx ); + } + else + break; + nLIndex ++; + PFormEntrys *oldEntry = pEntrys; + pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); // <--- game over + if( !pEntrys ) + pEntrys = oldEntry; + } + if ( nIdx > 1 ) { + ByteString sFooter( sSpace.Copy( 1 )); + if ( bNextMustBeDefineEOL ) + sFooter += "};"; + else if ( !bDefine ) + sFooter += "};\n\t"; + else + sFooter += "\n\n"; + WriteToMerged( sFooter ,true ); + } + } + } + + pResData->sId = sOldId; + pResData->sGId = sOldGId; + pResData->sResTyp = sOldTyp; + } + } + break; + case MERGE_MODE_LIST : { + ExportList *pList = NULL; + switch ( nList ) { + // PairedList + case LIST_STRING : pList = pResData->pStringList; break; + case LIST_FILTER : pList = pResData->pFilterList; break; + case LIST_UIENTRIES : pList = pResData->pUIEntries; break; + case LIST_ITEM : pList = pResData->pItemList; break; + case LIST_PAIRED : pList = pResData->pPairedList; break; + + } + + nListIndex++; + ULONG nMaxIndex = 0; + if ( pList ) + nMaxIndex = pList->GetSourceLanguageListEntryCount(); + ByteString sLine; + if ( pList && pList->GetObject( nListIndex )) + sLine = ( *pList->GetObject( nListIndex ))[ SOURCE_LANGUAGE ]; + if ( !sLine.Len()) + sLine = sLastListLine; + + if ( sLastListLine.Search( "<" ) != STRING_NOTFOUND ) { + if (( nList != LIST_UIENTRIES ) && + (( sLine.Search( "{" ) == STRING_NOTFOUND ) || + ( sLine.Search( "{" ) >= sLine.Search( "\"" ))) && + (( sLine.Search( "<" ) == STRING_NOTFOUND ) || + ( sLine.Search( "<" ) >= sLine.Search( "\"" )))) + { + sLine.SearchAndReplace( "\"", "< \"" ); + } + } + + while( PrepareTextToMerge( sLine, nList, nListLang, pResData ) && ( nListIndex <= nMaxIndex )) { + ByteString sText( "\t" ); + sText += sLine; + sText += " ;"; + sText += "\n"; + for ( USHORT i = 0; i < nLevel; i++ ) + sText += "\t"; + WriteToMerged( sText ,false ); + nListIndex++; + if ( pList && pList->GetObject( nListIndex )) + sLine = ( *pList->GetObject( nListIndex ))[ SOURCE_LANGUAGE ]; + if ( !sLine.Len()) + sLine = sLastListLine; + sLine += " ;"; + } + } + break; + } + pParseQueue->bMflag = false; +} + +ByteString Export::MergePairedList( ByteString& sLine , ByteString& sText ){ +// < "xy" ; IDENTIFIER ; > + ByteString sPre = sLine.Copy( 0 , sLine.Search('\"') ); + ByteString sPost = sLine.Copy( sLine.SearchBackward('\"') + 1 , sLine.Len() ); + sPre.Append( sText ); + sPre.Append( sPost ); + return sPre; +} + +/*****************************************************************************/ +void Export::SetChildWithText() +/*****************************************************************************/ +{ + if ( aResStack.Count() > 1 ) { + for ( ULONG i = 0; i < aResStack.Count() - 1; i++ ) { + aResStack.GetObject( i )->bChildWithText = TRUE; + } + } +} + +void ParserQueue::Push( const QueueEntry& aEntry ){ +// printf("nTyp = %d ",aEntry.nTyp); + USHORT nLen = aEntry.sLine.Len(); + + if( !bStart ){ + aQueueCur->push( aEntry ); + if( nLen > 1 && aEntry.sLine.GetChar( nLen-1 ) == '\n' ) + bStart = true; + else if ( aEntry.nTyp != IGNOREDTOKENS ){ + if( nLen > 1 && ( aEntry.sLine.GetChar( nLen-1 ) == '\\') ){ + // Next is Macro + bCurrentIsM = true; + }else{ + // Next is no Macro + bCurrentIsM = false; + } + } + } + else{ + aQueueNext->push( aEntry ); + if( nLen > 1 && aEntry.sLine.GetChar( nLen-1 ) != '\n' ){ + if( nLen > 1 && ( aEntry.sLine.GetChar( nLen-1 ) == '\\') ){ + // Next is Macro + bNextIsM = true; + } + else{ + // Next is no Macro + bNextIsM = false; + } + }else if( nLen > 2 && aEntry.sLine.GetChar( nLen-1 ) == '\n' ){ + if( aEntry.nTyp != IGNOREDTOKENS ){ + if( nLen > 2 && ( aEntry.sLine.GetChar( nLen-2 ) == '\\') ){ + // Next is Macro + bNextIsM = true; + } + else{ + // Next is no Macro + bNextIsM = false; + } + } + // Pop current + Pop( *aQueueCur ); + bLastWasM = bCurrentIsM; + // next -> current + bCurrentIsM = bNextIsM; + aQref = aQueueCur; + aQueueCur = aQueueNext; + aQueueNext = aQref; + + } + + else{ + // Pop current + Pop( *aQueueCur ); + bLastWasM = bCurrentIsM; + // next -> current + bCurrentIsM = bNextIsM; + aQref = aQueueCur; + aQueueCur = aQueueNext; + aQueueNext = aQref; + } + } +} + +void ParserQueue::Close(){ + // Pop current + Pop( *aQueueCur ); + // next -> current + bLastWasM = bCurrentIsM; + bCurrentIsM = bNextIsM; + aQref = aQueueCur; + aQueueCur = aQueueNext; + aQueueNext = aQref; + bNextIsM = false; + Pop( *aQueueNext ); +}; +void ParserQueue::Pop( std::queue<QueueEntry>& aQueue ){ + while( !aQueue.empty() ){ + QueueEntry aEntry = aQueue.front(); + aQueue.pop(); + aExport.Execute( aEntry.nTyp , (char*) aEntry.sLine.GetBuffer() ); + } +} +ParserQueue::ParserQueue( Export& aExportObj ) + : + bCurrentIsM( false ), + bNextIsM( false ) , + bLastWasM( false ), + bMflag( false ) , + aExport( aExportObj ) , + bStart( false ) , + bStartNext( false ) +{ + aQueueNext = new std::queue<QueueEntry>; + aQueueCur = new std::queue<QueueEntry>; +} + + +ParserQueue::~ParserQueue(){ + if( aQueueNext ) delete aQueueNext; + if( aQueueCur ) delete aQueueCur; +} diff --git a/transex3/source/export2.cxx b/transex3/source/export2.cxx new file mode 100644 index 000000000000..5db1067a7afb --- /dev/null +++ b/transex3/source/export2.cxx @@ -0,0 +1,730 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: export2.cxx,v $ + * $Revision: 1.43 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include "export.hxx" +#include "utf8conv.hxx" +#include <tools/datetime.hxx> +#include <tools/isofallback.hxx> +#include <stdio.h> +#include <osl/time.h> +#include <osl/process.h> +#include <rtl/ustring.hxx> +#include <iostream> +#include <iomanip> +#include <tools/urlobj.hxx> +#include <time.h> + +using namespace std; +// +// class ResData(); +// + +/*****************************************************************************/ +ResData::~ResData() +/*****************************************************************************/ +{ + if ( pStringList ) { + // delete existing res. of type StringList + for ( ULONG i = 0; i < pStringList->Count(); i++ ) { + ExportListEntry* test = pStringList->GetObject( i ); + if( test != NULL ) delete test; + } + delete pStringList; + } + if ( pFilterList ) { + // delete existing res. of type FilterList + for ( ULONG i = 0; i < pFilterList->Count(); i++ ) { + ExportListEntry* test = pFilterList->GetObject( i ); + delete test; + } + delete pFilterList; + } + if ( pItemList ) { + // delete existing res. of type ItemList + for ( ULONG i = 0; i < pItemList->Count(); i++ ) { + ExportListEntry* test = pItemList->GetObject( i ); + delete test; + } + delete pItemList; + } + if ( pUIEntries ) { + // delete existing res. of type UIEntries + for ( ULONG i = 0; i < pUIEntries->Count(); i++ ) { + ExportListEntry* test = pUIEntries->GetObject( i ); + delete test; + } + delete pUIEntries; + } +} + +// +// class Export +// + +/*****************************************************************************/ +ByteString Export::sLanguages; +ByteString Export::sForcedLanguages; +ByteString Export::sIsoCode99; +/*****************************************************************************/ + +void Export::DumpExportList( ByteString& sListName , ExportList& aList ){ + printf( "%s\n", sListName.GetBuffer() ); + ByteString l(""); + ExportListEntry* aEntry; + for( unsigned int x = 0; x < aList.Count() ; x++ ){ + aEntry = (ExportListEntry*) aList.GetObject( x ); + Export::DumpMap( l , *aEntry ); + } + printf("\n"); +} +ByteString Export::DumpMap( ByteString& sMapName , ByteStringHashMap& aMap ){ + ByteStringHashMap::const_iterator idbg; + ByteString sReturn; + + if( sMapName.Len() ) + printf("MapName %s\n", sMapName.GetBuffer()); + if( aMap.size() < 1 ) return ByteString(); + for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg ){ + ByteString a( idbg->first ); + ByteString b( idbg->second ); + printf("[%s]= %s",a.GetBuffer(),b.GetBuffer()); + printf("\n"); + } + printf("\n"); + return sReturn; +} +/*****************************************************************************/ +void Export::SetLanguages( std::vector<ByteString> val ){ +/*****************************************************************************/ + aLanguages = val; + isInitialized = true; +} +/*****************************************************************************/ +std::vector<ByteString> Export::GetLanguages(){ +/*****************************************************************************/ + return aLanguages; +} +/*****************************************************************************/ +std::vector<ByteString> Export::GetForcedLanguages(){ +/*****************************************************************************/ + return aForcedLanguages; +} +std::vector<ByteString> Export::aLanguages = std::vector<ByteString>(); +std::vector<ByteString> Export::aForcedLanguages = std::vector<ByteString>(); + + +/*****************************************************************************/ +void Export::QuotHTMLXRM( ByteString &rString ) +/*****************************************************************************/ +{ + ByteString sReturn; + //BOOL bBreak = FALSE; + for ( USHORT i = 0; i < rString.Len(); i++ ) { + ByteString sTemp = rString.Copy( i ); + if ( sTemp.Search( "<Arg n=" ) == 0 ) { + while ( i < rString.Len() && rString.GetChar( i ) != '>' ) { + sReturn += rString.GetChar( i ); + i++; + } + if ( rString.GetChar( i ) == '>' ) { + sReturn += ">"; + i++; + } + } + + if ( i < rString.Len()) { + switch ( rString.GetChar( i )) { + case '<': + if( i+2 < rString.Len() && + (rString.GetChar( i+1 ) == 'b' || rString.GetChar( i+1 ) == 'B') && + rString.GetChar( i+2 ) == '>' ) + { + sReturn +="<b>"; + i += 2; + } + else if( i+3 < rString.Len() && + rString.GetChar( i+1 ) == '/' && + (rString.GetChar( i+2 ) == 'b' || rString.GetChar( i+2 ) == 'B') && + rString.GetChar( i+3 ) == '>' ) + { + sReturn +="</b>"; + i += 3; + } + else + sReturn += "<"; + break; + + case '>': + sReturn += ">"; + break; + + case '\"': + sReturn += """; + break; + + case '\'': + sReturn += "'"; + break; + + case '&': + if ((( i + 4 ) < rString.Len()) && + ( rString.Copy( i, 5 ) == "&" )) + sReturn += rString.GetChar( i ); + else + sReturn += "&"; + break; + + default: + sReturn += rString.GetChar( i ); + break; + } + } + } + rString = sReturn; +} +/*****************************************************************************/ +void Export::QuotHTML( ByteString &rString ) +/*****************************************************************************/ +{ + ByteString sReturn; + for ( USHORT i = 0; i < rString.Len(); i++ ) { + ByteString sTemp = rString.Copy( i ); + if ( sTemp.Search( "<Arg n=" ) == 0 ) { + while ( i < rString.Len() && rString.GetChar( i ) != '>' ) { + sReturn += rString.GetChar( i ); + i++; + } + if ( rString.GetChar( i ) == '>' ) { + sReturn += ">"; + i++; + } + } + if ( i < rString.Len()) { + switch ( rString.GetChar( i )) { + case '<': + sReturn += "<"; + break; + + case '>': + sReturn += ">"; + break; + + case '\"': + sReturn += """; + break; + + case '\'': + sReturn += "'"; + break; + + case '&': + if ((( i + 4 ) < rString.Len()) && + ( rString.Copy( i, 5 ) == "&" )) + sReturn += rString.GetChar( i ); + else + sReturn += "&"; + break; + + default: + sReturn += rString.GetChar( i ); + break; + } + } + } + rString = sReturn; +} + +void Export::RemoveUTF8ByteOrderMarker( ByteString &rString ){ + if( hasUTF8ByteOrderMarker( rString ) ) + rString.Erase( 0 , 3 ); +} + +bool Export::hasUTF8ByteOrderMarker( const ByteString &rString ){ + // Byte order marker signature + + const unsigned char c1 = 0xEF; + const unsigned char c2 = 0xBB; + const unsigned char c3 = 0xBF; + + const char bom[ 3 ] = { c1 , c2 , c3 }; + + return rString.Len() >= 3 && + rString.GetChar( 0 ) == bom[ 0 ] && + rString.GetChar( 1 ) == bom[ 1 ] && + rString.GetChar( 2 ) == bom[ 2 ] ; +} +bool Export::fileHasUTF8ByteOrderMarker( const ByteString &rString ){ + SvFileStream aFileIn( String( rString , RTL_TEXTENCODING_ASCII_US ) , STREAM_READ ); + ByteString sLine; + if( !aFileIn.IsEof() ) { + aFileIn.ReadLine( sLine ); + if( aFileIn.IsOpen() ) aFileIn.Close(); + return hasUTF8ByteOrderMarker( sLine ); + } + if( aFileIn.IsOpen() ) aFileIn.Close(); + return false; +} +void Export::RemoveUTF8ByteOrderMarkerFromFile( const ByteString &rFilename ){ + SvFileStream aFileIn( String( rFilename , RTL_TEXTENCODING_ASCII_US ) , STREAM_READ ); + ByteString sLine; + if( !aFileIn.IsEof() ) { + aFileIn.ReadLine( sLine ); + // Test header + if( hasUTF8ByteOrderMarker( sLine ) ){ + //cout << "UTF8 Header found!\n"; + DirEntry aTempFile = Export::GetTempFile(); + ByteString sTempFile = ByteString( aTempFile.GetFull() , RTL_TEXTENCODING_ASCII_US ); + SvFileStream aNewFile( String( sTempFile , RTL_TEXTENCODING_ASCII_US ) , STREAM_WRITE ); + // Remove header + RemoveUTF8ByteOrderMarker( sLine ); + //cout << "Copy stripped stuff to " << sTempFile.GetBuffer() << endl; + aNewFile.WriteLine( sLine ); + // Copy the rest + while( !aFileIn.IsEof() ){ + aFileIn.ReadLine( sLine ); + aNewFile.WriteLine( sLine ); + } + if( aFileIn.IsOpen() ) aFileIn.Close(); + if( aNewFile.IsOpen() ) aNewFile.Close(); + DirEntry aEntry( rFilename.GetBuffer() ); + //cout << "Removing file " << rFilename.GetBuffer() << "\n"; + aEntry.Kill(); + //cout << "Renaming file " << sTempFile.GetBuffer() << " to " << rFilename.GetBuffer() << "\n"; + DirEntry( sTempFile ).MoveTo( DirEntry( rFilename.GetBuffer() ) ); + } + } + if( aFileIn.IsOpen() ) aFileIn.Close(); +} + +// Merge it into source code! +//bool Export::isMergingGermanAllowed( const ByteString& rPrj ){ +// (void) rPrj; +// return true; +/* static ByteStringBoolHashMap aHash; + + if( aHash.find( rPrj ) != aHash.end() ){ + return aHash[ rPrj ]; + } + + ByteString sFile = Export::GetEnv( "SRC_ROOT" ) ; + sFile.Append("/"); + sFile.Append( rPrj ); + sFile.Append("/prj/l10n"); +#if defined(WNT) || defined(OS2) + sFile.SearchAndReplaceAll('/','\\'); +#endif + DirEntry aFlagfile( sFile ); + + aHash[ rPrj ] = !aFlagfile.Exists(); + return aHash[ rPrj ];*/ +//} +bool Export::CopyFile( const ByteString& source , const ByteString& dest ) +{ +// cout << "CopyFile( " << source.GetBuffer() << " , " << dest.GetBuffer() << " )\n"; + const int BUFFERSIZE = 8192; + char buf[ BUFFERSIZE ]; + + FILE* IN_FILE = fopen( source.GetBuffer() , "r" ); + FILE* OUT_FILE = fopen( dest.GetBuffer() , "w" ); + + if( IN_FILE == NULL ) + { + cerr << "Export::CopyFile WARNING: Could not open " << source.GetBuffer() << "\n"; + return false; + } + if( OUT_FILE == NULL ) + { + cerr << "Export::CopyFile WARNING: Could not open/create " << dest.GetBuffer() << " for writing\n"; + return false; + } + + while( fgets( buf , BUFFERSIZE , IN_FILE ) != NULL ) + { + if( fputs( buf , OUT_FILE ) == EOF ) + { + cerr << "Export::CopyFile WARNING: Write problems " << source.GetBuffer() << "\n"; + fclose( IN_FILE ); + fclose( OUT_FILE ); + return false; + } + } + if( ferror( IN_FILE ) ) + { + cerr << "Export::CopyFile WARNING: Read problems " << dest.GetBuffer() << "\n"; + fclose( IN_FILE ); + fclose( OUT_FILE ); + return false; + } + fclose ( IN_FILE ); + fclose ( OUT_FILE ); + + return true; +} + +/*****************************************************************************/ +void Export::UnquotHTML( ByteString &rString ) +/*****************************************************************************/ +{ + ByteString sReturn; + while ( rString.Len()) { + if ( rString.Copy( 0, 5 ) == "&" ) { + sReturn += "&"; + rString.Erase( 0, 5 ); + } + else if ( rString.Copy( 0, 4 ) == "<" ) { + sReturn += "<"; + rString.Erase( 0, 4 ); + } + else if ( rString.Copy( 0, 4 ) == ">" ) { + sReturn += ">"; + rString.Erase( 0, 4 ); + } + else if ( rString.Copy( 0, 6 ) == """ ) { + sReturn += "\""; + rString.Erase( 0, 6 ); + } + else if ( rString.Copy( 0, 6 ) == "'" ) { + sReturn += "\'"; + rString.Erase( 0, 6 ); + } + else { + sReturn += rString.GetChar( 0 ); + rString.Erase( 0, 1 ); + } + } + rString = sReturn; +} +bool Export::isSourceLanguage( const ByteString &sLanguage ) +{ + return !isAllowed( sLanguage ); +} +bool Export::isAllowed( const ByteString &sLanguage ){ + return ! ( sLanguage.EqualsIgnoreCaseAscii("en-US") ); +} +/*****************************************************************************/ +bool Export::LanguageAllowed( const ByteString &nLanguage ) +/*****************************************************************************/ +{ + return std::find( aLanguages.begin() , aLanguages.end() , nLanguage ) != aLanguages.end(); +} + +bool Export::isInitialized = false; + +/*****************************************************************************/ +void Export::InitLanguages( bool bMergeMode ){ +/*****************************************************************************/ + if( !isInitialized ){ + ByteString sTmp; + ByteStringBoolHashMap aEnvLangs; + for ( USHORT x = 0; x < sLanguages.GetTokenCount( ',' ); x++ ){ + sTmp = sLanguages.GetToken( x, ',' ).GetToken( 0, '=' ); + sTmp.EraseLeadingAndTrailingChars(); + if( bMergeMode && !isAllowed( sTmp ) ){} + else if( !( (sTmp.GetChar(0)=='x' || sTmp.GetChar(0)=='X') && sTmp.GetChar(1)=='-' ) ){ + aLanguages.push_back( sTmp ); + } + } + InitForcedLanguages( bMergeMode ); + isInitialized = true; + } +} +/*****************************************************************************/ +void Export::InitForcedLanguages( bool bMergeMode ){ +/*****************************************************************************/ + ByteString sTmp; + ByteStringBoolHashMap aEnvLangs; + for ( USHORT x = 0; x < sForcedLanguages.GetTokenCount( ',' ); x++ ){ + sTmp = sForcedLanguages.GetToken( x, ',' ).GetToken( 0, '=' ); + sTmp.EraseLeadingAndTrailingChars(); + if( bMergeMode && isAllowed( sTmp ) ){} + else if( !( (sTmp.GetChar(0)=='x' || sTmp.GetChar(0)=='X') && sTmp.GetChar(1)=='-' ) ) + aForcedLanguages.push_back( sTmp ); + } +} + +/*****************************************************************************/ +ByteString Export::GetFallbackLanguage( const ByteString nLanguage ) +/*****************************************************************************/ +{ + ByteString sFallback=nLanguage; + GetIsoFallback( sFallback ); + return sFallback; +} + +void Export::replaceEncoding( ByteString& rString ) +{ +// ™ -> \u2122 + + for( xub_StrLen idx = 0; idx <= rString.Len()-8 ; idx++ ) + { + if( rString.GetChar( idx ) == '&' && + rString.GetChar( idx+1 ) == '#' && + rString.GetChar( idx+2 ) == 'x' && + rString.GetChar( idx+7 ) == ';' ) + { + ByteString sTmp = rString.Copy( 0 , idx ); + sTmp.Append( "\\u" ); + sTmp.Append( rString.GetChar( idx+3 ) ); + sTmp.Append( rString.GetChar( idx+4 ) ); + sTmp.Append( rString.GetChar( idx+5 ) ); + sTmp.Append( rString.GetChar( idx+6 ) ); + sTmp.Append( rString.Copy( idx+8 , rString.Len() ) ); + rString = sTmp; + } + } +} + +/*****************************************************************************/ +void Export::FillInFallbacks( ResData *pResData ) +/*****************************************************************************/ +{ + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + if( isAllowed( sCur ) ){ + ByteString nFallbackIndex = GetFallbackLanguage( sCur ); + if( nFallbackIndex.Len() ){ + if ( !pResData->sText[ sCur ].Len()) + pResData->sText[ sCur ] = + pResData->sText[ nFallbackIndex ]; + + if ( !pResData->sHelpText[ sCur ].Len()) + pResData->sHelpText[ sCur ] = + pResData->sHelpText[ nFallbackIndex ]; + + if ( !pResData->sQuickHelpText[ sCur ].Len()) + pResData->sQuickHelpText[ sCur ] = + pResData->sQuickHelpText[ nFallbackIndex ]; + + if ( !pResData->sTitle[ sCur ].Len()) + pResData->sTitle[ sCur ] = + pResData->sTitle[ nFallbackIndex ]; + + if ( pResData->pStringList ) + FillInListFallbacks( + pResData->pStringList, sCur, nFallbackIndex ); + + if ( pResData->pPairedList ) + FillInListFallbacks( + pResData->pPairedList, sCur, nFallbackIndex ); + + if ( pResData->pFilterList ) + FillInListFallbacks( + pResData->pFilterList, sCur, nFallbackIndex ); + + if ( pResData->pItemList ) + FillInListFallbacks( + pResData->pItemList, sCur, nFallbackIndex ); + + if ( pResData->pUIEntries ) + FillInListFallbacks( + pResData->pUIEntries, sCur, nFallbackIndex ); + } + } + } +} + +/*****************************************************************************/ +void Export::FillInListFallbacks( + ExportList *pList, const ByteString &nSource, const ByteString &nFallback ) +/*****************************************************************************/ +{ + + for ( ULONG i = 0; i < pList->Count(); i++ ) { + ExportListEntry *pEntry = pList->GetObject( i ); + if ( !( *pEntry )[ nSource ].Len()){ + ( *pEntry )[ nSource ] = ( *pEntry )[ nFallback ]; + ByteString x = ( *pEntry )[ nSource ]; + ByteString y = ( *pEntry )[ nFallback ]; + } + } +} + +/*****************************************************************************/ +ByteString Export::GetTimeStamp() +/*****************************************************************************/ +{ +// return "xx.xx.xx"; + char buf[20]; + Time aTime; + + snprintf(buf, sizeof(buf), "%8d %02d:%02d:%02d", int(Date().GetDate()), + int(aTime.GetHour()), int(aTime.GetMin()), int(aTime.GetSec())); + return ByteString(buf); +} + +/*****************************************************************************/ +BOOL Export::ConvertLineEnds( + ByteString sSource, ByteString sDestination ) +/*****************************************************************************/ +{ + String sSourceFile( sSource, RTL_TEXTENCODING_ASCII_US ); + String sDestinationFile( sDestination, RTL_TEXTENCODING_ASCII_US ); + + SvFileStream aSource( sSourceFile, STREAM_READ ); + if ( !aSource.IsOpen()) + return FALSE; + SvFileStream aDestination( sDestinationFile, STREAM_STD_WRITE | STREAM_TRUNC ); + if ( !aDestination.IsOpen()) { + aSource.Close(); + return FALSE; + } + + ByteString sLine; + + while ( !aSource.IsEof()) { + aSource.ReadLine( sLine ); + if ( !aSource.IsEof()) { + sLine.EraseAllChars( '\r' ); + aDestination.WriteLine( sLine ); + } + else + aDestination.WriteByteString( sLine ); + } + + aSource.Close(); + aDestination.Close(); + + return TRUE; +} + +/*****************************************************************************/ +ByteString Export::GetNativeFile( ByteString sSource ) +/*****************************************************************************/ +{ + DirEntry aTemp( GetTempFile()); + ByteString sReturn( aTemp.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + for ( USHORT i = 0; i < 10; i++ ) + if ( ConvertLineEnds( sSource, sReturn )) + return sReturn; + + return ""; +} + +const char* Export::GetEnv( const char *pVar ) +{ + char *pRet = getenv( pVar ); + if ( !pRet ) + pRet = 0; + return pRet; +} + + +int Export::getCurrentDirectory( rtl::OUString& base_fqurl_out, rtl::OUString& base_out ) +{ + DirEntry aDir("."); + aDir.ToAbs(); + base_out = rtl::OUString( aDir.GetFull() ); + return osl::File::getFileURLFromSystemPath( base_out , base_fqurl_out ); +} + + +// Stolen from sal/osl/unx/tempfile.c + +#define RAND_NAME_LENGTH 6 + +void Export::getRandomName( const ByteString& sPrefix , ByteString& sRandStr , const ByteString& sPostfix ) +{ + static const char LETTERS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + static const int COUNT_OF_LETTERS = sizeof(LETTERS)/sizeof(LETTERS[0]) - 1; + sRandStr.Append( sPrefix ); + + static sal_uInt64 value; + char buffer[RAND_NAME_LENGTH]; + + TimeValue tv; + sal_uInt64 v; + int i; + + osl_getSystemTime( &tv ); + oslProcessInfo proInfo; + osl_getProcessInfo( 0 , osl_Process_IDENTIFIER , &proInfo ); + + value += ((sal_uInt64) ( tv.Nanosec / 1000 ) << 16) ^ ( tv.Nanosec / 1000 ) ^ proInfo.Ident; + + v = value; + + for (i = 0; i < RAND_NAME_LENGTH; i++) + { + buffer[i] = LETTERS[v % COUNT_OF_LETTERS]; + v /= COUNT_OF_LETTERS; + } + + sRandStr.Append( buffer , RAND_NAME_LENGTH ); + sRandStr.Append( sPostfix ); +} + +void Export::getRandomName( ByteString& sRandStr ) +{ + const ByteString sEmpty; + getRandomName( sEmpty , sRandStr , sEmpty ); +} + +/*****************************************************************************/ +DirEntry Export::GetTempFile() +/*****************************************************************************/ +{ +#if defined(WNT) || defined(OS2) + String sTempDir( Export::GetEnv( "TEMP" ), RTL_TEXTENCODING_ASCII_US ); +#else + String sTempDir( String::CreateFromAscii( "/tmp" )); +#endif + rtl::OUString* sTempFilename = new rtl::OUString(); + + // Create a temp file + int nRC = osl::FileBase::createTempFile( 0 , 0 , sTempFilename ); + if( nRC ) printf(" osl::FileBase::createTempFile RC = %d",nRC); + + String strTmp( *sTempFilename ); + + INetURLObject::DecodeMechanism eMechanism = INetURLObject::DECODE_TO_IURI; + String sDecodedStr = INetURLObject::decode( strTmp , '%' , eMechanism ); + ByteString sTmp( sDecodedStr , RTL_TEXTENCODING_UTF8 ); + +#if defined(WNT) || defined(OS2) + sTmp.SearchAndReplace("file:///",""); + sTmp.SearchAndReplaceAll('/','\\'); +#else + // Set file permission to 644 + const sal_uInt64 nPerm = osl_File_Attribute_OwnRead | osl_File_Attribute_OwnWrite | + osl_File_Attribute_GrpRead | osl_File_Attribute_OthRead ; + + nRC = osl::File::setAttributes( *sTempFilename , nPerm ); + if( nRC ) printf(" osl::File::setAttributes RC = %d",nRC); + + sTmp.SearchAndReplace("file://",""); +#endif + DirEntry aDirEntry( sTmp ); + delete sTempFilename; + return aDirEntry; +} diff --git a/transex3/source/file.cxx b/transex3/source/file.cxx new file mode 100644 index 000000000000..4ea9ca55d574 --- /dev/null +++ b/transex3/source/file.cxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: file.cxx,v $ + * $Revision: 1.6 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <transex3/file.hxx> + +namespace transex +{ + +File::File( const rtl::OUString sFile ) +{ + sFileName = sFile; +} + +File::File( const rtl::OUString sFullPath , const rtl::OUString sFile ) +{ + sFileName = sFile; + sFullName = sFullPath; +} + +bool File::lessFile ( const File& rKey1, const File& rKey2 ) +{ + rtl::OUString sName1( ( static_cast< File >( rKey1 ) ).getFileName() ); + rtl::OUString sName2( ( static_cast< File >( rKey2 ) ).getFileName() ); + + return sName1.compareTo( sName2 ) < 0 ; +} + +} diff --git a/transex3/source/gsicheck.cxx b/transex3/source/gsicheck.cxx new file mode 100644 index 000000000000..99183602f951 --- /dev/null +++ b/transex3/source/gsicheck.cxx @@ -0,0 +1,1177 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: gsicheck.cxx,v $ + * $Revision: 1.29 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <tools/fsys.hxx> +#include <tools/stream.hxx> +#include <tools/list.hxx> + +// local includes +#include "tagtest.hxx" +#include "gsicheck.hxx" + +#define MAX_GID_LID_LEN 250 + +/*****************************************************************************/ +void PrintMessage( ByteString aType, ByteString aMsg, ByteString aPrefix, + ByteString aContext, BOOL bPrintContext, ULONG nLine, ByteString aUniqueId = ByteString() ) +/*****************************************************************************/ +{ + fprintf( stdout, "%s %s, Line %lu", aType.GetBuffer(), aPrefix.GetBuffer(), nLine ); + if ( aUniqueId.Len() ) + fprintf( stdout, ", UniqueID %s", aUniqueId.GetBuffer() ); + fprintf( stdout, ": %s", aMsg.GetBuffer() ); + + if ( bPrintContext ) + fprintf( stdout, " \"%s\"", aContext.GetBuffer() ); + fprintf( stdout, "\n" ); +} + +/*****************************************************************************/ +void PrintError( ByteString aMsg, ByteString aPrefix, + ByteString aContext, BOOL bPrintContext, ULONG nLine, ByteString aUniqueId = ByteString() ) +/*****************************************************************************/ +{ + PrintMessage( "Error:", aMsg, aPrefix, aContext, bPrintContext, nLine, aUniqueId ); +} + +BOOL LanguageOK( ByteString aLang ) +{ + if ( !aLang.Len() ) + return FALSE; + + if ( aLang.IsNumericAscii() ) + return TRUE; + + if ( aLang.GetTokenCount( '-' ) == 1 ) + return aLang.IsAlphaAscii() && aLang.IsLowerAscii(); + else if ( aLang.GetTokenCount( '-' ) == 2 ) + { + ByteString aTok0( aLang.GetToken( 0, '-' ) ); + ByteString aTok1( aLang.GetToken( 1, '-' ) ); + return aTok0.Len() && aTok0.IsAlphaAscii() && aTok0.IsLowerAscii() + && aTok1.Len() && aTok1.IsAlphaAscii() && aTok1.IsUpperAscii() + && !aTok1.EqualsIgnoreCaseAscii( aTok0 ); + } + + return FALSE; +} + + +// +// class LazySvFileStream +// + + +class LazySvFileStream : public SvFileStream +{ + +private: + String aFileName; + BOOL bOpened; + StreamMode eOpenMode; + +public: + LazySvFileStream() + : aFileName() + , bOpened( FALSE ) + , eOpenMode( 0 ) + {}; + + void SetOpenParams( const String& rFileName, StreamMode eOpenModeP ) + { + aFileName = rFileName; + eOpenMode = eOpenModeP; + }; + + void LazyOpen(); +}; + +void LazySvFileStream::LazyOpen() +{ + if ( !bOpened ) + { + Open( aFileName, eOpenMode ); + if ( !IsOpen()) + { + fprintf( stderr, "\nERROR: Could not open Output-File %s!\n\n", ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ).GetBuffer() ); + exit ( 4 ); + } + bOpened = TRUE; + } +} + + +// +// class GSILine +// + +/*****************************************************************************/ +GSILine::GSILine( const ByteString &rLine, ULONG nLine ) +/*****************************************************************************/ + : ByteString( rLine ) + , nLineNumber( nLine ) + , bOK( TRUE ) + , bFixed ( FALSE ) +{ + if ( rLine.GetTokenCount( '\t' ) == 15 ) + { + aFormat = FORMAT_SDF; + aUniqId = rLine.GetToken( 0, '\t' ); + aUniqId.Append("/").Append( rLine.GetToken( 1, '\t' ) ).Append("/").Append( rLine.GetToken( 3, '\t' ) ).Append("/").Append( rLine.GetToken( 4, '\t' ) ).Append("/").Append( rLine.GetToken( 5, '\t' ) ).Append("/").Append( rLine.GetToken( 6, '\t' ) ).Append("/").Append( rLine.GetToken( 7, '\t' ) ); + aLineType = ""; + aLangId = rLine.GetToken( 9, '\t' ); + aText = rLine.GetToken( 10, '\t' ); + aQuickHelpText = rLine.GetToken( 12, '\t' ); + aTitle = rLine.GetToken( 13, '\t' ); + + // do some more format checks here + if ( !rLine.GetToken( 8, '\t' ).IsNumericAscii() ) + { + PrintError( "The length field does not contain a number!", "Line format", rLine.GetToken( 8, '\t' ), TRUE, GetLineNumber(), GetUniqId() ); + NotOK(); + } + if ( !LanguageOK( aLangId ) ) + { + PrintError( "The Language is invalid!", "Line format", aLangId, TRUE, GetLineNumber(), GetUniqId() ); + NotOK(); + } + // limit GID and LID to MAX_GID_LID_LEN chars each for database conformity, see #137575# + if ( rLine.GetToken( 4, '\t' ).Len() > MAX_GID_LID_LEN || rLine.GetToken( 5, '\t' ).Len() > MAX_GID_LID_LEN ) + { + PrintError( ByteString("GID and LID may only be ").Append( ByteString::CreateFromInt32(MAX_GID_LID_LEN) ).Append( " chars long each!" ), "Line format", aLangId, TRUE, GetLineNumber(), GetUniqId() ); + NotOK(); + } + } + else // allow tabs in gsi files + { + aFormat = FORMAT_GSI; + ByteString sTmp( rLine ); + USHORT nPos = sTmp.Search( "($$)" ); + USHORT nStart = 0; + if ( nPos != STRING_NOTFOUND ) + { + aUniqId = sTmp.Copy( nStart, nPos - nStart ); + nStart = nPos + 4; // + length of the delemiter + nPos = sTmp.Search( "($$)", nStart ); + } + if ( nPos != STRING_NOTFOUND ) + { + aLineType = sTmp.Copy( nStart, nPos - nStart ); + nStart = nPos + 4; // + length of the delemiter + nPos = sTmp.Search( "($$)", nStart ); + aUniqId.Append( "/" ); + aUniqId.Append( aLineType ); + } + if ( nPos != STRING_NOTFOUND ) + { + aLangId = sTmp.Copy( nStart, nPos - nStart ); + nStart = nPos + 4; // + length of the delemiter + nPos = sTmp.Search( "($$)", nStart ); + } + if ( nPos != STRING_NOTFOUND ) + { +// ByteString aStatus = sTmp.Copy( nStart, nPos - nStart ); // ext int ... + nStart = nPos + 4; // + length of the delemiter + } + if ( nPos != STRING_NOTFOUND ) + aText = sTmp.Copy( nStart ); + else + aFormat = FORMAT_UNKNOWN; + } + + if ( FORMAT_UNKNOWN == GetLineFormat() ) + NotOK(); +} + +/*****************************************************************************/ +void GSILine::NotOK() +/*****************************************************************************/ +{ + bOK = FALSE; +} + +/*****************************************************************************/ +void GSILine::ReassembleLine() +/*****************************************************************************/ +{ + ByteString aReassemble; + if ( GetLineFormat() == FORMAT_SDF ) + { + USHORT i; + for ( i = 0 ; i < 10 ; i++ ) + { + aReassemble.Append( GetToken( i, '\t' ) ); + aReassemble.Append( "\t" ); + } + aReassemble.Append( aText ); + aReassemble.Append( "\t" ); + aReassemble.Append( GetToken( 11, '\t' ) ); // should be empty but there are some places in sc. Not reflected to sources!! + aReassemble.Append( "\t" ); + aReassemble.Append( aQuickHelpText ); + aReassemble.Append( "\t" ); + aReassemble.Append( aTitle ); + for ( i = 14 ; i < 15 ; i++ ) + { + aReassemble.Append( "\t" ); + aReassemble.Append( GetToken( i, '\t' ) ); + } + *(ByteString*)this = aReassemble; + } + else if ( GetLineFormat() == FORMAT_GSI ) + { + USHORT nPos = Search( "($$)" ); + USHORT nStart = 0; + if ( nPos != STRING_NOTFOUND ) + { + nStart = nPos + 4; // + length of the delemiter + nPos = Search( "($$)", nStart ); + } + if ( nPos != STRING_NOTFOUND ) + { + nStart = nPos + 4; // + length of the delemiter + nPos = Search( "($$)", nStart ); + } + if ( nPos != STRING_NOTFOUND ) + { + nStart = nPos + 4; // + length of the delemiter + nPos = Search( "($$)", nStart ); + } + if ( nPos != STRING_NOTFOUND ) + { + nStart = nPos + 4; // + length of the delemiter + } + if ( nPos != STRING_NOTFOUND ) + { + aReassemble = Copy( 0, nStart ); + aReassemble += aText; + *(ByteString*)this = aReassemble; + } + else + PrintError( "Cannot reassemble GSI line (internal Error).", "Line format", "", FALSE, GetLineNumber(), GetUniqId() ); + } + else + PrintError( "Cannot reassemble line of unknown type (internal Error).", "Line format", "", FALSE, GetLineNumber(), GetUniqId() ); +} + +// +// class GSIBlock +// +/*****************************************************************************/ +GSIBlock::GSIBlock( BOOL PbPrintContext, BOOL bSource, BOOL bTrans, BOOL bRef, BOOL bAllowKID, BOOL bAllowSusp ) +/*****************************************************************************/ + : pSourceLine( NULL ) + , pReferenceLine( NULL ) + , bPrintContext( PbPrintContext ) + , bCheckSourceLang( bSource ) + , bCheckTranslationLang( bTrans ) + , bReference( bRef ) + , bAllowKeyIDs( bAllowKID ) + , bAllowSuspicious( bAllowSusp ) + , bHasBlockError( FALSE ) +{ +} + +/*****************************************************************************/ +GSIBlock::~GSIBlock() +/*****************************************************************************/ +{ + delete pSourceLine; + delete pReferenceLine; + + for ( ULONG i = 0; i < Count(); i++ ) + delete ( GetObject( i )); +} + +/*****************************************************************************/ +void GSIBlock::InsertLine( GSILine* pLine, ByteString aSourceLang) +/*****************************************************************************/ +{ + if ( pLine->GetLanguageId().Equals( aSourceLang ) ) + { + if ( pSourceLine ) + { + PrintError( "Source Language entry double. Treating as Translation.", "File format", "", pLine->GetLineNumber(), pLine->GetUniqId() ); + bHasBlockError = TRUE; + pSourceLine->NotOK(); + pLine->NotOK(); + } + else + { + pSourceLine = pLine; + return; + } + } + ULONG nPos = 0; + + if ( aSourceLang.Len() ) // only check blockstructure if source lang is given + { + while ( nPos < Count() ) + { + if ( GetObject( nPos )->GetLanguageId().Equals( pLine->GetLanguageId() ) ) + { + PrintError( "Translation Language entry double. Checking both.", "File format", "", pLine->GetLineNumber(), pLine->GetUniqId() ); + bHasBlockError = TRUE; + GetObject( nPos )->NotOK(); + pLine->NotOK(); + } + nPos++; + } + } + Insert( pLine, LIST_APPEND ); +} + +/*****************************************************************************/ +void GSIBlock::SetReferenceLine( GSILine* pLine ) +/*****************************************************************************/ +{ + pReferenceLine = pLine; +} + +/*****************************************************************************/ +void GSIBlock::PrintMessage( ByteString aType, ByteString aMsg, ByteString aPrefix, + ByteString aContext, ULONG nLine, ByteString aUniqueId ) +/*****************************************************************************/ +{ + ::PrintMessage( aType, aMsg, aPrefix, aContext, bPrintContext, nLine, aUniqueId ); +} + +/*****************************************************************************/ +void GSIBlock::PrintError( ByteString aMsg, ByteString aPrefix, + ByteString aContext, ULONG nLine, ByteString aUniqueId ) +/*****************************************************************************/ +{ + PrintMessage( "Error:", aMsg, aPrefix, aContext, nLine, aUniqueId ); +} + +/*****************************************************************************/ +void GSIBlock::PrintList( ParserMessageList *pList, ByteString aPrefix, + GSILine *pLine ) +/*****************************************************************************/ +{ + ULONG i; + for ( i = 0 ; i < pList->Count() ; i++ ) + { + ParserMessage *pMsg = pList->GetObject( i ); + ByteString aContext; + if ( bPrintContext ) + { + if ( pMsg->GetTagBegin() == STRING_NOTFOUND ) + aContext = pLine->GetText().Copy( 0, 300 ); + else + aContext = pLine->Copy( pMsg->GetTagBegin()-150, 300 ); + aContext.EraseTrailingChars(' '); + aContext.EraseLeadingChars(' '); + } + + PrintMessage( pMsg->Prefix(), pMsg->GetErrorText(), aPrefix, aContext, pLine->GetLineNumber(), pLine->GetUniqId() ); + } +} + +/*****************************************************************************/ +BOOL GSIBlock::IsUTF8( const ByteString &aTestee, BOOL bFixTags, USHORT &nErrorPos, ByteString &aErrorMsg, BOOL &bHasBeenFixed, ByteString &aFixed ) const +/*****************************************************************************/ +{ + String aUTF8Tester( aTestee, RTL_TEXTENCODING_UTF8 ); + if ( STRING_MATCH != (nErrorPos = ByteString( aUTF8Tester, RTL_TEXTENCODING_UTF8 ).Match( aTestee )) ) + { + aUTF8Tester = String( aTestee.GetBuffer(), nErrorPos, RTL_TEXTENCODING_UTF8 ); + nErrorPos = aUTF8Tester.Len(); + aErrorMsg = ByteString( "UTF8 Encoding seems to be broken" ); + return FALSE; + } + + nErrorPos = aUTF8Tester.SearchChar( String::CreateFromAscii( "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f" ).GetBuffer() ); + if ( nErrorPos != STRING_NOTFOUND ) + { + aErrorMsg = ByteString( "String contains illegal character" ); + return FALSE; + } + + if ( bFixTags ) + { + bHasBeenFixed = FALSE; + aFixed.Erase(); + } + + if ( !bAllowKeyIDs ) + { + BOOL bIsKeyID = FALSE; + BOOL bNewId = FALSE; + ByteString aID( aTestee ); + USHORT nAfterID = 0; + + if ( aTestee.Equals( "{&", 0, 2 ) ) + { // check for strings from instset_native like "{&Tahoma8}335795.Installation Wiza ..." + USHORT nTagEnd = aTestee.Search( '}' ); + if ( nTagEnd != STRING_NOTFOUND ) + { + if ( bFixTags ) + aFixed = aTestee.Copy( 0, nTagEnd+1 ); + nErrorPos = nTagEnd+1; + aID = aTestee.Copy( nTagEnd+1 ); + nAfterID = nTagEnd+1; + } + } + + ByteString aDelimiter( (String)String( sal_Unicode(0x2016) ), RTL_TEXTENCODING_UTF8 ); + + if ( aID.Equals( aDelimiter, 6, aDelimiter.Len() ) ) + { // New KeyId 6 Letters, digits and spechial chars followed by delimiter + bNewId = TRUE; + nErrorPos = 1; + aID = aID.Copy( 0, 6 ); + nAfterID += 6; + nAfterID = nAfterID + aDelimiter.Len(); + } + else if ( ( aID.GetChar(6) == '*' ) && aID.Equals( aDelimiter, 7, aDelimiter.Len() ) ) + { // New KeyId 6 Letters, digits and spechial chars followed by '*delimiter' to indicate translation in progress + bNewId = TRUE; + nErrorPos = 1; + aID = aID.Copy( 0, 6 ); + nAfterID += 7; + nAfterID = nAfterID + aDelimiter.Len(); + } + else if ( aID.GetTokenCount( '.' ) > 1 ) + { // test for old KeyIDs 5 to 6 digits followed by a dot '44373.' + bNewId = FALSE; + nErrorPos = 1; + aID = aID.GetToken( 0, '.' ); + nAfterID = nAfterID + aID.Len(); + } + else + { + aID.Erase(); + } + + if ( bNewId ) + { + if ( aID.Len() == 6 ) + { + bIsKeyID = TRUE; + ByteString aDigits("0123456789abcdefghijklmnopqrstuvwxyz+-<=>"); + for ( USHORT i=0 ; i < aID.Len() ;i++ ) + { + if ( aDigits.Search( aID.GetChar(i) ) == STRING_NOTFOUND ) + bIsKeyID = FALSE; + } + } + } + else + { + if ( aID.Len() > 0 && aID.GetChar(aID.Len()-1) == '*' ) + aID.Erase( aID.Len()-1 ); + + if ( aID.IsNumericAscii() && aID.Len() >= 5 ) + bIsKeyID = TRUE; + } + + if ( bIsKeyID ) + { + aErrorMsg = ByteString( "String contains KeyID" ); + if ( bFixTags ) + { + aFixed += aTestee.Copy( nAfterID ); + bHasBeenFixed = TRUE; + aErrorMsg = ByteString( "FIXED String containing KeyID" ); + } + else + aErrorMsg = ByteString( "String contains KeyID" ); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ +BOOL GSIBlock::TestUTF8( GSILine* pTestee, BOOL bFixTags ) +/*****************************************************************************/ +{ + USHORT nErrorPos = 0; + ByteString aErrorMsg; + BOOL bError = FALSE; + ByteString aFixed; + BOOL bHasBeenFixed = FALSE; + if ( !IsUTF8( pTestee->GetText(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) ) + { + ByteString aContext( pTestee->GetText().Copy( nErrorPos, 20 ) ); + PrintError( aErrorMsg.Append(" in Text at Position " ).Append( ByteString::CreateFromInt32( nErrorPos ) ), "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId() ); + bError = TRUE; + if ( bHasBeenFixed ) + { + pTestee->SetText( aFixed ); + pTestee->SetFixed(); + } + } + if ( !IsUTF8( pTestee->GetQuickHelpText(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) ) + { + ByteString aContext( pTestee->GetQuickHelpText().Copy( nErrorPos, 20 ) ); + PrintError( aErrorMsg.Append(" in QuickHelpText at Position " ).Append( ByteString::CreateFromInt32( nErrorPos ) ), "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId() ); + bError = TRUE; + if ( bHasBeenFixed ) + { + pTestee->SetQuickHelpText( aFixed ); + pTestee->SetFixed(); + } + } + if ( !IsUTF8( pTestee->GetTitle(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) ) + { + ByteString aContext( pTestee->GetTitle().Copy( nErrorPos, 20 ) ); + PrintError( aErrorMsg.Append(" in Title at Position " ).Append( ByteString::CreateFromInt32( nErrorPos ) ), "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId() ); + bError = TRUE; + if ( bHasBeenFixed ) + { + pTestee->SetTitle( aFixed ); + pTestee->SetFixed(); + } + } + if ( bError ) + pTestee->NotOK(); + return !bError; +} + + +/*****************************************************************************/ +BOOL GSIBlock::HasSuspiciousChars( GSILine* pTestee, GSILine* pSource ) +/*****************************************************************************/ +{ + USHORT nPos = 0; + if ( !bAllowSuspicious && ( nPos = pTestee->GetText().Search("??")) != STRING_NOTFOUND ) + if ( pSource->GetText().Search("??") == STRING_NOTFOUND ) + { + String aUTF8Tester = String( pTestee->GetText(), 0, nPos, RTL_TEXTENCODING_UTF8 ); + USHORT nErrorPos = aUTF8Tester.Len(); + ByteString aContext( pTestee->GetText().Copy( nPos, 20 ) ); + PrintError( ByteString("Found double questionmark in translation only. Looks like an encoding problem at Position " ).Append( ByteString::CreateFromInt32( nErrorPos ) ), "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId() ); + pTestee->NotOK(); + return TRUE; + } + + return FALSE; +} + + +/*****************************************************************************/ +BOOL GSIBlock::CheckSyntax( ULONG nLine, BOOL bRequireSourceLine, BOOL bFixTags ) +/*****************************************************************************/ +{ + static LingTest aTester; + BOOL bHasError = FALSE; + + if ( !pSourceLine ) + { + if ( bRequireSourceLine ) + { + PrintError( "No source language entry defined!", "File format", "", nLine ); + bHasBlockError = TRUE; + } + } + else + { + aTester.CheckReference( pSourceLine ); + if ( pSourceLine->HasMessages() ) + { + PrintList( pSourceLine->GetMessageList(), "ReferenceString", pSourceLine ); + pSourceLine->NotOK(); + bHasError = TRUE; + } + } + if ( bReference ) + { + if ( !pReferenceLine ) + { + GSILine *pSource; + if ( pSourceLine ) + pSource = pSourceLine; + else + pSource = GetObject( 0 ); // get some other line + if ( pSource ) + PrintError( "No reference line found. Entry is new in source file", "File format", "", pSource->GetLineNumber(), pSource->GetUniqId() ); + else + PrintError( "No reference line found. Entry is new in source file", "File format", "", nLine ); + bHasBlockError = TRUE; + } + else + { + if ( pSourceLine && !pSourceLine->Equals( *pReferenceLine ) ) + { + xub_StrLen nPos = pSourceLine->Match( *pReferenceLine ); + ByteString aContext( pReferenceLine->Copy( nPos - 5, 15) ); + aContext.Append( "\" --> \"" ).Append( pSourceLine->Copy( nPos - 5, 15) ); + PrintError( "Source Language Entry has changed.", "File format", aContext, pSourceLine->GetLineNumber(), pSourceLine->GetUniqId() ); + pSourceLine->NotOK(); + bHasError = TRUE; + } + } + } + + if ( pSourceLine ) + bHasError |= !TestUTF8( pSourceLine, bFixTags ); + + ULONG i; + for ( i = 0; i < Count(); i++ ) + { + aTester.CheckTestee( GetObject( i ), pSourceLine != NULL, bFixTags ); + if ( GetObject( i )->HasMessages() || aTester.HasCompareWarnings() ) + { + if ( GetObject( i )->HasMessages() || aTester.GetCompareWarnings().HasErrors() ) + GetObject( i )->NotOK(); + bHasError = TRUE; + PrintList( GetObject( i )->GetMessageList(), "Translation", GetObject( i ) ); + PrintList( &(aTester.GetCompareWarnings()), "Translation Tag Missmatch", GetObject( i ) ); + } + bHasError |= !TestUTF8( GetObject( i ), bFixTags ); + if ( pSourceLine ) + bHasError |= HasSuspiciousChars( GetObject( i ), pSourceLine ); + } + + return bHasError || bHasBlockError; +} + +void GSIBlock::WriteError( LazySvFileStream &aErrOut, BOOL bRequireSourceLine ) +{ + if ( pSourceLine && pSourceLine->IsOK() && bCheckSourceLang && !bHasBlockError ) + return; + + BOOL bHasError = FALSE; + BOOL bCopyAll = ( !pSourceLine && bRequireSourceLine ) || ( pSourceLine && !pSourceLine->IsOK() && !bCheckTranslationLang ) || bHasBlockError; + ULONG i; + for ( i = 0; i < Count(); i++ ) + { + if ( !GetObject( i )->IsOK() || bCopyAll ) + { + bHasError = TRUE; + aErrOut.LazyOpen(); + aErrOut.WriteLine( *GetObject( i ) ); + } + } + + if ( pSourceLine && ( bHasError || !pSourceLine->IsOK() ) && !( !bHasError && bCheckTranslationLang ) ) + { + aErrOut.LazyOpen(); + aErrOut.WriteLine( *pSourceLine ); + } +} + +void GSIBlock::WriteCorrect( LazySvFileStream &aOkOut, BOOL bRequireSourceLine ) +{ + if ( ( !pSourceLine && bRequireSourceLine ) || ( pSourceLine && !pSourceLine->IsOK() && !bCheckTranslationLang ) ) + return; + + BOOL bHasOK = FALSE; + ULONG i; + for ( i = 0; i < Count(); i++ ) + { + if ( ( GetObject( i )->IsOK() || bCheckSourceLang ) && !bHasBlockError ) + { + bHasOK = TRUE; + aOkOut.LazyOpen(); + aOkOut.WriteLine( *GetObject( i ) ); + } + } + + if ( ( pSourceLine && pSourceLine->IsOK() && ( Count() || !bCheckTranslationLang ) ) || ( bHasOK && bCheckTranslationLang ) ) + { + aOkOut.LazyOpen(); + aOkOut.WriteLine( *pSourceLine ); + } +} + +void GSIBlock::WriteFixed( LazySvFileStream &aFixOut, BOOL /*bRequireSourceLine*/ ) +{ + if ( pSourceLine && !pSourceLine->IsFixed() && bCheckSourceLang ) + return; + + BOOL bHasFixes = FALSE; + ULONG i; + for ( i = 0; i < Count(); i++ ) + { + if ( GetObject( i )->IsFixed() ) + { + bHasFixes = TRUE; + aFixOut.LazyOpen(); + aFixOut.WriteLine( *GetObject( i ) ); + } + } + + if ( pSourceLine && ( bHasFixes || pSourceLine->IsFixed() ) ) + { + aFixOut.LazyOpen(); + aFixOut.WriteLine( *pSourceLine ); + } +} + + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +void Help() +/*****************************************************************************/ +{ + fprintf( stdout, "\n" ); + fprintf( stdout, "gsicheck Version 1.9.0 (c)1999 - 2006 by SUN Microsystems\n" ); + fprintf( stdout, "=========================================================\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "gsicheck checks the syntax of tags in GSI-Files and SDF-Files\n" ); + fprintf( stdout, " checks for inconsistencies and malicious UTF8 encoding\n" ); + fprintf( stdout, " checks tags in Online Help\n" ); + fprintf( stdout, " checks for *new* KeyIDs and relax GID/LID length to %s\n", ByteString::CreateFromInt32(MAX_GID_LID_LEN).GetBuffer() ); + fprintf( stdout, "\n" ); + fprintf( stdout, "Syntax: gsicheck [ -c ] [-f] [ -we ] [ -wef ErrorFilename ] [ -wc ]\n" ); + fprintf( stdout, " [ -wcf CorrectFilename ] [ -s | -t ] [ -l LanguageID ]\n" ); + fprintf( stdout, " [ -r ReferenceFile ] filename\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "-c Add context to error message (Print the line containing the error)\n" ); + fprintf( stdout, "-f try to fix errors. See also -wf -wff \n" ); + fprintf( stdout, "-wf Write File containing all fixed parts\n" ); + fprintf( stdout, "-wff Same as above but give own filename\n" ); + fprintf( stdout, "-we Write File containing all errors\n" ); + fprintf( stdout, "-wef Same as above but give own filename\n" ); + fprintf( stdout, "-wc Write File containing all correct parts\n" ); + fprintf( stdout, "-wcf Same as above but give own filename\n" ); + fprintf( stdout, "-s Check only source language. Should be used before handing out to vendor.\n" ); + fprintf( stdout, "-t Check only Translation language(s). Should be used before merging.\n" ); + fprintf( stdout, "-k Allow KeyIDs to be present in strings\n" ); + fprintf( stdout, "-e disable encoding checks. E.g.: double questionmark \'??\' which may be the\n" ); + fprintf( stdout, " result of false conversions\n" ); + fprintf( stdout, "-l ISO Languagecode or numerical 2 digits Identifier of the source language.\n" ); + fprintf( stdout, " Default is en-US. Use \"\" (empty string) or 'none'\n" ); + fprintf( stdout, " to disable source language dependent checks\n" ); + fprintf( stdout, "-r Reference filename to check that source language entries\n" ); + fprintf( stdout, " have not been changed\n" ); + fprintf( stdout, "\n" ); +} + +/*****************************************************************************/ +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + + BOOL bError = FALSE; + BOOL bPrintContext = FALSE; + BOOL bCheckSourceLang = FALSE; + BOOL bCheckTranslationLang = FALSE; + BOOL bWriteError = FALSE; + BOOL bWriteCorrect = FALSE; + BOOL bWriteFixed = FALSE; + BOOL bFixTags = FALSE; + BOOL bAllowKID = FALSE; + BOOL bAllowSuspicious = FALSE; + String aErrorFilename; + String aCorrectFilename; + String aFixedFilename; + BOOL bFileHasError = FALSE; + ByteString aSourceLang( "en-US" ); // English is default + ByteString aFilename; + ByteString aReferenceFilename; + BOOL bReferenceFile = FALSE; + for ( USHORT i = 1 ; i < argc ; i++ ) + { + if ( *argv[ i ] == '-' ) + { + switch (*(argv[ i ]+1)) + { + case 'c':bPrintContext = TRUE; + break; + case 'w': + { + if ( (*(argv[ i ]+2)) == 'e' ) + { + if ( (*(argv[ i ]+3)) == 'f' ) + if ( (i+1) < argc ) + { + aErrorFilename = String( argv[ i+1 ], RTL_TEXTENCODING_ASCII_US ); + bWriteError = TRUE; + i++; + } + else + { + fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); + bError = TRUE; + } + else + bWriteError = TRUE; + } + else if ( (*(argv[ i ]+2)) == 'c' ) + if ( (*(argv[ i ]+3)) == 'f' ) + if ( (i+1) < argc ) + { + aCorrectFilename = String( argv[ i+1 ], RTL_TEXTENCODING_ASCII_US ); + bWriteCorrect = TRUE; + i++; + } + else + { + fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); + bError = TRUE; + } + else + bWriteCorrect = TRUE; + else if ( (*(argv[ i ]+2)) == 'f' ) + if ( (*(argv[ i ]+3)) == 'f' ) + if ( (i+1) < argc ) + { + aFixedFilename = String( argv[ i+1 ], RTL_TEXTENCODING_ASCII_US ); + bWriteFixed = TRUE; + bFixTags = TRUE; + i++; + } + else + { + fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); + bError = TRUE; + } + else + { + bWriteFixed = TRUE; + bFixTags = TRUE; + } + else + { + fprintf( stderr, "\nERROR: Unknown Switch %s!\n\n", argv[ i ] ); + bError = TRUE; + } + } + break; + case 's':bCheckSourceLang = TRUE; + break; + case 't':bCheckTranslationLang = TRUE; + break; + case 'l': + { + if ( (i+1) < argc ) + { + aSourceLang = ByteString( argv[ i+1 ] ); + if ( aSourceLang.EqualsIgnoreCaseAscii( "none" ) ) + aSourceLang.Erase(); + i++; + } + else + { + fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); + bError = TRUE; + } + } + break; + case 'r': + { + if ( (i+1) < argc ) + { + aReferenceFilename = argv[ i+1 ]; + bReferenceFile = TRUE; + i++; + } + else + { + fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] ); + bError = TRUE; + } + } + break; + case 'f': + { + bFixTags = TRUE; + } + break; + case 'k': + { + bAllowKID = TRUE; + } + break; + case 'e': + { + bAllowSuspicious = TRUE; + } + break; + default: + fprintf( stderr, "\nERROR: Unknown Switch %s!\n\n", argv[ i ] ); + bError = TRUE; + } + } + else + { + if ( !aFilename.Len()) + aFilename = ByteString( argv[ i ] ); + else + { + fprintf( stderr, "\nERROR: Only one filename may be specified!\n\n"); + bError = TRUE; + } + } + } + + + if ( !aFilename.Len() || bError ) + { + Help(); + exit ( 0 ); + } + + if ( aSourceLang.Len() && !LanguageOK( aSourceLang ) ) + { + fprintf( stderr, "\nERROR: The Language '%s' is invalid!\n\n", aSourceLang.GetBuffer() ); + Help(); + exit ( 1 ); + } + + if ( bCheckSourceLang && bCheckTranslationLang ) + { + fprintf( stderr, "\nERROR: The Options -s and -t are mutually exclusive.\nUse only one of them.\n\n" ); + Help(); + exit ( 1 ); + } + + + + DirEntry aSource = DirEntry( String( aFilename, RTL_TEXTENCODING_ASCII_US )); + if ( !aSource.Exists()) { + fprintf( stderr, "\nERROR: GSI-File %s not found!\n\n", aFilename.GetBuffer() ); + exit ( 2 ); + } + + SvFileStream aGSI( String( aFilename, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); + if ( !aGSI.IsOpen()) { + fprintf( stderr, "\nERROR: Could not open GSI-File %s!\n\n", aFilename.GetBuffer() ); + exit ( 3 ); + } + + SvFileStream aReferenceGSI; + if ( bReferenceFile ) + { + DirEntry aReferenceSource = DirEntry( String( aReferenceFilename, RTL_TEXTENCODING_ASCII_US )); + if ( !aReferenceSource.Exists()) { + fprintf( stderr, "\nERROR: GSI-File %s not found!\n\n", aFilename.GetBuffer() ); + exit ( 2 ); + } + + aReferenceGSI.Open( String( aReferenceFilename, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); + if ( !aReferenceGSI.IsOpen()) { + fprintf( stderr, "\nERROR: Could not open Input-File %s!\n\n", aFilename.GetBuffer() ); + exit ( 3 ); + } + } + + LazySvFileStream aOkOut; + String aBaseName = aSource.GetBase(); + if ( bWriteCorrect ) + { + if ( !aCorrectFilename.Len() ) + { + String sTmpBase( aBaseName ); + sTmpBase += String( "_ok", RTL_TEXTENCODING_ASCII_US ); + aSource.SetBase( sTmpBase ); + aCorrectFilename = aSource.GetFull(); + } + aOkOut.SetOpenParams( aCorrectFilename , STREAM_STD_WRITE | STREAM_TRUNC ); + } + + LazySvFileStream aErrOut; + if ( bWriteError ) + { + if ( !aErrorFilename.Len() ) + { + String sTmpBase( aBaseName ); + sTmpBase += String( "_err", RTL_TEXTENCODING_ASCII_US ); + aSource.SetBase( sTmpBase ); + aErrorFilename = aSource.GetFull(); + } + aErrOut.SetOpenParams( aErrorFilename , STREAM_STD_WRITE | STREAM_TRUNC ); + } + + LazySvFileStream aFixOut; + if ( bWriteFixed ) + { + if ( !aFixedFilename.Len() ) + { + String sTmpBase( aBaseName ); + sTmpBase += String( "_fix", RTL_TEXTENCODING_ASCII_US ); + aSource.SetBase( sTmpBase ); + aFixedFilename = aSource.GetFull(); + } + aFixOut.SetOpenParams( aFixedFilename , STREAM_STD_WRITE | STREAM_TRUNC ); + } + + + ByteString sReferenceLine; + GSILine* pReferenceLine = NULL; + ByteString aOldReferenceId("No Valid ID"); // just set to something which can never be an ID + ULONG nReferenceLine = 0; + + ByteString sGSILine; + GSILine* pGSILine = NULL; + ByteString aOldId("No Valid ID"); // just set to something which can never be an ID + GSIBlock *pBlock = NULL; + ULONG nLine = 0; + + while ( !aGSI.IsEof() ) + { + aGSI.ReadLine( sGSILine ); + nLine++; + pGSILine = new GSILine( sGSILine, nLine ); + BOOL bDelete = TRUE; + + + if ( pGSILine->Len() ) + { + if ( FORMAT_UNKNOWN == pGSILine->GetLineFormat() ) + { + PrintError( "Format of line is unknown. Ignoring!", "Line format", pGSILine->Copy( 0,40 ), bPrintContext, pGSILine->GetLineNumber() ); + pGSILine->NotOK(); + if ( bWriteError ) + { + bFileHasError = TRUE; + aErrOut.LazyOpen(); + aErrOut.WriteLine( *pGSILine ); + } + } + else if ( pGSILine->GetLineType().EqualsIgnoreCaseAscii("res-comment") ) + { // ignore comment lines, but write them to Correct Items File + if ( bWriteCorrect ) + { + aOkOut.LazyOpen(); + aOkOut.WriteLine( *pGSILine ); + } + } + else + { + ByteString aId = pGSILine->GetUniqId(); + if ( aId != aOldId ) + { + if ( pBlock ) + { + bFileHasError |= pBlock->CheckSyntax( nLine, aSourceLang.Len() != 0, bFixTags ); + + if ( bWriteError ) + pBlock->WriteError( aErrOut, aSourceLang.Len() != 0 ); + if ( bWriteCorrect ) + pBlock->WriteCorrect( aOkOut, aSourceLang.Len() != 0 ); + if ( bWriteFixed ) + pBlock->WriteFixed( aFixOut, aSourceLang.Len() != 0 ); + + delete pBlock; + } + pBlock = new GSIBlock( bPrintContext, bCheckSourceLang, bCheckTranslationLang, bReferenceFile, bAllowKID, bAllowSuspicious ); + + aOldId = aId; + + + // find corresponding line in reference file + if ( bReferenceFile ) + { + BOOL bContinueSearching = TRUE; + while ( ( !aReferenceGSI.IsEof() || pReferenceLine ) && bContinueSearching ) + { + if ( !pReferenceLine ) + { + aReferenceGSI.ReadLine( sReferenceLine ); + nReferenceLine++; + pReferenceLine = new GSILine( sReferenceLine, nReferenceLine ); + } + if ( pReferenceLine->GetLineFormat() != FORMAT_UNKNOWN ) + { + if ( pReferenceLine->GetUniqId() == aId && pReferenceLine->GetLanguageId().Equals( aSourceLang ) ) + { + pBlock->SetReferenceLine( pReferenceLine ); + pReferenceLine = NULL; + } + else if ( pReferenceLine->GetUniqId() > aId ) + { +// if ( pGSILine->GetLanguageId() == aSourceLang ) +// PrintError( "No reference line found. Entry is new in source file", "File format", "", bPrintContext, pGSILine->GetLineNumber(), aId ); + bContinueSearching = FALSE; + } + else + { + if ( pReferenceLine->GetUniqId() < aId && pReferenceLine->GetLanguageId().Equals( aSourceLang ) ) + PrintError( "No Entry in source file found. Entry has been removed from source file", "File format", "", bPrintContext, pGSILine->GetLineNumber(), pReferenceLine->GetUniqId() ); + delete pReferenceLine; + pReferenceLine = NULL; + } + } + else + { + delete pReferenceLine; + pReferenceLine = NULL; + } + + } + } + + } + + pBlock->InsertLine( pGSILine, aSourceLang ); + bDelete = FALSE; + } + } + if ( bDelete ) + delete pGSILine; + + } + if ( pBlock ) + { + bFileHasError |= pBlock->CheckSyntax( nLine, aSourceLang.Len() != 0, bFixTags ); + + if ( bWriteError ) + pBlock->WriteError( aErrOut, aSourceLang.Len() != 0 ); + if ( bWriteCorrect ) + pBlock->WriteCorrect( aOkOut, aSourceLang.Len() != 0 ); + if ( bWriteFixed ) + pBlock->WriteFixed( aFixOut, aSourceLang.Len() != 0 ); + + delete pBlock; + } + aGSI.Close(); + + if ( bWriteError ) + aErrOut.Close(); + if ( bWriteCorrect ) + aOkOut.Close(); + if ( bWriteFixed ) + aFixOut.Close(); + + if ( bFileHasError ) + return 55; + else + return 0; +} diff --git a/transex3/source/gsicheck.hxx b/transex3/source/gsicheck.hxx new file mode 100644 index 000000000000..13debcfc7106 --- /dev/null +++ b/transex3/source/gsicheck.hxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: gsicheck.hxx,v $ + * $Revision: 1.8.22.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _GSICHECK_HXX_ +#define _GSICHECK_HXX_ + +#include "tagtest.hxx" + +// +// class GSILine +// +enum LineFormat { FORMAT_GSI, FORMAT_SDF, FORMAT_UNKNOWN }; + +class GSILine : public ByteString +{ +private: + + ParserMessageList aMessages; + LineFormat aFormat; + ULONG nLineNumber; + + ByteString aUniqId; + ByteString aLineType; + ByteString aLangId; + ByteString aText; + ByteString aQuickHelpText; + ByteString aTitle; + + BOOL bOK; + BOOL bFixed; + + void ReassembleLine(); + +public: + GSILine( const ByteString &rLine, ULONG nLine ); + LineFormat GetLineFormat() const { return aFormat; } + ULONG GetLineNumber() const { return nLineNumber; } + + ByteString const GetUniqId() const { return aUniqId; } + ByteString const GetLineType() const { return aLineType; } + ByteString const GetLanguageId() const { return aLangId; } + ByteString const GetText() const { return aText; } + String const GetUText() const { return String( aText, RTL_TEXTENCODING_UTF8 ); } + ByteString const GetQuickHelpText() const { return aQuickHelpText; } + ByteString const GetTitle() const { return aTitle; } + + void SetUText( String &aNew ) { aText = ByteString( aNew, RTL_TEXTENCODING_UTF8 ); ReassembleLine(); } + void SetText( ByteString &aNew ) { aText = aNew; ReassembleLine(); } + void SetQuickHelpText( ByteString &aNew ) { aQuickHelpText = aNew; ReassembleLine(); } + void SetTitle( ByteString &aNew ) { aTitle = aNew; ReassembleLine(); } + + ParserMessageList* GetMessageList() { return &aMessages; }; + BOOL HasMessages(){ return ( aMessages.Count() > 0 ); }; + + BOOL IsOK() const { return bOK; } + void NotOK(); + + BOOL IsFixed() const { return bFixed; } + void SetFixed() { bFixed = TRUE; }; +}; + +// +// class GSIBlock +// + +DECLARE_LIST( GSIBlock_Impl, GSILine * ) + +class LazySvFileStream; + +class GSIBlock : public GSIBlock_Impl +{ +private: + GSILine *pSourceLine; + GSILine *pReferenceLine; + void PrintList( ParserMessageList *pList, ByteString aPrefix, GSILine *pLine ); + BOOL bPrintContext; + BOOL bCheckSourceLang; + BOOL bCheckTranslationLang; + BOOL bReference; + BOOL bAllowKeyIDs; + BOOL bAllowSuspicious; + + BOOL bHasBlockError; + + BOOL IsUTF8( const ByteString &aTestee, BOOL bFixTags, USHORT &nErrorPos, ByteString &aErrorMsg, BOOL &bHasBeenFixed, ByteString &aFixed ) const; + BOOL TestUTF8( GSILine* pTestee, BOOL bFixTags ); + BOOL HasSuspiciousChars( GSILine* pTestee, GSILine* pSource ); + +public: + GSIBlock( BOOL PbPrintContext, BOOL bSource, BOOL bTrans, BOOL bRef, BOOL bAllowKID, BOOL bAllowSusp ); + ~GSIBlock(); + void PrintMessage( ByteString aType, ByteString aMsg, ByteString aPrefix, ByteString aContext, ULONG nLine, ByteString aUniqueId = ByteString() ); + void PrintError( ByteString aMsg, ByteString aPrefix, ByteString aContext, ULONG nLine, ByteString aUniqueId = ByteString() ); + void InsertLine( GSILine* pLine, const ByteString aSourceLang); + void SetReferenceLine( GSILine* pLine ); + BOOL CheckSyntax( ULONG nLine, BOOL bRequireSourceLine, BOOL bFixTags ); + + void WriteError( LazySvFileStream &aErrOut, BOOL bRequireSourceLine ); + void WriteCorrect( LazySvFileStream &aOkOut, BOOL bRequireSourceLine ); + void WriteFixed( LazySvFileStream &aFixOut, BOOL bRequireSourceLine ); +}; + +#endif + diff --git a/transex3/source/gsiconv.cxx b/transex3/source/gsiconv.cxx new file mode 100644 index 000000000000..f6dea76ebb51 --- /dev/null +++ b/transex3/source/gsiconv.cxx @@ -0,0 +1,372 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: gsiconv.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <tools/fsys.hxx> +#include <tools/stream.hxx> + +// local includes +#include "utf8conv.hxx" + +#define GSI_FILE_UNKNOWN 0x0000 +#define GSI_FILE_OLDSTYLE 0x0001 +#define GSI_FILE_L10NFRAMEWORK 0x0002 + +/*****************************************************************************/ +USHORT GetGSIFileType( SvStream &rStream ) +/*****************************************************************************/ +{ + USHORT nFileType = GSI_FILE_UNKNOWN; + + ULONG nPos( rStream.Tell()); + rStream.Seek( STREAM_SEEK_TO_BEGIN ); + + ByteString sLine; + while( !rStream.IsEof() && !sLine.Len()) + rStream.ReadLine( sLine ); + + if( sLine.Len()) { + if( sLine.Search( "($$)" ) != STRING_NOTFOUND ) + nFileType = GSI_FILE_OLDSTYLE; + else + nFileType = GSI_FILE_L10NFRAMEWORK; + } + + rStream.Seek( nPos ); + + return nFileType; +} + +/*****************************************************************************/ +ByteString GetGSILineId( const ByteString &rLine, USHORT nFileType ) +/*****************************************************************************/ +{ + ByteString sId; + switch ( nFileType ) { + case GSI_FILE_OLDSTYLE: + sId = rLine; + sId.SearchAndReplaceAll( "($$)", "\t" ); + sId = sId.GetToken( 0, '\t' ); + break; + + case GSI_FILE_L10NFRAMEWORK: + sId = rLine.GetToken( 0, '\t' ); + sId += "\t"; + sId += rLine.GetToken( 1, '\t' ); + sId += "\t"; + sId += rLine.GetToken( 4, '\t' ); + sId += "\t"; + sId += rLine.GetToken( 5, '\t' ); + break; + } + return sId; +} + +/*****************************************************************************/ +ByteString GetGSILineLangId( const ByteString &rLine, USHORT nFileType ) +/*****************************************************************************/ +{ + ByteString sLangId; + switch ( nFileType ) { + case GSI_FILE_OLDSTYLE: + sLangId = rLine; + sLangId.SearchAndReplaceAll( "($$)", "\t" ); + sLangId = sLangId.GetToken( 2, '\t' ); + break; + + case GSI_FILE_L10NFRAMEWORK: + sLangId = rLine.GetToken( 9, '\t' ); + break; + } + return sLangId; +} + +/*****************************************************************************/ +void ConvertGSILine( BOOL bToUTF8, ByteString &rLine, + rtl_TextEncoding nEncoding, USHORT nFileType ) +/*****************************************************************************/ +{ + switch ( nFileType ) { + case GSI_FILE_OLDSTYLE: + if ( bToUTF8 ) + rLine = UTF8Converter::ConvertToUTF8( rLine, nEncoding ); + else + rLine = UTF8Converter::ConvertFromUTF8( rLine, nEncoding ); + break; + + case GSI_FILE_L10NFRAMEWORK: { + ByteString sConverted; + for ( USHORT i = 0; i < rLine.GetTokenCount( '\t' ); i++ ) { + ByteString sToken = rLine.GetToken( i, '\t' ); + if (( i > 9 ) && ( i < 14 )) { + if( bToUTF8 ) + sToken = UTF8Converter::ConvertToUTF8( sToken, nEncoding ); + else + sToken = UTF8Converter::ConvertFromUTF8( sToken, nEncoding ); + } + if ( i ) + sConverted += "\t"; + sConverted += sToken; + } + rLine = sConverted; + } + break; + } +} + +/*****************************************************************************/ +void Help() +/*****************************************************************************/ +{ + fprintf( stdout, "\n" ); + fprintf( stdout, "gsiconv (c)1999 by StarOffice Entwicklungs GmbH\n" ); + fprintf( stdout, "===============================================\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "gsiconv converts strings in GSI-Files (Gutschmitt Interface) from or to UTF-8\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "Syntax: gsiconv (-t|-f langid charset)|(-p n) filename\n" ); + fprintf( stdout, "Switches: -t => conversion from charset to UTF-8\n" ); + fprintf( stdout, " -f => conversion from UTF-8 to charset\n" ); + fprintf( stdout, " -p n => creates several files with ca. n lines\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "Allowed charsets:\n" ); + fprintf( stdout, " MS_932 => Japanese\n" ); + fprintf( stdout, " MS_936 => Chinese Simplified\n" ); + fprintf( stdout, " MS_949 => Korean\n" ); + fprintf( stdout, " MS_950 => Chinese Traditional\n" ); + fprintf( stdout, " MS_1250 => East Europe\n" ); + fprintf( stdout, " MS_1251 => Cyrillic\n" ); + fprintf( stdout, " MS_1252 => West Europe\n" ); + fprintf( stdout, " MS_1253 => Greek\n" ); + fprintf( stdout, " MS_1254 => Turkish\n" ); + fprintf( stdout, " MS_1255 => Hebrew\n" ); + fprintf( stdout, " MS_1256 => Arabic\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "Allowed langids:\n" ); + fprintf( stdout, " 1 => ENGLISH_US\n" ); + fprintf( stdout, " 3 => PORTUGUESE \n" ); + fprintf( stdout, " 4 => GERMAN_DE (new german style)\n" ); + fprintf( stdout, " 7 => RUSSIAN\n" ); + fprintf( stdout, " 30 => GREEK\n" ); + fprintf( stdout, " 31 => DUTCH\n" ); + fprintf( stdout, " 33 => FRENCH\n" ); + fprintf( stdout, " 34 => SPANISH\n" ); + fprintf( stdout, " 35 => FINNISH\n" ); + fprintf( stdout, " 36 => HUNGARIAN\n" ); + fprintf( stdout, " 39 => ITALIAN\n" ); + fprintf( stdout, " 42 => CZECH\n" ); + fprintf( stdout, " 44 => ENGLISH (UK)\n" ); + fprintf( stdout, " 45 => DANISH\n" ); + fprintf( stdout, " 46 => SWEDISH\n" ); + fprintf( stdout, " 47 => NORWEGIAN\n" ); + fprintf( stdout, " 49 => GERMAN (old german style)\n" ); + fprintf( stdout, " 55 => PORTUGUESE_BRAZILIAN\n" ); + fprintf( stdout, " 81 => JAPANESE\n" ); + fprintf( stdout, " 82 => KOREAN\n" ); + fprintf( stdout, " 86 => CHINESE_SIMPLIFIED\n" ); + fprintf( stdout, " 88 => CHINESE_TRADITIONAL\n" ); + fprintf( stdout, " 90 => TURKISH\n" ); + fprintf( stdout, " 96 => ARABIC\n" ); + fprintf( stdout, " 97 => HEBREW\n" ); + fprintf( stdout, "\n" ); +} + +/*****************************************************************************/ +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + if (( argc != 5 ) && ( argc != 4 )) { + Help(); + exit ( 0 ); + } + + if ( argc == 4 ) { + if ( ByteString( argv[ 1 ] ) == "-p" ) { + + DirEntry aSource = DirEntry( String( argv[ 3 ], RTL_TEXTENCODING_ASCII_US )); + if ( !aSource.Exists()) { + fprintf( stderr, "\nERROR: GSI-File %s not found!\n\n", ByteString( argv[ 3 ] ).GetBuffer()); + exit ( 2 ); + } + + DirEntry aOutput( aSource ); + + String sBase = aOutput.GetBase(); + String sExt = aOutput.GetExtension(); + + String sGSI( argv[ 3 ], RTL_TEXTENCODING_ASCII_US ); + SvFileStream aGSI( sGSI, STREAM_STD_READ ); + if ( !aGSI.IsOpen()) { + fprintf( stderr, "\nERROR: Could not open GSI-File %s!\n\n", ByteString( argv[ 3 ] ).GetBuffer()); + exit ( 3 ); + } + + USHORT nFileType( GetGSIFileType( aGSI )); + + ULONG nMaxLines = (ULONG) ByteString( argv[ 2 ] ).ToInt64(); + if ( !nMaxLines ) { + fprintf( stderr, "\nERROR: Linecount must be at least 1!\n\n" ); + exit ( 3 ); + } + + ByteString sGSILine; + ByteString sOldId; + ULONG nLine = 0; + ULONG nOutputFile = 1; + + String sOutput( sBase ); + sOutput += String( "_", RTL_TEXTENCODING_ASCII_US ); + sOutput += String::CreateFromInt64( nOutputFile ); + if ( sExt.Len()) { + sOutput += String( ".", RTL_TEXTENCODING_ASCII_US ); + sOutput += sExt; + } + nOutputFile ++; + + aOutput.SetName( sOutput ); + SvFileStream aOutputStream( aOutput.GetFull(), STREAM_STD_WRITE | STREAM_TRUNC ); + + while ( !aGSI.IsEof()) { + + aGSI.ReadLine( sGSILine ); + ByteString sId( GetGSILineId( sGSILine, nFileType )); + + nLine++; + + if (( nLine >= nMaxLines ) && ( sId != sOldId )) { + aOutputStream.Close(); + + ByteString sText( aOutput.GetFull(), gsl_getSystemTextEncoding()); + sText += " with "; + sText += ByteString::CreateFromInt64( nLine ); + sText += " lines written."; + + fprintf( stdout, "%s\n", sText.GetBuffer()); + String sOutput1( sBase ); + sOutput1 += String( "_", RTL_TEXTENCODING_ASCII_US ); + sOutput1 += String::CreateFromInt64( nOutputFile ); + if ( sExt.Len()) { + sOutput1 += String( ".", RTL_TEXTENCODING_ASCII_US ); + sOutput1 += sExt; + } + nOutputFile ++; + + aOutput.SetName( sOutput1 ); + + aOutputStream.Open( aOutput.GetFull(), STREAM_STD_WRITE | STREAM_TRUNC ); + nLine = 0; + } + + aOutputStream.WriteLine( sGSILine ); + + sOldId = sId; + } + + aGSI.Close(); + aOutputStream.Close(); + + ByteString sText( aOutput.GetFull(), RTL_TEXTENCODING_ASCII_US ); + sText += " with "; + sText += ByteString::CreateFromInt64( nLine ); + sText += " lines written."; + } + else { + Help(); + exit( 1 ); + } + } + else { + if ( ByteString( argv[ 1 ] ) == "-t" || ByteString( argv[ 1 ] ) == "-f" ) { + rtl_TextEncoding nEncoding; + + ByteString sCurLangId( argv[ 2 ] ); + + ByteString sCharset( argv[ 3 ] ); + sCharset.ToUpperAscii(); + + if ( sCharset == "MS_932" ) nEncoding = RTL_TEXTENCODING_MS_932; + else if ( sCharset == "MS_936" ) nEncoding = RTL_TEXTENCODING_MS_936; + else if ( sCharset == "MS_949" ) nEncoding = RTL_TEXTENCODING_MS_949; + else if ( sCharset == "MS_950" ) nEncoding = RTL_TEXTENCODING_MS_950; + else if ( sCharset == "MS_1250" ) nEncoding = RTL_TEXTENCODING_MS_1250; + else if ( sCharset == "MS_1251" ) nEncoding = RTL_TEXTENCODING_MS_1251; + else if ( sCharset == "MS_1252" ) nEncoding = RTL_TEXTENCODING_MS_1252; + else if ( sCharset == "MS_1253" ) nEncoding = RTL_TEXTENCODING_MS_1253; + else if ( sCharset == "MS_1254" ) nEncoding = RTL_TEXTENCODING_MS_1254; + else if ( sCharset == "MS_1255" ) nEncoding = RTL_TEXTENCODING_MS_1255; + else if ( sCharset == "MS_1256" ) nEncoding = RTL_TEXTENCODING_MS_1256; + else if ( sCharset == "MS_1257" ) nEncoding = RTL_TEXTENCODING_MS_1257; + else if ( sCharset == "UTF8" ) nEncoding = RTL_TEXTENCODING_UTF8; + + else { + Help(); + exit ( 1 ); + } + + DirEntry aSource = DirEntry( String( argv[ 4 ], RTL_TEXTENCODING_ASCII_US )); + if ( !aSource.Exists()) { + fprintf( stderr, "\nERROR: GSI-File %s not found!\n\n", ByteString( argv[ 3 ] ).GetBuffer()); + exit ( 2 ); + } + + String sGSI( argv[ 4 ], RTL_TEXTENCODING_ASCII_US ); + SvFileStream aGSI( sGSI, STREAM_STD_READ ); + if ( !aGSI.IsOpen()) { + fprintf( stderr, "\nERROR: Could not open GSI-File %s!\n\n", ByteString( argv[ 3 ] ).GetBuffer()); + exit ( 3 ); + } + USHORT nFileType( GetGSIFileType( aGSI )); + + ByteString sGSILine; + while ( !aGSI.IsEof()) { + + aGSI.ReadLine( sGSILine ); + ByteString sLangId( GetGSILineLangId( sGSILine, nFileType )); + if ( sLangId == sCurLangId ) + ConvertGSILine(( ByteString( argv[ 1 ] ) == "-t" ), sGSILine, nEncoding, nFileType ); + + fprintf( stdout, "%s\n", sGSILine.GetBuffer()); + } + + aGSI.Close(); + } + else { + Help(); + exit( 1 ); + } + } + return 0; +} diff --git a/transex3/source/helpex.cxx b/transex3/source/helpex.cxx new file mode 100644 index 000000000000..f4a1589b530e --- /dev/null +++ b/transex3/source/helpex.cxx @@ -0,0 +1,299 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: helpex.cxx,v $ + * $Revision: 1.14 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <stdlib.h> + +// local includes +#include "helpmerge.hxx" + +// defines to parse command line +#define STATE_NON 0x0001 +#define STATE_INPUT 0x0002 +#define STATE_OUTPUT 0x0003 +#define STATE_PRJ 0x0004 +#define STATE_ROOT 0x0005 +#define STATE_SDFFILE 0x0006 +#define STATE_ERRORLOG 0x0007 +#define STATE_BREAKHELP 0x0008 +#define STATE_UNMERGE 0x0009 +#define STATE_UTF8 0x000A +#define STATE_LANGUAGES 0x000B +#define STATE_FORCE_LANGUAGES 0x000C +#define STATE_OUTPUTX 0xfe +#define STATE_OUTPUTY 0xff + +// set of global variables +ByteString sInputFile; +BOOL bEnableExport; +BOOL bMergeMode; +BOOL bErrorLog; +BOOL bUTF8; +ByteString sPrj; +ByteString sPrjRoot; +ByteString sOutputFile; +ByteString sOutputFileX; +ByteString sOutputFileY; +ByteString sSDFFile; +bool bQuiet; + +/*****************************************************************************/ +BOOL ParseCommandLine( int argc, char* argv[]) +/*****************************************************************************/ +{ + bEnableExport = FALSE; + bMergeMode = FALSE; + bErrorLog = TRUE; + bUTF8 = TRUE; + sPrj = ""; + sPrjRoot = ""; + bQuiet = false; + Export::sLanguages = ""; + Export::sForcedLanguages = ""; + + USHORT nState = STATE_NON; + BOOL bInput = FALSE; + + // parse command line + for( int i = 1; i < argc; i++ ) { + if ( ByteString( argv[ i ]).ToUpperAscii() == "-I" ) { + nState = STATE_INPUT; // next tokens specifies source files + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-O" ) { + nState = STATE_OUTPUT; // next token specifies the dest file + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-X" ) { + nState = STATE_OUTPUTX; // next token specifies the dest file + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-Y" ) { + nState = STATE_OUTPUTY; // next token specifies the dest file + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-P" ) { + nState = STATE_PRJ; // next token specifies the cur. project + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-LF" ) { + nState = STATE_FORCE_LANGUAGES; + } + + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-R" ) { + nState = STATE_ROOT; // next token specifies path to project root + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-M" ) { + nState = STATE_SDFFILE; // next token specifies the merge database + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-E" ) { + nState = STATE_ERRORLOG; + bErrorLog = FALSE; + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-QQ" ) { + bQuiet = true; + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-UTF8" ) { + nState = STATE_UTF8; + bUTF8 = TRUE; + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-NOUTF8" ) { + nState = STATE_UTF8; + bUTF8 = FALSE; + } + else if ( ByteString( argv[ i ]).ToUpperAscii() == "-L" ) { + nState = STATE_LANGUAGES; + } + else { + switch ( nState ) { + case STATE_NON: { + return FALSE; // no valid command line + } + //break; + case STATE_INPUT: { + sInputFile = argv[ i ]; + bInput = TRUE; // source file found + } + break; + case STATE_OUTPUT: { + sOutputFile = argv[ i ]; // the dest. file + } + break; + case STATE_OUTPUTX: { + sOutputFileX = argv[ i ]; // the dest. file + } + break; + case STATE_OUTPUTY: { + sOutputFileY = argv[ i ]; // the dest. file + } + break; + case STATE_PRJ: { + sPrj = argv[ i ]; +// sPrj.ToLowerAscii(); // the project + } + break; + case STATE_ROOT: { + sPrjRoot = argv[ i ]; // path to project root + } + break; + case STATE_SDFFILE: { + sSDFFile = argv[ i ]; + bMergeMode = TRUE; // activate merge mode, cause merge database found + } + break; + case STATE_LANGUAGES: { + Export::sLanguages = argv[ i ]; + } + case STATE_FORCE_LANGUAGES:{ + Export::sForcedLanguages = argv[ i ]; + } + break; + } + } + } + + if ( bInput ) { + // command line is valid + bEnableExport = TRUE; + return TRUE; + } + + // command line is not valid + return FALSE; +} + + +/*****************************************************************************/ +void Help() +/*****************************************************************************/ +{ + fprintf( stdout, "Syntax: HELPEX[-p Prj][-r PrjRoot]-i FileIn ( -o FileOut | -x path -y relfile )[-m DataBase][-e][-b][-u][-L l1,l2,...][-QQ] -LF l1,l2 \n" ); + fprintf( stdout, " Prj: Project\n" ); + fprintf( stdout, " PrjRoot: Path to project root (..\\.. etc.)\n" ); + fprintf( stdout, " FileIn: Source file (*.lng)\n" ); + fprintf( stdout, " FileOut: Destination file (*.*)\n" ); + fprintf( stdout, " DataBase: Mergedata (*.sdf)\n" ); + fprintf( stdout, " -QQ: quiet output\n" ); + fprintf( stdout, " -L: Restrict the handled languages. l1,l2,... are elements of (en-US,fr,de...)\n" ); + fprintf( stdout, " A fallback language can be defined like this: l1=f1.\n" ); + fprintf( stdout, " f1, f2,... are also elements of (en-US,fr,de...)\n" ); + fprintf( stdout, " Example: -L fr=en-US\n" ); + fprintf( stdout, " Restriction to fr, en-US will be fallback for fr\n" ); + fprintf( stdout, " -LF: Force the creation of that languages\n" ); + +} + +/*****************************************************************************/ +#ifndef TESTDRIVER + +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + + if ( !ParseCommandLine( argc, argv )) { + Help(); + return 1; + } + //sal_uInt32 startfull = Export::startMessure(); + + bool hasInputList = sInputFile.GetBuffer()[0]=='@'; +// printf("x = %s , y = %s , o = %s\n", sOutputFileX.GetBuffer(), sOutputFileY.GetBuffer() , sOutputFile.GetBuffer() ); + bool hasNoError = true; + + if ( sOutputFile.Len() ){ // Merge single file ? + //printf("DBG: Inputfile = %s\n",sInputFile.GetBuffer()); + HelpParser aParser( sInputFile, bUTF8 , false ); + + if ( bMergeMode ) + { + + //sal_uInt64 startreadloc = Export::startMessure(); + MergeDataFile aMergeDataFile( sSDFFile, sInputFile , FALSE, RTL_TEXTENCODING_MS_1252 ); + //MergeDataFile aMergeDataFile( sSDFFile, sInputFile , FALSE, RTL_TEXTENCODING_MS_1252, false ); + //Export::stopMessure( ByteString("read localize.sdf") , startreadloc ); + + hasNoError = aParser.Merge( sSDFFile, sOutputFile , Export::sLanguages , aMergeDataFile ); + } + else + hasNoError = aParser.CreateSDF( sOutputFile, sPrj, sPrjRoot, sInputFile, new XMLFile( '0' ), "help" ); + }else if ( sOutputFileX.Len() && sOutputFileY.Len() && hasInputList ) { // Merge multiple files ? + if ( bMergeMode ){ + + ifstream aFStream( sInputFile.Copy( 1 , sInputFile.Len() ).GetBuffer() , ios::in ); + + if( !aFStream ){ + cerr << "ERROR: - helpex - Can't open the file " << sInputFile.Copy( 1 , sInputFile.Len() ).GetBuffer() << "\n"; + exit(-1); + } + + vector<ByteString> filelist; + rtl::OStringBuffer filename; + sal_Char aChar; + while( aFStream.get( aChar ) ) + { + if( aChar == ' ' || aChar == '\n') + filelist.push_back( ByteString( filename.makeStringAndClear().getStr() ) ); + else + filename.append( aChar ); + } + if( filename.getLength() > 0 ) + filelist.push_back( ByteString ( filename.makeStringAndClear().getStr() ) ); + + aFStream.close(); + ByteString sHelpFile(""); // dummy + //MergeDataFile aMergeDataFile( sSDFFile, sHelpFile , FALSE, RTL_TEXTENCODING_MS_1252, false ); + MergeDataFile aMergeDataFile( sSDFFile, sHelpFile , FALSE, RTL_TEXTENCODING_MS_1252 ); + + //aMergeDataFile.Dump(); + std::vector<ByteString> aLanguages; + HelpParser::parse_languages( aLanguages , aMergeDataFile ); + + bool bCreateDir = true; + for( vector<ByteString>::iterator pos = filelist.begin() ; pos != filelist.end() ; ++pos ) + { + sHelpFile = *pos; + cout << ".";cout.flush(); + + HelpParser aParser( sHelpFile , bUTF8 , true ); + hasNoError = aParser.Merge( sSDFFile , sOutputFileX , sOutputFileY , true , aLanguages , aMergeDataFile , bCreateDir ); + bCreateDir = false; + } + } + } else + cerr << "helpex ERROR: Wrong input parameters!\n"; + + //Export::stopMessure( ByteString("full cycle") , startfull ); + if( hasNoError ) + return 0; + else + return 1; +} +#endif diff --git a/transex3/source/helpmerge.cxx b/transex3/source/helpmerge.cxx new file mode 100644 index 000000000000..8aafc692f14c --- /dev/null +++ b/transex3/source/helpmerge.cxx @@ -0,0 +1,730 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: helpmerge.cxx,v $ + * $Revision: 1.24 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <tools/fsys.hxx> +#include <osl/file.hxx> +// local includes +#include <stdio.h> +#include <stdlib.h> +#include "helpmerge.hxx" +#include "utf8conv.hxx" +#include <algorithm> +#include <sys/types.h> +#include <sys/stat.h> +#include <iostream> +#include <fstream> +#include <vector> +#include "rtl/strbuf.hxx" +#ifdef WNT +#include <direct.h> +//#include <WinBase.h> +#include "tools/prewin.h" +#include <windows.h> +#include "tools/postwin.h" +#endif + +/*****************************************************************************/ +void HelpParser::FillInFallbacks( LangHashMap& rElem_out, ByteString sLangIdx_in ){ +/*****************************************************************************/ + static const ByteString ENGLISH_LANGUAGECODE( "en-US" ); + static const ByteString GERMAN_LANGUAGECODE ( "de" ); + ByteString sCur; + XMLElement* pTmp = NULL; + XMLElement* pTmp2 = NULL; + + sCur = sLangIdx_in; + ByteString sFallback( sCur ); + GetIsoFallback( sFallback ); + if( (rElem_out.find( sFallback ) != rElem_out.end()) && rElem_out[ sFallback ] != NULL ){ + pTmp2 = rElem_out[ sFallback ]; + pTmp = new XMLElement( *pTmp2 ) ; // Copy + pTmp->SetPos( pTmp2->GetPos()+1 ); + pTmp->ChangeLanguageTag( String( sLangIdx_in , RTL_TEXTENCODING_ASCII_US) ); + rElem_out[ sLangIdx_in ] = pTmp; + pTmp2 = NULL; + } + else if( (rElem_out.find( ENGLISH_LANGUAGECODE ) != rElem_out.end()) && rElem_out[ ENGLISH_LANGUAGECODE ] != NULL ){// No English + pTmp2 = rElem_out[ ENGLISH_LANGUAGECODE ]; + pTmp = new XMLElement( *pTmp2 ) ; // Copy + pTmp->SetPos( pTmp2->GetPos()+1 ); + pTmp->ChangeLanguageTag( String( sLangIdx_in , RTL_TEXTENCODING_ASCII_US) ); + rElem_out[ sCur ] = pTmp; + pTmp2 = NULL; + } + else if( (rElem_out.find( GERMAN_LANGUAGECODE ) != rElem_out.end() ) && rElem_out[ GERMAN_LANGUAGECODE ] != NULL ){// No English + pTmp2 = rElem_out[ GERMAN_LANGUAGECODE ]; + pTmp = new XMLElement( *pTmp2 ); // Copy + pTmp->SetPos( pTmp2->GetPos()+1 ); + pTmp->ChangeLanguageTag( String( sLangIdx_in , RTL_TEXTENCODING_ASCII_US ) ); + rElem_out[ sCur ] = pTmp; + pTmp2 = NULL; + }else{ + fprintf(stdout,"ERROR: No Fallback found for language %s:\n",sCur.GetBuffer()); + rElem_out[ sCur ]=new XMLElement(); // Use dummy element + } +} + +/*****************************************************************************/ +void HelpParser::Dump(XMLHashMap* rElem_in) { +/*****************************************************************************/ + for(XMLHashMap::iterator pos = rElem_in->begin();pos != rElem_in->end(); ++pos){ + Dump(pos->second,pos->first); + } +} +/*****************************************************************************/ +void HelpParser::Dump(LangHashMap* rElem_in,const ByteString sKey_in) { +/*****************************************************************************/ + ByteString x; + OString y; + fprintf(stdout,"+------------%s-----------+\n",sKey_in.GetBuffer() ); + for(LangHashMap::iterator posn=rElem_in->begin();posn!=rElem_in->end();++posn){ + x=posn->first; + y=posn->second->ToOString(); + fprintf(stdout,"key=%s value=%s\n",x.GetBuffer(),y.getStr()); + } + fprintf(stdout,"+--------------------------+\n"); +} + +HelpParser::HelpParser( const ByteString &rHelpFile, bool rUTF8 , bool rHasInputList ) + : sHelpFile( rHelpFile ), + bUTF8 ( rUTF8 ), + bHasInputList( rHasInputList ) + {}; + +/*****************************************************************************/ +bool HelpParser::CreateSDF( +/*****************************************************************************/ + const ByteString &rSDFFile_in, const ByteString &rPrj_in,const ByteString &rRoot_in, + const ByteString &sHelpFile, XMLFile *pXmlFile, const ByteString &rGsi1){ + // GSI File constants + static const String GSI_SEQUENCE1( String::CreateFromAscii("\t0\t") ); + static const String GSI_SEQUENCE2( String::CreateFromAscii("\t\t\t0\t") ); + static const String GSI_TAB ( String::CreateFromAscii("\t") ); + static const String GSI_SEQUENCE4( String::CreateFromAscii("\t\t\t\t") ); + static const String ret ( String::CreateFromAscii("\n") ); + static const String ret_char ( String::CreateFromAscii("") ); + static const String tab ( String::CreateFromAscii("\t") ); + static const String tab_char ( String::CreateFromAscii("") ); + + SimpleXMLParser aParser; + String sUsedTempFile; + String sXmlFile; + + if( Export::fileHasUTF8ByteOrderMarker( sHelpFile ) ){ + DirEntry aTempFile = Export::GetTempFile(); + DirEntry aSourceFile( String( sHelpFile , RTL_TEXTENCODING_ASCII_US ) ); + aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE ); + String sTempFile = aTempFile.GetFull(); + Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) ); + sUsedTempFile = sTempFile; + sXmlFile = sTempFile; + }else{ + sUsedTempFile = String::CreateFromAscii(""); + sXmlFile = String( sHelpFile , RTL_TEXTENCODING_ASCII_US ); + } + +// ByteString fullFilePath; + //DirEntry aFile( sXmlFile ); + //makeAbsolutePath( sHelpFile , rRoot_in); + ByteString fullFilePath = rPrj_in; + fullFilePath.Append( "\\" ); + fullFilePath.Append( makeAbsolutePath( sHelpFile , rRoot_in ) ); + fullFilePath.SearchAndReplaceAll( "\\", "/" ); + + String strFullPath( fullFilePath.GetBuffer() , RTL_TEXTENCODING_ASCII_US ); + + //printf( "%s\n", fullFilePath.GetBuffer() ); + std::auto_ptr <XMLFile> file ( aParser.Execute( strFullPath , sXmlFile, pXmlFile ) ); + + if(file.get() == NULL){ + printf("%s\n",ByteString(aParser.GetError().sMessage,RTL_TEXTENCODING_ASCII_US).GetBuffer()); + exit(-1); + //return false; + } + file->Extract(); + if( !file->CheckExportStatus() ){ + return true; + } + SvFileStream aSDFStream( String( rSDFFile_in, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_WRITE | STREAM_TRUNC ); + + if ( !aSDFStream.IsOpen()) { + fprintf(stdout,"Can't open file %s\n",rSDFFile_in.GetBuffer()); + return false; + } + + ByteString sActFileName = makeAbsolutePath( sHelpFile , rRoot_in ); + +/* DirEntry aEntry( String( sHelpFile, RTL_TEXTENCODING_ASCII_US )); + aEntry.ToAbs(); + String sFullEntry = aEntry.GetFull(); + aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( rRoot_in ); + ByteString sPrjEntry( aEntry.GetFull(), gsl_getSystemTextEncoding()); + ByteString sActFileName( + sFullEntry.Copy( sPrjEntry.Len() + 1 ), gsl_getSystemTextEncoding()); + + sActFileName.SearchAndReplaceAll( "/", "\\" ); +*/ + XMLHashMap* aXMLStrHM = file->GetStrings(); + LangHashMap* pElem; + XMLElement* pXMLElement = NULL; + + //Dump(aXMLStrHM); + + ByteString sTimeStamp( Export::GetTimeStamp() ); + OUString sOUTimeStamp( sTimeStamp.GetBuffer() , sTimeStamp.Len() , RTL_TEXTENCODING_ASCII_US ); + + OUStringBuffer sBuffer; + const OUString sOUPrj( rPrj_in.GetBuffer() , rPrj_in.Len() , RTL_TEXTENCODING_ASCII_US ); + const OUString sOUActFileName(sActFileName.GetBuffer() , sActFileName.Len() , RTL_TEXTENCODING_ASCII_US ); + const OUString sOUGsi1( rGsi1.GetBuffer() , rGsi1.Len() , RTL_TEXTENCODING_ASCII_US ); + + Export::InitLanguages( false ); + std::vector<ByteString> aLanguages = Export::GetLanguages(); + + std::vector<ByteString> order = file->getOrder(); + std::vector<ByteString>::iterator pos; + XMLHashMap::iterator posm; + + for( pos = order.begin(); pos != order.end() ; ++pos ) + { + posm = aXMLStrHM->find( *pos ); + pElem = posm->second; + ByteString sCur; + + for( unsigned int n = 0; n < aLanguages.size(); n++ ) + { + sCur = aLanguages[ n ]; + if(pElem->find( sCur )==pElem->end()) + { + FillInFallbacks( *pElem , sCur ); + } + pXMLElement = (*pElem)[ sCur ]; + + if( pXMLElement != NULL ) + { + OUString data = pXMLElement->ToOUString(); + String sTmp = String(data.getStr()); + sTmp.SearchAndReplaceAll(ret,ret_char); // Remove \n + sTmp.SearchAndReplaceAll(tab,tab_char); // Remove \t + + data = OUString( sTmp ); + sBuffer.append( sOUPrj ); + sBuffer.append( GSI_TAB ); //"\t"; + if ( rRoot_in.Len()) + sBuffer.append( sOUActFileName ); + sBuffer.append( GSI_SEQUENCE1 ); //"\t0\t"; + sBuffer.append( sOUGsi1 ); //"help"; + sBuffer.append( GSI_TAB ); //"\t"; + ByteString sID = posm->first; // ID + sBuffer.append( OUString( sID.GetBuffer() , sID.Len() , RTL_TEXTENCODING_UTF8 ) ); + sBuffer.append( GSI_TAB ); //"\t"; + ByteString sOldRef = pXMLElement->GetOldref(); // oldref + sBuffer.append( OUString(sOldRef.GetBuffer() , sOldRef.Len() , RTL_TEXTENCODING_UTF8 ) ); + sBuffer.append( GSI_SEQUENCE2 ); //"\t\t\t0\t"; + sBuffer.append( OUString( sCur.GetBuffer() , sCur.Len() , RTL_TEXTENCODING_UTF8 ) ); + sBuffer.append( GSI_TAB ); //"\t"; + sBuffer.append( data ); + sBuffer.append( GSI_SEQUENCE4 ); //"\t\t\t\t"; + sBuffer.append( sOUTimeStamp ); + ByteString sOut( sBuffer.makeStringAndClear().getStr() , RTL_TEXTENCODING_UTF8 ); + //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( rPrj_in ) ) ) + //{ + if( data.getLength() > 0 ) aSDFStream.WriteLine( sOut ); + //} + pXMLElement=NULL; + }else fprintf(stdout,"\nDBG: NullPointer in HelpParser::CreateSDF , Language %s\n",sCur.GetBuffer() ); + } + + } + //Dump(aXMLStrHM); + aSDFStream.Close(); + + if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){ + DirEntry aTempFile( sUsedTempFile ); + aTempFile.Kill(); + } + return TRUE; +} + +ByteString HelpParser::makeAbsolutePath( const ByteString& sHelpFile , const ByteString& rRoot_in ) +{ + DirEntry aEntry( String( sHelpFile, RTL_TEXTENCODING_ASCII_US )); + aEntry.ToAbs(); + String sFullEntry = aEntry.GetFull(); + aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( rRoot_in ); + ByteString sPrjEntry( aEntry.GetFull(), gsl_getSystemTextEncoding()); + ByteString sActFileName( + sFullEntry.Copy( sPrjEntry.Len() + 1 ), gsl_getSystemTextEncoding()); + + sActFileName.SearchAndReplaceAll( "/", "\\" ); + return sActFileName; +} +bool HelpParser::Merge( const ByteString &rSDFFile, const ByteString &rDestinationFile , + ByteString& sLanguage , MergeDataFile& aMergeDataFile ) +{ + + (void) rSDFFile; + bool hasNoError = true; + + SimpleXMLParser aParser; + + String sUsedTempFile; + String sXmlFile; + + if( Export::fileHasUTF8ByteOrderMarker( sHelpFile ) ){ + DirEntry aTempFile = Export::GetTempFile(); + DirEntry aSourceFile( String( sHelpFile , RTL_TEXTENCODING_ASCII_US ) ); + aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE ); + String sTempFile = aTempFile.GetFull(); + Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) ); + sUsedTempFile = sTempFile; + sXmlFile = sTempFile; + }else{ + sUsedTempFile = String::CreateFromAscii(""); + sXmlFile = String( sHelpFile , RTL_TEXTENCODING_ASCII_US ); + } + + OUString sOUHelpFile( sXmlFile ); + String fullFilePath; + DirEntry aFile( sXmlFile ); + + XMLFile* xmlfile = ( aParser.Execute( aFile.GetFull() , sOUHelpFile, new XMLFile( '0' ) ) ); + printf("Dest file %s\n",rDestinationFile.GetBuffer()); + hasNoError = MergeSingleFile( xmlfile , aMergeDataFile , sLanguage , rDestinationFile ); + delete xmlfile; + if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){ + DirEntry aTempFile( sUsedTempFile ); + aTempFile.Kill(); + } + return hasNoError; +} + +bool ByteStringEqual( const ByteString& rKey1, const ByteString& rKey2 ) { + return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL; +}; +bool ByteStringLess( const ByteString& rKey1, const ByteString& rKey2 ) { + return rKey1.CompareTo( rKey2 )==COMPARE_LESS; +} + +void HelpParser::parse_languages( std::vector<ByteString>& aLanguages , MergeDataFile& aMergeDataFile ){ + std::vector<ByteString> aTmp; + + const ByteString DE ("de"); + const ByteString ENUS ("en-US"); + static const ByteString ALL( "ALL" ); + + Export::InitLanguages( false ); + + if( Export::sLanguages.EqualsIgnoreCaseAscii( ALL ) ) + { + aLanguages = aMergeDataFile.GetLanguages(); + aLanguages.push_back( DE ); + aLanguages.push_back( ENUS ); + + if( !Export::sForcedLanguages.Equals("") ) + { + std::vector<ByteString> aFL = Export::GetForcedLanguages(); + std::copy( aFL.begin() , + aFL.end() , + back_inserter( aLanguages ) + ); + std::sort( aLanguages.begin() , aLanguages.end() , ByteStringLess ); + std::vector<ByteString>::iterator unique_iter = std::unique( aLanguages.begin() , aLanguages.end() , ByteStringEqual ); + std::copy( aLanguages.begin() , unique_iter , back_inserter( aTmp ) ); + aLanguages = aTmp; + } + } + else{ + aLanguages = Export::GetLanguages(); + } + +} + +bool HelpParser::Merge( + const ByteString &rSDFFile, const ByteString &rPathX , const ByteString &rPathY , bool bISO , + const std::vector<ByteString>& aLanguages , MergeDataFile& aMergeDataFile , bool bCreateDir ) +{ + + + (void) rSDFFile ; + bool hasNoError = true; + SimpleXMLParser aParser; + String sUsedTempFile; + String sXmlFile; + + if( Export::fileHasUTF8ByteOrderMarker( sHelpFile ) ) + { + DirEntry aTempFile = Export::GetTempFile(); + DirEntry aSourceFile( String( sHelpFile , RTL_TEXTENCODING_ASCII_US ) ); + aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE ); + String sTempFile = aTempFile.GetFull(); + Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) ); + sUsedTempFile = sTempFile; + sXmlFile = sTempFile; + } + else + { + sUsedTempFile = String::CreateFromAscii(""); + sXmlFile = String( sHelpFile , RTL_TEXTENCODING_ASCII_US ); + } + + + OUString sOUHelpFile( sXmlFile ); + String fullFilePath; + DirEntry aFile( sXmlFile ); + + XMLFile* xmlfile = ( aParser.Execute( aFile.GetFull() , sOUHelpFile, new XMLFile( '0' ) ) ); + xmlfile->Extract(); + + if( xmlfile == NULL) + { + printf("%s\n",ByteString(aParser.GetError().sMessage,RTL_TEXTENCODING_UTF8).GetBuffer()); + exit(-1); + //return false; + } + + + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sFilepath; + if( bISO ) sFilepath = GetOutpath( rPathX , sCur , rPathY ); + else sFilepath = rPathX; + if( bCreateDir ) MakeDir( sFilepath ); + + XMLFile* file = new XMLFile( *xmlfile ); + sFilepath.Append( sHelpFile ); + hasNoError = MergeSingleFile( file , aMergeDataFile , sCur , sFilepath ); + delete file; + + if( !hasNoError ) return false; // Stop on error + } + + if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ) + { + DirEntry aTempFile( sUsedTempFile ); + aTempFile.Kill(); + } + delete xmlfile; + return hasNoError; +} + +bool HelpParser::MergeSingleFile( XMLFile* file , MergeDataFile& aMergeDataFile , const ByteString& sLanguage , + ByteString sPath ) +{ + file->Extract(); + + XMLHashMap* aXMLStrHM = file->GetStrings(); + LangHashMap* aLangHM; + static ResData pResData( "","",""); + pResData.sResTyp = "help"; + + ByteString sTmp = Export::sLanguages; + + sTmp.EraseLeadingAndTrailingChars(); + + for(XMLHashMap::iterator pos=aXMLStrHM->begin();pos!=aXMLStrHM->end();++pos) // Merge every l10n related string + { + + aLangHM = pos->second; + //printf("*********************DUMPING HASHMAP***************************************"); + //Dump( aXMLStrHM ); + //printf("DBG: sHelpFile = %s\n",sHelpFile.GetBuffer() ); + + pResData.sGId = pos->first; + pResData.sFilename = sHelpFile; + + ProcessHelp( aLangHM , sLanguage, &pResData , aMergeDataFile ); + } + + + // Init temp and target file + ByteString sTempFile; + ByteString sTargetFile( sPath ); + ByteString sTempFileCopy; + + static const ByteString INPATH = Export::GetEnv( "INPATH" ); + Export::getRandomName( sPath , sTempFile , INPATH ); + Export::getRandomName( sPath , sTempFileCopy , INPATH ); + // Write in the temp file + bool hasNoError = file->Write ( sTempFile ); + if( !hasNoError ) + { + cerr << "ERROR: file->Write failed\n"; + return false; + } + + DirEntry aTmp( sTempFile ); + DirEntry aTmp2( sTempFileCopy ); + DirEntry aTar( sTargetFile ); + + if( !Export::CopyFile( sTempFile , sTempFileCopy ) ) + { +#if defined(UNX) || defined(OS2) + sleep( 3 ); +#else + Sleep( 3 ); +#endif + if( !Export::CopyFile( sTempFile , sTempFileCopy ) ) + { + cerr << "ERROR: Can not copy file from " << sTempFile.GetBuffer() << " to " << sTempFileCopy.GetBuffer() << "\n"; + return false; + } + } + //remove( sTargetFile.GetBuffer() ); + + FileStat aFSTest( aTar ); + if( aFSTest.GetSize() < 1 ) + { + remove( sTargetFile.GetBuffer() ); + } + int rc; +#if defined(UNX) || defined(OS2) + rc = rename( sTempFile.GetBuffer() , sTargetFile.GetBuffer() ); +#else + rc = MoveFileEx( sTempFile.GetBuffer() , sTargetFile.GetBuffer(), MOVEFILE_REPLACE_EXISTING ); +#endif + FileStat aFS( aTar ); + + //cout << "mv " << sTempFile.GetBuffer() << " " << sTargetFile.GetBuffer() << "\n"; + //cout << "rc -> " << rc << " filesize -> " << aFS.GetSize() << "\n"; +// Windows rename returns -1 if the file already exits +//#ifdef UNX + if( rc < 0 || aFS.GetSize() < 1 ) +//#else +// if( aFS.GetSize() < 1 ) +//#endif + { +#if defined(UNX) || defined(OS2) + sleep( 3 ); +#else + Sleep( 3 ); +#endif + aFSTest.Update( aTar ); + if( aFSTest.GetSize() < 1 ) + { + remove( sTargetFile.GetBuffer() ); + } +#if defined(UNX) || defined(OS2) + rc = rename( sTempFileCopy.GetBuffer() , sTargetFile.GetBuffer() ); +#else + rc = MoveFileEx( sTempFileCopy.GetBuffer() , sTargetFile.GetBuffer() , MOVEFILE_REPLACE_EXISTING ); +#endif + aFS.Update( aTar ); + + //cout << "mv2 " << sTempFileCopy.GetBuffer() << " " << sTargetFile.GetBuffer() << "\n"; + //cout << "rc -> " << rc << " filesize -> " << aFS.GetSize() << "\n"; + +// Windows rename returns -1 if the file already exits +//#ifdef WNT +// if( aFS.GetSize() < 1 ) +//#else + if( rc < 0 || aFS.GetSize() < 1 ) +//#endif + { + cerr << "ERROR: helpex Can't rename file " << sTempFileCopy.GetBuffer() << " to " << sTargetFile.GetBuffer() << " rename rc=" << rc << " filesize=" << aFS.GetSize() << "\n"; + aTmp.Kill(); + aTmp2.Kill(); + if( aFS.GetSize() < 1 ) + aTar.Kill(); + return false; + } + } + aTmp.Kill(); + aTmp2.Kill(); + + return true; +} + +ByteString HelpParser::GetOutpath( const ByteString& rPathX , const ByteString& sCur , const ByteString& rPathY ){ + ByteString testpath = rPathX; + static const ByteString sDelimiter( DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US ); + testpath.EraseTrailingChars( '/' ); + testpath.EraseTrailingChars( '\\' ); + testpath += sDelimiter; + testpath += sCur; + testpath += sDelimiter; + ByteString sRelativePath( rPathY ); + sRelativePath.EraseLeadingChars( '/' ); + sRelativePath.EraseLeadingChars( '\\' ); + testpath += sRelativePath; + testpath += sDelimiter; + return testpath; +} +void HelpParser::MakeDir( const ByteString& sPath ){ + ByteString sTPath( sPath ); + ByteString sDelimiter( DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US ); + sTPath.SearchAndReplaceAll( sDelimiter , '/' ); + USHORT cnt = sTPath.GetTokenCount( '/' ); + ByteString sCreateDir; + for( USHORT i = 0 ; i < cnt ; i++ ) + { + sCreateDir += sTPath.GetToken( i , '/' ); + sCreateDir += sDelimiter; +#ifdef WNT + _mkdir( sCreateDir.GetBuffer() ); +#else + mkdir( sCreateDir.GetBuffer() , S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ); +#endif + } +} + + +/* ProcessHelp Methode: search for en-US entry and replace it with the current language*/ +void HelpParser::ProcessHelp( LangHashMap* aLangHM , const ByteString& sCur , ResData *pResData , MergeDataFile& aMergeDataFile ){ + + XMLElement* pXMLElement = NULL; + PFormEntrys *pEntrys = NULL; + XMLData *data = NULL; + XMLParentNode *parent = NULL; + + String sNewdata; + ByteString sLId; + ByteString sGId; + + pEntrys = NULL; + +#ifdef MERGE_SOURCE_LANGUAGES + if( true ){ // Merge en-US! +#else + if( !sCur.EqualsIgnoreCaseAscii("en-US") ){ +#endif + pXMLElement = (*aLangHM)[ "en-US" ]; + if( pXMLElement == NULL ) + { + printf("Error: Can't find en-US entry\n"); + } + if( pXMLElement != NULL ) + { + parent = pXMLElement->GetParent(); + sLId = pXMLElement->GetOldref(); + pResData->sId = sLId; + + pEntrys = aMergeDataFile.GetPFormEntrys( pResData ); + if( pEntrys != NULL) + { + ByteString sNewText; + pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur , true ); + sNewdata = String( sNewText , RTL_TEXTENCODING_UTF8 ); + if ( sNewdata.Len()) + { + if( pXMLElement != NULL ) + { + data = new XMLData( sNewdata , NULL , true ); // Add new one + pXMLElement->RemoveAndDeleteAllChilds(); + pXMLElement->AddChild( data ); + aLangHM->erase( sCur ); + } + } + }else if( pResData == NULL ){fprintf(stdout,"Can't find GID=%s LID=%s TYP=%s\n",pResData->sGId.GetBuffer(),pResData->sId.GetBuffer(),pResData->sResTyp.GetBuffer());} + pXMLElement->ChangeLanguageTag( String( sCur , RTL_TEXTENCODING_ASCII_US) ); + } + + } +} +/* Process() Method merges */ +void HelpParser::Process( LangHashMap* aLangHM , const ByteString& sCur , ResData *pResData , MergeDataFile& aMergeDataFile ){ + + XMLElement* pXMLElement = NULL; + PFormEntrys *pEntrys = NULL; + XMLData *data = NULL; + XMLParentNode *parent = NULL; + XMLDefault *xmldefault = NULL; + + short curLang = 0; + String sNewdata; + bool isFallback = false; + ByteString sLId; + ByteString sGId; + + pEntrys = NULL; + +#ifdef MERGE_SOURCE_LANGUAGES + if( true ){ // Merge en-US! +#else + if( !sCur.EqualsIgnoreCaseAscii("en-US") ){ +#endif + pXMLElement = (*aLangHM)[ sCur ]; + if( pXMLElement == NULL ) + { + FillInFallbacks( *aLangHM , sCur ); + pXMLElement = ( *aLangHM )[ sCur ]; + isFallback = true; + } + if( pXMLElement != NULL ) + { + parent = pXMLElement->GetParent(); + sLId = pXMLElement->GetOldref(); + pResData->sId = sLId; + + pEntrys = aMergeDataFile.GetPFormEntrys( pResData ); + if( pEntrys != NULL) + { + ByteString sNewText; + pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur , true ); + sNewdata = String( sNewText , RTL_TEXTENCODING_UTF8 ); + if ( sNewdata.Len()) + { + printf("Entries found\n"); + if( pXMLElement != NULL ) + { + data = new XMLData( sNewdata , NULL , true ); // Add new one + if( pXMLElement->ToOUString().compareTo( OUString(data->GetData()) ) != 0 ) + { + pXMLElement->RemoveAndDeleteAllChilds(); + pXMLElement->AddChild( data ); + } + if( isFallback ) + { + xmldefault = new XMLDefault( String::CreateFromAscii("\n") , NULL ); + int pos = parent->GetPosition( pXMLElement->GetId() ); + if( pos != -1 ){ + parent->AddChild(xmldefault , pos+1 ); + parent->AddChild(pXMLElement , pos+2 ); + } + else fprintf(stdout,"ERROR: Can't find reference Element of id %s language %d\n",pXMLElement->GetId().GetBuffer(),curLang); + } + + aLangHM->erase( sCur ); + } + } + delete pResData; + }else if( pResData == NULL ){fprintf(stdout,"Can't find GID=%s LID=%s TYP=%s\n",pResData->sGId.GetBuffer(),pResData->sId.GetBuffer(),pResData->sResTyp.GetBuffer());} + } + + } +} + diff --git a/transex3/source/hw2fw.cxx b/transex3/source/hw2fw.cxx new file mode 100644 index 000000000000..dd77b8d9210c --- /dev/null +++ b/transex3/source/hw2fw.cxx @@ -0,0 +1,202 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: hw2fw.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <tools/string.hxx> + +struct hw_pair +{ + sal_Unicode nFrom; + sal_Unicode nTo; +}; + +#define MAKE_PAIR(a,b) { a, b } + +static struct hw_pair aHWPairs[] = +{ + MAKE_PAIR( 0xFF65, 0x30FB ), // HALFWIDTH KATAKANA MIDDLE DOT --> KATAKANA MIDDLE DOT + MAKE_PAIR( 0xFF66, 0x30F2 ), // HALFWIDTH KATAKANA LETTER WO --> KATAKANA LETTER WO + MAKE_PAIR( 0xFF67, 0x30A1 ), // HALFWIDTH KATAKANA LETTER SMALL A --> KATAKANA LETTER SMALL A + MAKE_PAIR( 0xFF68, 0x30A3 ), // HALFWIDTH KATAKANA LETTER SMALL I --> KATAKANA LETTER SMALL I + MAKE_PAIR( 0xFF69, 0x30A5 ), // HALFWIDTH KATAKANA LETTER SMALL U --> KATAKANA LETTER SMALL U + MAKE_PAIR( 0xFF6A, 0x30A7 ), // HALFWIDTH KATAKANA LETTER SMALL E --> KATAKANA LETTER SMALL E + MAKE_PAIR( 0xFF6B, 0x30A9 ), // HALFWIDTH KATAKANA LETTER SMALL O --> KATAKANA LETTER SMALL O + MAKE_PAIR( 0xFF6C, 0x30E3 ), // HALFWIDTH KATAKANA LETTER SMALL YA --> KATAKANA LETTER SMALL YA + MAKE_PAIR( 0xFF6D, 0x30E5 ), // HALFWIDTH KATAKANA LETTER SMALL YU --> KATAKANA LETTER SMALL YU + MAKE_PAIR( 0xFF6E, 0x30E7 ), // HALFWIDTH KATAKANA LETTER SMALL YO --> KATAKANA LETTER SMALL YO + MAKE_PAIR( 0xFF6F, 0x30C3 ), // HALFWIDTH KATAKANA LETTER SMALL TU --> KATAKANA LETTER SMALL TU + MAKE_PAIR( 0xFF70, 0x30FC ), // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK --> KATAKANA-HIRAGANA PROLONGED SOUND MARK + MAKE_PAIR( 0xFF71, 0x30A2 ), // HALFWIDTH KATAKANA LETTER A --> KATAKANA LETTER A + MAKE_PAIR( 0xFF72, 0x30A4 ), // HALFWIDTH KATAKANA LETTER I --> KATAKANA LETTER I + MAKE_PAIR( 0xFF73, 0x30A6 ), // HALFWIDTH KATAKANA LETTER U --> KATAKANA LETTER U + MAKE_PAIR( 0xFF74, 0x30A8 ), // HALFWIDTH KATAKANA LETTER E --> KATAKANA LETTER E + MAKE_PAIR( 0xFF75, 0x30AA ), // HALFWIDTH KATAKANA LETTER O --> KATAKANA LETTER O + MAKE_PAIR( 0xFF76, 0x30AB ), // HALFWIDTH KATAKANA LETTER KA --> KATAKANA LETTER KA + MAKE_PAIR( 0xFF77, 0x30AD ), // HALFWIDTH KATAKANA LETTER KI --> KATAKANA LETTER KI + MAKE_PAIR( 0xFF78, 0x30AF ), // HALFWIDTH KATAKANA LETTER KU --> KATAKANA LETTER KU + MAKE_PAIR( 0xFF79, 0x30B1 ), // HALFWIDTH KATAKANA LETTER KE --> KATAKANA LETTER KE + MAKE_PAIR( 0xFF7A, 0x30B3 ), // HALFWIDTH KATAKANA LETTER KO --> KATAKANA LETTER KO + MAKE_PAIR( 0xFF7B, 0x30B5 ), // HALFWIDTH KATAKANA LETTER SA --> KATAKANA LETTER SA + MAKE_PAIR( 0xFF7C, 0x30B7 ), // HALFWIDTH KATAKANA LETTER SI --> KATAKANA LETTER SI + MAKE_PAIR( 0xFF7D, 0x30B9 ), // HALFWIDTH KATAKANA LETTER SU --> KATAKANA LETTER SU + MAKE_PAIR( 0xFF7E, 0x30BB ), // HALFWIDTH KATAKANA LETTER SE --> KATAKANA LETTER SE + MAKE_PAIR( 0xFF7F, 0x30BD ), // HALFWIDTH KATAKANA LETTER SO --> KATAKANA LETTER SO + MAKE_PAIR( 0xFF80, 0x30BF ), // HALFWIDTH KATAKANA LETTER TA --> KATAKANA LETTER TA + MAKE_PAIR( 0xFF81, 0x30C1 ), // HALFWIDTH KATAKANA LETTER TI --> KATAKANA LETTER TI + MAKE_PAIR( 0xFF82, 0x30C4 ), // HALFWIDTH KATAKANA LETTER TU --> KATAKANA LETTER TU + MAKE_PAIR( 0xFF83, 0x30C6 ), // HALFWIDTH KATAKANA LETTER TE --> KATAKANA LETTER TE + MAKE_PAIR( 0xFF84, 0x30C8 ), // HALFWIDTH KATAKANA LETTER TO --> KATAKANA LETTER TO + MAKE_PAIR( 0xFF85, 0x30CA ), // HALFWIDTH KATAKANA LETTER NA --> KATAKANA LETTER NA + MAKE_PAIR( 0xFF86, 0x30CB ), // HALFWIDTH KATAKANA LETTER NI --> KATAKANA LETTER NI + MAKE_PAIR( 0xFF87, 0x30CC ), // HALFWIDTH KATAKANA LETTER NU --> KATAKANA LETTER NU + MAKE_PAIR( 0xFF88, 0x30CD ), // HALFWIDTH KATAKANA LETTER NE --> KATAKANA LETTER NE + MAKE_PAIR( 0xFF89, 0x30CE ), // HALFWIDTH KATAKANA LETTER NO --> KATAKANA LETTER NO + MAKE_PAIR( 0xFF8A, 0x30CF ), // HALFWIDTH KATAKANA LETTER HA --> KATAKANA LETTER HA + MAKE_PAIR( 0xFF8B, 0x30D2 ), // HALFWIDTH KATAKANA LETTER HI --> KATAKANA LETTER HI + MAKE_PAIR( 0xFF8C, 0x30D5 ), // HALFWIDTH KATAKANA LETTER HU --> KATAKANA LETTER HU + MAKE_PAIR( 0xFF8D, 0x30D8 ), // HALFWIDTH KATAKANA LETTER HE --> KATAKANA LETTER HE + MAKE_PAIR( 0xFF8E, 0x30DB ), // HALFWIDTH KATAKANA LETTER HO --> KATAKANA LETTER HO + MAKE_PAIR( 0xFF8F, 0x30DE ), // HALFWIDTH KATAKANA LETTER MA --> KATAKANA LETTER MA + MAKE_PAIR( 0xFF90, 0x30DF ), // HALFWIDTH KATAKANA LETTER MI --> KATAKANA LETTER MI + MAKE_PAIR( 0xFF91, 0x30E0 ), // HALFWIDTH KATAKANA LETTER MU --> KATAKANA LETTER MU + MAKE_PAIR( 0xFF92, 0x30E1 ), // HALFWIDTH KATAKANA LETTER ME --> KATAKANA LETTER ME + MAKE_PAIR( 0xFF93, 0x30E2 ), // HALFWIDTH KATAKANA LETTER MO --> KATAKANA LETTER MO + MAKE_PAIR( 0xFF94, 0x30E4 ), // HALFWIDTH KATAKANA LETTER YA --> KATAKANA LETTER YA + MAKE_PAIR( 0xFF95, 0x30E6 ), // HALFWIDTH KATAKANA LETTER YU --> KATAKANA LETTER YU + MAKE_PAIR( 0xFF96, 0x30E8 ), // HALFWIDTH KATAKANA LETTER YO --> KATAKANA LETTER YO + MAKE_PAIR( 0xFF97, 0x30E9 ), // HALFWIDTH KATAKANA LETTER RA --> KATAKANA LETTER RA + MAKE_PAIR( 0xFF98, 0x30EA ), // HALFWIDTH KATAKANA LETTER RI --> KATAKANA LETTER RI + MAKE_PAIR( 0xFF99, 0x30EB ), // HALFWIDTH KATAKANA LETTER RU --> KATAKANA LETTER RU + MAKE_PAIR( 0xFF9A, 0x30EC ), // HALFWIDTH KATAKANA LETTER RE --> KATAKANA LETTER RE + MAKE_PAIR( 0xFF9B, 0x30ED ), // HALFWIDTH KATAKANA LETTER RO --> KATAKANA LETTER RO + MAKE_PAIR( 0xFF9C, 0x30EF ), // HALFWIDTH KATAKANA LETTER WA --> KATAKANA LETTER WA + MAKE_PAIR( 0xFF9D, 0x30F3 ), // HALFWIDTH KATAKANA LETTER N --> KATAKANA LETTER N + MAKE_PAIR( 0xFF9E, 0x3099 ), // HALFWIDTH KATAKANA VOICED SOUND MARK --> COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK + MAKE_PAIR( 0xFF9F, 0x309A ) // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK --> COMBINING KATAKANA- +}; + + +static struct hw_pair aCombine3099[] = +{ + { 0x30a6, 0x30f4 }, + { 0x30ab, 0x30ac }, + { 0x30ad, 0x30ae }, + { 0x30af, 0x30b0 }, + { 0x30b1, 0x30b2 }, + { 0x30b3, 0x30b4 }, + { 0x30b5, 0x30b6 }, + { 0x30b7, 0x30b8 }, + { 0x30b9, 0x30ba }, + { 0x30bb, 0x30bc }, + { 0x30bd, 0x30be }, + { 0x30bf, 0x30c0 }, + { 0x30c1, 0x30c2 }, + { 0x30c4, 0x30c5 }, + { 0x30c6, 0x30c7 }, + { 0x30c8, 0x30c9 }, + { 0x30cf, 0x30d0 }, + { 0x30d2, 0x30d3 }, + { 0x30d5, 0x30d6 }, + { 0x30d8, 0x30d9 }, + { 0x30db, 0x30dc }, + { 0x30ef, 0x30f7 }, + { 0x30f0, 0x30f8 }, + { 0x30f1, 0x30f9 }, + { 0x30f2, 0x30fa }, + { 0x30fd, 0x30fe } +}; + +static struct hw_pair aCombine309A[] = +{ + { 0x30cf, 0x30d1 }, + { 0x30d2, 0x30d4 }, + { 0x30d5, 0x30d7 }, + { 0x30d8, 0x30da }, + { 0x30db, 0x30dd } +}; + +USHORT ImplReplaceFullWidth( sal_Unicode* pString, USHORT nLen ) +{ + sal_Unicode* pRead = pString; + sal_Unicode* pWrite = pRead; + USHORT nNewLen = nLen; + + while( (pRead - pString) < nLen ) + { + if( pWrite != pRead ) + *pWrite = *pRead; + + if( *pRead >= 0xff65 && *pRead <= 0xff9f ) + { + *pWrite = aHWPairs[ *pRead - 0xff65 ].nTo; + + struct hw_pair* pTable = NULL; + int nTableEntries = 0; + if( *pWrite == 0x3099 ) + { + // replace 0x3099 combinations + pTable = aCombine3099; + nTableEntries = sizeof(aCombine3099)/sizeof(aCombine3099[0]); + } + else if( *pWrite == 0x309a ) + { + // replace 0x309a combinations + pTable = aCombine309A; + nTableEntries = sizeof(aCombine309A)/sizeof(aCombine309A[0]); + } + if( pTable ) + { + sal_Unicode c = pWrite[-1]; + for( int i = 0; i < nTableEntries; i++ ) + if( c == pTable[i].nFrom ) + { + pWrite--; + *pWrite = pTable[i].nTo; + nNewLen--; + break; + } + } + } + pRead++; + pWrite++; + } + if( pWrite < pRead ) + *pWrite = 0; + + return nNewLen; +} + +void ConvertHalfwitdhToFullwidth( String& rString ) +{ + USHORT nNewLen = ImplReplaceFullWidth( rString.GetBufferAccess(), rString.Len() ); + rString.ReleaseBufferAccess( nNewLen ); +} diff --git a/transex3/source/lngex.cxx b/transex3/source/lngex.cxx new file mode 100644 index 000000000000..53c97de6e045 --- /dev/null +++ b/transex3/source/lngex.cxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lngex.cxx,v $ + * $Revision: 1.18 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> + +// local includes +#include "lngmerge.hxx" + +// defines to parse command line +#define STATE_NON 0x0001 +#define STATE_INPUT 0x0002 +#define STATE_OUTPUT 0x0003 +#define STATE_PRJ 0x0004 +#define STATE_ROOT 0x0005 +#define STATE_MERGESRC 0x0006 +#define STATE_ERRORLOG 0x0007 +#define STATE_BREAKHELP 0x0008 +#define STATE_UNMERGE 0x0009 +#define STATE_UTF8 0x000A +#define STATE_ULF 0x000B +#define STATE_LANGUAGES 0x000C + +// set of global variables +ByteString sInputFile; +BOOL bEnableExport; +BOOL bMergeMode; +BOOL bErrorLog; +BOOL bUTF8; +BOOL bULF; // ULF = Unicode Language File +bool bQuiet; +ByteString sPrj; +ByteString sPrjRoot; +ByteString sOutputFile; +ByteString sMergeSrc; + +/*****************************************************************************/ +BOOL ParseCommandLine( int argc, char* argv[]) +/*****************************************************************************/ +{ + bEnableExport = FALSE; + bMergeMode = FALSE; + bErrorLog = TRUE; + bUTF8 = TRUE; + bULF = FALSE; + bQuiet = false; + sPrj = ""; + sPrjRoot = ""; + Export::sLanguages = ""; + + USHORT nState = STATE_NON; + BOOL bInput = FALSE; + + // parse command line + for( int i = 1; i < argc; i++ ) { + ByteString sSwitch( argv[ i ] ); + sSwitch.ToUpperAscii(); + if ( sSwitch == "-I" ) { + nState = STATE_INPUT; // next tokens specifies source files + } + else if ( sSwitch == "-O" ) { + nState = STATE_OUTPUT; // next token specifies the dest file + } + else if ( sSwitch == "-P" ) { + nState = STATE_PRJ; // next token specifies the cur. project + } + else if ( sSwitch == "-R" ) { + nState = STATE_ROOT; // next token specifies path to project root + } + else if ( sSwitch == "-QQ" ) { + bQuiet = true; + } + else if ( sSwitch == "-M" ) { + nState = STATE_MERGESRC; // next token specifies the merge database + } + else if ( sSwitch == "-E" ) { + nState = STATE_ERRORLOG; + bErrorLog = FALSE; + } + else if ( sSwitch == "-UTF8" ) { + nState = STATE_UTF8; + bUTF8 = TRUE; + } +/* else if ( sSwitch == "-NOUTF8" ) { + nState = STATE_UTF8; + bUTF8 = FALSE; + }*/ +/* else if ( sSwitch == "-ULF" ) { + nState = STATE_ULF; + bULF = TRUE; + }*/ + else if ( sSwitch == "-L" ) { + nState = STATE_LANGUAGES; + } + else { + switch ( nState ) { + case STATE_NON: { + return FALSE; // no valid command line + } + //break; + case STATE_INPUT: { + sInputFile = argv[ i ]; + bInput = TRUE; // source file found + } + break; + case STATE_OUTPUT: { + sOutputFile = argv[ i ]; // the dest. file + } + break; + case STATE_PRJ: { + sPrj = argv[ i ]; +// sPrj.ToLowerAscii(); // the project + } + break; + case STATE_ROOT: { + sPrjRoot = argv[ i ]; // path to project root + } + break; + case STATE_MERGESRC: { + sMergeSrc = argv[ i ]; + bMergeMode = TRUE; // activate merge mode, cause merge database found + } + break; + case STATE_LANGUAGES: { + Export::sLanguages = argv[ i ]; + } + break; + } + } + } + + if ( bInput ) { + // command line is valid + bULF = TRUE; + bEnableExport = TRUE; + return TRUE; + } + + // command line is not valid + return FALSE; +} + + +/*****************************************************************************/ +void Help() +/*****************************************************************************/ +{ + //fprintf( stdout, "Syntax:ULFEX[-p Prj][-r PrjRoot]-i FileIn -o FileOut[-m DataBase][-e][-b][-u][-NOUTF8][-ULF][-L l1,l2,...]\n" ); + fprintf( stdout, "Syntax:ULFEX[-p Prj][-r PrjRoot]-i FileIn -o FileOut[-m DataBase][-L l1,l2,...]\n" ); + fprintf( stdout, " Prj: Project\n" ); + fprintf( stdout, " PrjRoot: Path to project root (..\\.. etc.)\n" ); + fprintf( stdout, " FileIn: Source file (*.lng)\n" ); + fprintf( stdout, " FileOut: Destination file (*.*)\n" ); + fprintf( stdout, " DataBase: Mergedata (*.sdf)\n" ); + fprintf( stdout, " -QQ: quite output\n" ); + //fprintf( stdout, " -NOUTF8: disable UTF8 as language independent encoding\n" ); + //fprintf( stdout, " -ULF: enables Unicode Language File format, leads to UTF8 encoded version of lng files" ); + fprintf( stdout, " -L: Restrict the handled languages. l1,l2,... are elements of (de,en-US...)\n" ); + fprintf( stdout, " A fallback language can be defined like this: l1=f1.\n" ); + fprintf( stdout, " f1, f2,... are also elements of (de,en-US...)\n" ); + fprintf( stdout, " Example: -L de,es=en-US\n" ); + fprintf( stdout, " Restriction to de and es, en-US will be fallback for es\n" ); +} + +/*****************************************************************************/ +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + if ( !ParseCommandLine( argc, argv )) { + Help(); + return 1; + } + if( !bQuiet ){ + fprintf( stdout, "\nUlfEx 1 Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.\n" ); + fprintf( stdout, "====================================================================\n" ); + fprintf( stdout, "\nProcessing File %s ...\n", sInputFile.GetBuffer()); + }else + { + fprintf(stdout, "."); + fflush( stdout ); + } + + if ( sOutputFile.Len()) { + LngParser aParser( sInputFile, bUTF8, bULF , bQuiet ); + if ( bMergeMode ) + aParser.Merge( sMergeSrc, sOutputFile , sPrj ); + else + aParser.CreateSDF( sOutputFile, sPrj, sPrjRoot ); + } + + if( !bQuiet ) fprintf( stdout, "\n=================================================\n\n" ); + + return 0; +} diff --git a/transex3/source/lngmerge.cxx b/transex3/source/lngmerge.cxx new file mode 100644 index 000000000000..e55fdc83ce37 --- /dev/null +++ b/transex3/source/lngmerge.cxx @@ -0,0 +1,360 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lngmerge.cxx,v $ + * $Revision: 1.29 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <tools/fsys.hxx> + +// local includes +#include "lngmerge.hxx" +#include "utf8conv.hxx" +#include <iostream> +using namespace std; +// +// class LngParser +// +/*****************************************************************************/ +LngParser::LngParser( const ByteString &rLngFile, BOOL bUTF8, BOOL bULFFormat , bool bQuiet_in ) +/*****************************************************************************/ + : + nError( LNG_OK ), + pLines( NULL ), + sSource( rLngFile ), + bDBIsUTF8( bUTF8 ), + bULF( bULFFormat ), + bQuiet( bQuiet_in ) +{ + pLines = new LngLineList( 100, 100 ); + DirEntry aEntry( String( sSource, RTL_TEXTENCODING_ASCII_US )); + if ( aEntry.Exists()) { + SvFileStream aStream( String( sSource, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); + if ( aStream.IsOpen()) { + ByteString sLine; + bool bFirstLine = true; + while ( !aStream.IsEof()) { + aStream.ReadLine( sLine ); + + if( bFirstLine ){ // Always remove UTF8 BOM from the first line + Export::RemoveUTF8ByteOrderMarker( sLine ); + bFirstLine = false; + } + + pLines->Insert( new ByteString( sLine ), LIST_APPEND ); + } + } + else + nError = LNG_COULD_NOT_OPEN; + } + else + nError = LNG_FILE_NOTFOUND; +} + +/*****************************************************************************/ +LngParser::~LngParser() +/*****************************************************************************/ +{ + for ( ULONG i = 0; i < pLines->Count(); i++ ) + delete pLines->GetObject( i ); + delete pLines; +} + +/*****************************************************************************/ +void LngParser::FillInFallbacks( ByteStringHashMap Text ) +/*****************************************************************************/ +{ + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + if( Export::isAllowed( sCur ) ){ + ByteString sFallbackLang = Export::GetFallbackLanguage( sCur ); + if( sFallbackLang.Len() ){ + Text[ sCur ] = Text[ sFallbackLang ]; + } + } + } +} + +/*****************************************************************************/ +BOOL LngParser::CreateSDF( + const ByteString &rSDFFile, const ByteString &rPrj, + const ByteString &rRoot ) +/*****************************************************************************/ +{ + + Export::InitLanguages( false ); + aLanguages = Export::GetLanguages(); + SvFileStream aSDFStream( String( rSDFFile, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_WRITE | STREAM_TRUNC ); + if ( !aSDFStream.IsOpen()) { + nError = SDF_COULD_NOT_OPEN; + } + aSDFStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); + nError = SDF_OK; + DirEntry aEntry( String( sSource, RTL_TEXTENCODING_ASCII_US )); + aEntry.ToAbs(); + String sFullEntry = aEntry.GetFull(); + aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( rRoot ); + ByteString sPrjEntry( aEntry.GetFull(), gsl_getSystemTextEncoding()); + ByteString sActFileName( + sFullEntry.Copy( sPrjEntry.Len() + 1 ), gsl_getSystemTextEncoding()); + sActFileName.SearchAndReplaceAll( "/", "\\" ); + + ULONG nPos = 0; + BOOL bStart = true; + ByteString sGroup; + ByteStringHashMap Text; + ByteString sID; + ByteString sLine; + + while( nPos < pLines->Count() ){ + sLine = *pLines->GetObject( nPos++ ); + while( nPos < pLines->Count() && !isNextGroup( sGroup , sLine ) ){ + ReadLine( sLine , Text ); + sID = sGroup; + sLine = *pLines->GetObject( nPos++ ); + }; + if( bStart ){ + bStart = false; + sID = sGroup; + } + else { + + WriteSDF( aSDFStream , Text , rPrj , rRoot , sActFileName , sID ); + } + } + aSDFStream.Close(); + return true; +} + + void LngParser::WriteSDF( SvFileStream &aSDFStream , ByteStringHashMap &rText_inout , + const ByteString &rPrj , const ByteString &rRoot , + const ByteString &sActFileName , const ByteString &sID ) + { + + BOOL bExport = true; + if ( bExport ) { + ByteString sTimeStamp( Export::GetTimeStamp()); + ByteString sCur; + FillInFallbacks( rText_inout ); + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + ByteString sAct = rText_inout[ sCur ]; + if ( !sAct.Len() && sCur.Len() ) + sAct = rText_inout[ ByteString("en-US") ]; + + ByteString sOutput( rPrj ); sOutput += "\t"; + if ( rRoot.Len()) + sOutput += sActFileName; + sOutput += "\t0\t"; + sOutput += "LngText\t"; + sOutput += sID; sOutput += "\t\t\t\t0\t"; + sOutput += sCur; sOutput += "\t"; + sOutput += sAct; sOutput += "\t\t\t\t"; + sOutput += sTimeStamp; + //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( rPrj ) ) ) + aSDFStream.WriteLine( sOutput ); + } + } + } + bool LngParser::isNextGroup( ByteString &sGroup_out , ByteString &sLine_in ){ + sLine_in.EraseLeadingChars( ' ' ); + sLine_in.EraseTrailingChars( ' ' ); + if (( sLine_in.GetChar( 0 ) == '[' ) && + ( sLine_in.GetChar( sLine_in.Len() - 1 ) == ']' )){ + sGroup_out = sLine_in.GetToken( 1, '[' ).GetToken( 0, ']' ); + sGroup_out.EraseLeadingChars( ' ' ); + sGroup_out.EraseTrailingChars( ' ' ); + return true; + } + return false; + } + void LngParser::ReadLine( const ByteString &sLine_in , ByteStringHashMap &rText_inout){ + //printf("sLine -> '%s'\n",sLine_in.GetBuffer()); + ByteString sLang = sLine_in.GetToken( 0, '=' ); + sLang.EraseLeadingChars( ' ' ); + sLang.EraseTrailingChars( ' ' ); + ByteString sText = sLine_in.GetToken( 1, '\"' ).GetToken( 0, '\"' ); + if( sLang.Len() ) + rText_inout[ sLang ] = sText; + } + +/*****************************************************************************/ +BOOL LngParser::Merge( + const ByteString &rSDFFile, const ByteString &rDestinationFile , const ByteString& rPrj ) +/*****************************************************************************/ +{ + (void) rPrj; + Export::InitLanguages( true ); + SvFileStream aDestination( + String( rDestinationFile, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_WRITE | STREAM_TRUNC ); + if ( !aDestination.IsOpen()) { + nError = LNG_COULD_NOT_OPEN; + } + nError = LNG_OK; +// MergeDataFile( const ByteString &rFileName, const ByteString& rFile , BOOL bErrLog, CharSet aCharSet, BOOL bUTF8 ); + + MergeDataFile aMergeDataFile( rSDFFile, sSource , FALSE, RTL_TEXTENCODING_MS_1252);//, bDBIsUTF8 ); + ByteString sTmp( Export::sLanguages ); + if( sTmp.ToUpperAscii().Equals("ALL") ) + Export::SetLanguages( aMergeDataFile.GetLanguages() ); + aLanguages = Export::GetLanguages(); + + ULONG nPos = 0; + BOOL bGroup = FALSE; + ByteString sGroup; + + // seek to next group + while ( nPos < pLines->Count() && !bGroup ) { + ByteString sLine( *pLines->GetObject( nPos )); + sLine.EraseLeadingChars( ' ' ); + sLine.EraseTrailingChars( ' ' ); + if (( sLine.GetChar( 0 ) == '[' ) && + ( sLine.GetChar( sLine.Len() - 1 ) == ']' )) + { + sGroup = sLine.GetToken( 1, '[' ).GetToken( 0, ']' ); + sGroup.EraseLeadingChars( ' ' ); + sGroup.EraseTrailingChars( ' ' ); + bGroup = TRUE; + } + nPos ++; + } + + while ( nPos < pLines->Count()) { + ByteStringHashMap Text; + ByteString sID( sGroup ); + ULONG nLastLangPos = 0; + + ResData *pResData = new ResData( "", sID , sSource ); + pResData->sResTyp = "LngText"; + PFormEntrys *pEntrys = aMergeDataFile.GetPFormEntrys( pResData ); + // read languages + bGroup = FALSE; + + ByteString sLanguagesDone; + + while ( nPos < pLines->Count() && !bGroup ) { + ByteString sLine( *pLines->GetObject( nPos )); + sLine.EraseLeadingChars( ' ' ); + sLine.EraseTrailingChars( ' ' ); + if (( sLine.GetChar( 0 ) == '[' ) && + ( sLine.GetChar( sLine.Len() - 1 ) == ']' )) + { + sGroup = sLine.GetToken( 1, '[' ).GetToken( 0, ']' ); + sGroup.EraseLeadingChars( ' ' ); + sGroup.EraseTrailingChars( ' ' ); + bGroup = TRUE; + nPos ++; + sLanguagesDone = ""; + } + else if ( sLine.GetTokenCount( '=' ) > 1 ) { + ByteString sLang = sLine.GetToken( 0, '=' ); + sLang.EraseLeadingChars( ' ' ); + sLang.EraseTrailingChars( ' ' ); + + ByteString sSearch( ";" ); + sSearch += sLang; + sSearch += ";"; + + if (( sLanguagesDone.Search( sSearch ) != STRING_NOTFOUND )) { + pLines->Remove( nPos ); + } + if( bULF && pEntrys ) + { + // this is a valid text line + ByteString sText = sLine.GetToken( 1, '\"' ).GetToken( 0, '\"' ); + if( sLang.Len() ){ + ByteString sNewText; + pEntrys->GetText( sNewText, STRING_TYP_TEXT, sLang, TRUE ); + + if ( sNewText.Len()) { + ByteString *pLine = pLines->GetObject( nPos ); + + ByteString sText1( sLang ); + sText1 += " = \""; + sText1 += sNewText; + sText1 += "\""; + *pLine = sText1; + //} + Text[ sLang ] = sNewText; + } + } + nLastLangPos = nPos; + nPos ++; + sLanguagesDone += sSearch; + } + else { + nLastLangPos = nPos; + nPos ++; + sLanguagesDone += sSearch; + } + } + else + nPos++; + } + ByteString sCur; + if ( nLastLangPos ) { + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + if( //( !sCur.EqualsIgnoreCaseAscii("de") || + //( sCur.EqualsIgnoreCaseAscii("de") && Export::isMergingGermanAllowed( rPrj ) ) ) + !sCur.EqualsIgnoreCaseAscii("en-US") && !Text[ sCur ].Len() && pEntrys ){ + + ByteString sNewText; + pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur, TRUE ); + if (( sNewText.Len()) && + !(( sCur.Equals("x-comment") ) && ( sNewText == "-" ))) + { + ByteString sLine; + sLine += sCur; + sLine += " = \""; + sLine += sNewText; + sLine += "\""; + + nLastLangPos++; + nPos++; + + pLines->Insert( new ByteString( sLine ), nLastLangPos ); + } + } + } + } + + delete pResData; + } + + for ( ULONG i = 0; i < pLines->Count(); i++ ) + aDestination.WriteLine( *pLines->GetObject( i )); + + aDestination.Close(); + return TRUE; +} diff --git a/transex3/source/localize.cxx b/transex3/source/localize.cxx new file mode 100644 index 000000000000..d5e0541e6a24 --- /dev/null +++ b/transex3/source/localize.cxx @@ -0,0 +1,999 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: localize.cxx,v $ + * $Revision: 1.50 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" + +#include "srciter.hxx" +#include "export.hxx" +#include <stdio.h> +#include "tools/errcode.hxx" +#include "tools/fsys.hxx" + +#ifndef TRANSEX_FILE_HXX +#define TRANSEX_FILE_HXX +#include <transex3/file.hxx> +#endif + + +// +// SourceTreeLocalizer +// + +const char *ExeTable[][5] = { + { "src", "transex3", " -UTF8 -e", "negative", "noiso" }, + { "hrc", "transex3", " -UTF8 -e", "positive", "noiso" }, + //{ "src", "transex3", "-UTF8 -e", "negative", "noiso" }, + //{ "hrc", "transex3", "-UTF8 -e", "positive", "noiso" }, + + //{ "lng", "lngex", "-UTF8 -e", "negative", "noiso" }, + { "ulf", "ulfex", " -e", "negative", "noiso" }, + { "xrb", "xmlex", "-UTF8 -e", "negative", "iso" }, + { "xxl", "xmlex", "-UTF8 -e", "negative", "iso" }, + { "xgf", "xmlex", "-UTF8 -e -t:xgf", "negative", "iso" }, + { "xcd", "cfgex", "-UTF8 -e", "negative", "iso" }, + { "xcu", "cfgex", "-UTF8 -e", "negative", "iso" }, + { "xcs", "cfgex", "-UTF8 -e -f", "negative", "iso" }, + { "xrm", "xrmex", "-UTF8 -e", "negative", "iso" }, + { "xhp", "helpex", " -e", "negative", "noiso" }, + { "NULL", "NULL", "NULL", "NULL", "NULL" } +}; + +const char *NegativeList[] = { + "officecfg/data/org.openoffice.Office.Labels.xcd", + "officecfg/data/org/openoffice/Office/Labels.xcd", + "officecfg/data/org/openoffice/Office/SFX.xcd", + "officecfg/data/org/openoffice/Office/Accelerators.xcu", + "hidother.src", + "NULL" +}; + +const char *PositiveList[] = { + "svx/inc/globlmn_tmpl.hrc", + "sw/source/ui/inc/swmn_tmpl.hrc", + "sw/source/ui/inc/swacc_tmpl.hrc", + "sw/source/ui/inc/toolbox_tmpl.hrc", + "offmgr/inc/offmenu_tmpl.hrc", + "offmgr/source/offapp/intro/intro_tmpl.hrc", + "dbaccess/source/ui/inc/toolbox_tmpl.hrc", + "svx/source/intro/intro_tmpl.hrc", + "dbaccess/source/ui/dlg/AutoControls_tmpl.hrc", + "svx/source/unodialogs/textconversiondlgs/chinese_direction_tmpl.hrc", + "chart2/source/controller/dialogs/res_DataLabel_tmpl.hrc", + "chart2/source/controller/dialogs/res_LegendPosition_tmpl.hrc", + "chart2/source/controller/dialogs/res_Statistic_tmpl.hrc", + "chart2/source/controller/dialogs/res_Titlesx_tmpl.hrc", + "chart2/source/controller/dialogs/res_SecondaryAxisCheckBoxes_tmpl.hrc", + "chart2/source/controller/menu/MenuItems_tmpl.hrc", + "chart2/source/controller/dialogs/res_ErrorBar_tmpl.hrc", + "chart2/source/controller/dialogs/res_Trendline_tmpl.hrc", + "NULL" +}; + + +const char PRJ_DIR_NAME[] = "prj"; +const char DLIST_NAME[] = "d.lst"; + +#define LOCALIZE_NONE 0x0000 +#define LOCALIZE_EXTRACT 0x0001 +#define LOCALIZE_MERGE 0x0002 + +class SourceTreeLocalizer : public SourceTreeIterator +{ +private: + SvFileStream aSDF; + USHORT nMode; + + ByteString sLanguageRestriction; + + ByteString sIsoCode99; + ByteString sOutputFile; + bool bQuiet2; + + int nFileCnt; + + const ByteString GetProjectName( BOOL bAbs = FALSE ); + const ByteString GetProjectRootRel(); + + + BOOL CheckNegativeList( const ByteString &rFileName ); + BOOL CheckPositiveList( const ByteString &rFileName ); + + void WorkOnFile( + const ByteString &rFileName, + const ByteString &rExecutable, + const ByteString &rParameter, + const ByteString &rIso + ); + + void WorkOnFileType( + const ByteString &rDirectory, + const ByteString &rExtension, + const ByteString &rExecutable, + const ByteString &rParameter, + const ByteString &rCollectMode, + const ByteString &rIso + ); + void WorkOnDirectory( const ByteString &rDirectory ); + BOOL ExecuteMerge(); + BOOL MergeSingleFile( + const ByteString &rPrj, + const ByteString &rFile, + const ByteString &rSDFFile + ); + +public: + SourceTreeLocalizer( const ByteString &rRoot, const ByteString &rVersion , bool bLocal , bool bQuiet2_in , bool skip_links ); + ~SourceTreeLocalizer(); + + ByteString getSourceLanguages( ByteString sLanguageRestriction , ByteString sCommand ); + + void SetLanguageRestriction( const ByteString& rRestrictions ) + { sLanguageRestriction = rRestrictions; } + void SetIsoCode99( const ByteString& rIsoCode ) + { sIsoCode99 = rIsoCode; } + int getFileCnt(); + BOOL Extract( const ByteString &rDestinationFile ); + BOOL Merge( const ByteString &rSourceFile , const ByteString &rOutput ); + int GetFileCnt(); + virtual void OnExecuteDirectory( const rtl::OUString &rDirectory ); +}; + +/*****************************************************************************/ +SourceTreeLocalizer::SourceTreeLocalizer( + const ByteString &rRoot, const ByteString &rVersion, bool bLocal_in , bool bQuiet2_in , bool skip_links ) +/*****************************************************************************/ + : SourceTreeIterator( rRoot, rVersion , bLocal_in ), + nMode( LOCALIZE_NONE ), + bQuiet2( bQuiet2_in ), + nFileCnt( 0 ) +{ + bSkipLinks = skip_links ; +} + +/*****************************************************************************/ +SourceTreeLocalizer::~SourceTreeLocalizer() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +const ByteString SourceTreeLocalizer::GetProjectName( BOOL bAbs ) +/*****************************************************************************/ +{ + BOOL bFound = FALSE; + DirEntry aCur; + aCur.ToAbs(); + + for ( ; ! bFound && aCur.Level() > 1; aCur.CutName() ) + { + DirEntry aTest = aCur + DirEntry(PRJ_DIR_NAME) + DirEntry(DLIST_NAME); + if ( aTest.Exists() ) + { + // HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if (( ByteString( aCur.GetName(), RTL_TEXTENCODING_ASCII_US ).Equals("webinstall") ) || + ( ByteString( aCur.GetName(), RTL_TEXTENCODING_ASCII_US ).Equals("portal") ) || + ( ByteString( aCur.GetName(), RTL_TEXTENCODING_ASCII_US ).Equals("xulclient") ) || + ( ByteString( aCur.GetName(), RTL_TEXTENCODING_ASCII_US ).Search( "wdk_" ) == 0 )) + return ""; + // end HACK !!!!!!!!!!!!!!!!!!!!!!!!! + + + + if ( bAbs ) + return ByteString( aCur.GetFull(), RTL_TEXTENCODING_ASCII_US ); + else + return ByteString( aCur.GetName(), RTL_TEXTENCODING_ASCII_US ); + } + } + + return ""; +} +/*****************************************************************************/ +int SourceTreeLocalizer::GetFileCnt(){ +/*****************************************************************************/ + return nFileCnt; +} + +/*****************************************************************************/ +const ByteString SourceTreeLocalizer::GetProjectRootRel() +/*****************************************************************************/ +{ + ByteString sProjectRoot( GetProjectName( TRUE )); + DirEntry aCur; + aCur.ToAbs(); + ByteString sCur( aCur.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + if( sCur.SearchAndReplace( sProjectRoot, "" ) == STRING_NOTFOUND ) + return ""; + + ByteString sDelimiter( + DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US ); + + sCur.SearchAndReplaceAll( sDelimiter, "/" ); + sCur.EraseLeadingChars( '/' ); + ULONG nCount = sCur.GetTokenCount( '/' ); + + ByteString sProjectRootRel; + for ( ULONG i = 0; i < nCount; i++ ) { + if ( sProjectRootRel.Len()) + sProjectRootRel += sDelimiter; + sProjectRootRel += ".."; + } + if ( sProjectRootRel.Len()) + return sProjectRootRel; + + return "."; +} + +bool skipProject( ByteString sPrj ) +{ + static const ByteString READLICENSE( "readlicense" ); + return sPrj.EqualsIgnoreCaseAscii( READLICENSE ); +} + +/*****************************************************************************/ +void SourceTreeLocalizer::WorkOnFile( + const ByteString &rFileName, const ByteString &rExecutable, + const ByteString &rParameter, const ByteString &rIso ) +/*****************************************************************************/ +{ + String sFull( rFileName, RTL_TEXTENCODING_ASCII_US ); + DirEntry aEntry( sFull ); + ByteString sFileName( aEntry.GetName(), RTL_TEXTENCODING_ASCII_US ); + + // set current working directory + DirEntry aPath( aEntry.GetPath()); + DirEntry aOldCWD; + aPath.SetCWD(); + + ByteString sPrj( GetProjectName()); + //printf ("prj = %s , exe = %s\n", sPrj.GetBuffer() , rExecutable.GetBuffer() ); +// printf("Skip %s = %d \n",sPrj.GetBuffer() , skipProject( sPrj ) ); + //printf("prj = %s\n",sPrj.GetBuffer()); + if ( sPrj.Len() && !skipProject( sPrj ) ) + { + ByteString sRoot( GetProjectRootRel()); + + // get temp file + DirEntry aTemp( Export::GetTempFile()); + ByteString sTempFile( aTemp.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + ByteString sExecutable( rExecutable ); +#if defined(WNT) || defined(OS2) + sExecutable += ".exe"; + String sPath( Export::GetEnv( "PATH" ), RTL_TEXTENCODING_ASCII_US ); +#else + String sPath( Export::GetEnv( "LD_LIBRARY_PATH" ), RTL_TEXTENCODING_ASCII_US ); +#endif + + DirEntry aExecutable( String( sExecutable, RTL_TEXTENCODING_ASCII_US )); + aExecutable.Find( sPath ); + + ByteString sCommand( aExecutable.GetFull(), RTL_TEXTENCODING_ASCII_US ); + sCommand += " "; + sCommand += rParameter; + sCommand += " -p "; + sCommand += sPrj; + sCommand += " -r "; + sCommand += sRoot; + sCommand += " -i "; + sCommand += sFileName; + sCommand += " -o "; + sCommand += sTempFile; + if ( sLanguageRestriction.Len()) { + sCommand += " -l "; + sCommand += getSourceLanguages( sLanguageRestriction , sCommand ); + } + if ( rIso.Equals("iso") && sIsoCode99.Len()) { + sCommand += " -ISO99 "; + sCommand += sIsoCode99; + } + if( bQuiet2 ){ + sCommand +=" -QQ "; + } + //printf("DBG: %s\n",sCommand.GetBuffer()); + system( sCommand.GetBuffer()); + nFileCnt++; + printf("."); + fflush( stdout ); + + SvFileStream aSDFIn( aTemp.GetFull(), STREAM_READ ); + ByteString sLine; + while ( aSDFIn.IsOpen() && !aSDFIn.IsEof()) { + aSDFIn.ReadLine( sLine ); + if ( sLine.Len()) { + aSDF.WriteLine( sLine ); + } + } + aSDFIn.Close(); + + aTemp.Kill(); + + } + // reset current working directory + aOldCWD.SetCWD(); +} + +ByteString SourceTreeLocalizer::getSourceLanguages( ByteString sLanguageRestriction_inout , ByteString sCommand ) +{ + // Source languages in helpcontent2 and macromigration en-US only! + if( sCommand.Search("helpex") != STRING_NOTFOUND ) { + sLanguageRestriction_inout.Assign( ByteString("en-US") ); + } + else if( sCommand.Search("xmlex") != STRING_NOTFOUND ){ + sLanguageRestriction_inout.Assign( ByteString("en-US") ); + } + return sLanguageRestriction_inout; +} + +/*****************************************************************************/ +BOOL SourceTreeLocalizer::CheckNegativeList( const ByteString &rFileName ) +/*****************************************************************************/ +{ + ULONG nIndex = 0; + BOOL bReturn = TRUE; + + ByteString sDelimiter( + DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US ); + + ByteString sFileName( rFileName ); + sFileName.ToLowerAscii(); + + ByteString sNegative( NegativeList[ nIndex ] ); + while( !sNegative.Equals( "NULL" ) && bReturn ) { + sNegative.SearchAndReplaceAll( "\\", sDelimiter ); + sNegative.SearchAndReplaceAll( "/", sDelimiter ); + sNegative.ToLowerAscii(); + + if( sFileName.Search( sNegative ) == sFileName.Len() - sNegative.Len()) + bReturn = FALSE; + + nIndex++; + sNegative = NegativeList[ nIndex ]; + } + + return bReturn; +} + +/*****************************************************************************/ +BOOL SourceTreeLocalizer::CheckPositiveList( const ByteString &rFileName ) +/*****************************************************************************/ +{ + ULONG nIndex = 0; + BOOL bReturn = FALSE; + + ByteString sDelimiter( + DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US ); + + ByteString sFileName( rFileName ); + sFileName.ToLowerAscii(); + + ByteString sNegative( PositiveList[ nIndex ] ); + while( !sNegative.Equals( "NULL" ) && !bReturn ) { + sNegative.SearchAndReplaceAll( "\\", sDelimiter ); + sNegative.SearchAndReplaceAll( "/", sDelimiter ); + sNegative.ToLowerAscii(); + + if( sFileName.Search( sNegative ) == sFileName.Len() - sNegative.Len()) + bReturn = TRUE; + + nIndex++; + sNegative = PositiveList[ nIndex ]; + } + + return bReturn; +} + +/*****************************************************************************/ +void SourceTreeLocalizer::WorkOnFileType( + const ByteString &rDirectory, const ByteString &rExtension, + const ByteString &rExecutable, const ByteString &rParameter, + const ByteString &rCollectMode, const ByteString &rIso +) +/*****************************************************************************/ +{ + String sWild( rDirectory, RTL_TEXTENCODING_ASCII_US ); + sWild += DirEntry::GetAccessDelimiter(); + sWild += String::CreateFromAscii( "*." ); + sWild += String( rExtension, RTL_TEXTENCODING_ASCII_US ); + + DirEntry aEntry( sWild ); + Dir aDir( sWild, FSYS_KIND_FILE ); + + for ( USHORT i = 0; i < aDir.Count(); i++ ) { + DirEntry aFile( aDir[ i ] ); + ByteString sFile( aFile.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + BOOL bAllowed = TRUE; + + if ( rCollectMode.Equals( "negative" )) + bAllowed = CheckNegativeList( sFile ); + else if ( rCollectMode.Equals( "positive" )) + bAllowed = CheckPositiveList( sFile ); + + if ( bAllowed ) + WorkOnFile( sFile, rExecutable, rParameter, rIso ); + } +} + +/*****************************************************************************/ +void SourceTreeLocalizer::WorkOnDirectory( const ByteString &rDirectory ) +/*****************************************************************************/ +{ + //printf("Working on Directory %s\n",rDirectory.GetBuffer()); + ULONG nIndex = 0; + ByteString sExtension( ExeTable[ nIndex ][ 0 ] ); + ByteString sExecutable( ExeTable[ nIndex ][ 1 ] ); + ByteString sParameter( ExeTable[ nIndex ][ 2 ] ); + ByteString sCollectMode( ExeTable[ nIndex ][ 3 ] ); + ByteString sIso( ExeTable[ nIndex ][ 4 ] ); + + while( !sExtension.Equals( "NULL" )) { + WorkOnFileType( + rDirectory, + sExtension, + sExecutable, + sParameter, + sCollectMode, + sIso + ); + + nIndex++; + + sExtension = ExeTable[ nIndex ][ 0 ]; + sExecutable = ExeTable[ nIndex ][ 1 ]; + sParameter = ExeTable[ nIndex ][ 2 ]; + sCollectMode = ExeTable[ nIndex ][ 3 ]; + sIso = ExeTable[ nIndex ][ 4 ]; + } +} + +void SourceTreeLocalizer::OnExecuteDirectory( const rtl::OUString &aDirectory ) +{ + ByteString rDirectory( rtl::OUStringToOString( aDirectory , RTL_TEXTENCODING_UTF8 , aDirectory.getLength() ) ) ; + if ( nMode == LOCALIZE_NONE ){ + if( !bQuiet2 ) fprintf( stdout, "%s\n", rDirectory.GetBuffer()); + } + else + WorkOnDirectory( rDirectory ); +} + +/*****************************************************************************/ +BOOL SourceTreeLocalizer::Extract( const ByteString &rDestinationFile ) +/*****************************************************************************/ +{ + nMode = LOCALIZE_EXTRACT; + aSDF.Open( String( rDestinationFile, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_WRITE | STREAM_TRUNC ); + aSDF.SetLineDelimiter( LINEEND_CRLF ); + + BOOL bReturn = aSDF.IsOpen(); + if ( bReturn ) { + bReturn = StartExecute(); + aSDF.Close(); + } + else{ + printf("ERROR: Can't create file %s\n", rDestinationFile.GetBuffer() ); + } + nMode = LOCALIZE_NONE; + return bReturn; +} + +/*****************************************************************************/ +BOOL SourceTreeLocalizer::MergeSingleFile( + const ByteString &rPrj, + const ByteString &rFile, + const ByteString &rSDFFile +) +/*****************************************************************************/ +{ + //printf("MergeSingleFile(%s,%s,%s)",rPrj.GetBuffer(),rFile.GetBuffer(),rSDFFile.GetBuffer()); + if ( !rFile.Len()) + return TRUE; + + ByteString sRoot( Export::GetEnv( "SRC_ROOT" )); + DirEntry aEntry( String( sRoot, RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( String( rPrj, RTL_TEXTENCODING_ASCII_US )); + + ByteString sDelimiter( + DirEntry::GetAccessDelimiter(), RTL_TEXTENCODING_ASCII_US ); + + ByteString sCur( rFile ); + sCur.SearchAndReplaceAll( "\\", sDelimiter ); + sCur.SearchAndReplaceAll( "/", sDelimiter ); + + aEntry += DirEntry( String( sCur, RTL_TEXTENCODING_ASCII_US )); + ByteString sFile( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + ByteString sBCur( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + if( !bQuiet2 ) fprintf( stdout, "##### %s #####\n", sBCur.GetBuffer()); + + ULONG nIndex = 0; + ByteString sExtension( aEntry.GetExtension(), RTL_TEXTENCODING_ASCII_US ); + ByteString sCandidate( ExeTable[ nIndex ][ 0 ] ); + + while( !sCandidate.Equals ("NULL") && !sCandidate.Equals(sExtension) ) + sCandidate = ExeTable[ ++nIndex ][ 0 ]; + + ByteString sIso( ExeTable[ nIndex ][ 4 ] ); + + if ( !sCandidate.Equals( "NULL" ) ) { + if( !aEntry.Exists()) { + DirEntryKind theDir=FSYS_KIND_FILE; + Dir myDir( aEntry.GetPath(), theDir); + DirEntry current; + BOOL found=FALSE; + for( USHORT x=0; x < myDir.Count() && !found;){ + current=myDir[x++]; + StringCompare result=current.GetName().CompareIgnoreCaseToAscii( aEntry.GetName() ); + if( result==COMPARE_EQUAL ){ + fprintf(stderr,"WARNING: %s not found\n", ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US).GetBuffer() ); + fprintf(stderr,"but use %s instead \n" , ByteString(current.GetFull(), RTL_TEXTENCODING_ASCII_US).GetBuffer() ); + aEntry=current; + found=TRUE; + } + } + if(!found) return TRUE; + + } + + DirEntry aOut( Export::GetTempFile() ); + ByteString sOutput; + if( sOutputFile.Len() == 0 ) + sOutput = ByteString ( aOut.GetFull(), RTL_TEXTENCODING_ASCII_US ); + else + sOutput = sOutputFile; + ByteString sCommand( ExeTable[ nIndex ][ 1 ] ); + sCommand += " -i "; + sCommand += ByteString( aEntry.GetName(), RTL_TEXTENCODING_ASCII_US ); + sCommand += " -m "; + sCommand += rSDFFile; + sCommand += " -o "; + sCommand += sOutput; + sCommand += " "; + sCommand += ByteString( ExeTable[ nIndex ][ 2 ] ); + if ( sIso.Equals( "iso" ) && sIsoCode99.Len()) { + sCommand += " -ISO99 "; + sCommand += sIsoCode99; + } + if ( sLanguageRestriction.Len()) { + sCommand += " -l "; + sCommand += sLanguageRestriction; + } + if( bQuiet2 ){ + sCommand +=" -QQ "; + } + + DirEntry aPath( aEntry.GetPath()); + DirEntry aOldCWD; + aPath.SetCWD(); + + system( sCommand.GetBuffer()); + nFileCnt++; + printf("."); + //if( bQuiet2 ){ printf("."); } + SvFileStream aInStream( aOut.GetFull(), STREAM_READ ); + if ( !aInStream.IsOpen()) { + fprintf( stderr, + "ERROR: Unable to open file %s for reading!\n", + sOutput.GetBuffer()); + } + else { + FileStat::SetReadOnlyFlag( aEntry, FALSE ); + String myStr2(aEntry.GetFull()); + String aTemp22 = String::CreateFromAscii("_tmp"); + myStr2.Append(aTemp22); + + ByteString test(myStr2,RTL_TEXTENCODING_ASCII_US); + SvFileStream aOutStream( myStr2, STREAM_STD_WRITE | STREAM_TRUNC ); + if ( !aOutStream.IsOpen()) { + ByteString test2(myStr2,RTL_TEXTENCODING_ASCII_US); + fprintf( stderr,"ERROR: Unable to open file %s for modification!\n", test2.GetBuffer()); + aInStream.Close(); + } + + else { + ByteString sLine; + aOutStream.SetLineDelimiter( LINEEND_LF ); + + aInStream.ReadLine( sLine ); + while ( !aInStream.IsEof()) { + aOutStream.WriteLine( sLine ); + aInStream.ReadLine( sLine ); + } + aInStream.Close(); + aOutStream.Close(); + + + DirEntry myTempFile(ByteString(myStr2,RTL_TEXTENCODING_ASCII_US)); // xxx_tmp -> + DirEntry myFile(ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US));// xxx + + DirEntry oldFile(ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US)); + + if(oldFile.Kill()==ERRCODE_NONE){ + if(myTempFile.MoveTo(myFile)!=ERRCODE_NONE){ + fprintf( stderr, "ERROR: Can't rename file %s\n",ByteString(myStr2,RTL_TEXTENCODING_ASCII_US).GetBuffer()); + } + } + else{ + fprintf( stderr, "ERROR: Can't remove file %s\n",ByteString(aEntry.GetFull(),RTL_TEXTENCODING_ASCII_US).GetBuffer()); + } + } // else + + aOldCWD.SetCWD(); + aOut.Kill(); + } // else + } + return TRUE; +} +/*****************************************************************************/ +BOOL SourceTreeLocalizer::ExecuteMerge( ) +/*****************************************************************************/ +{ + DirEntry aEntry( Export::GetTempFile()); + BOOL bReturn = TRUE; + bool bMerged = false; + + ByteString sFileName; + ByteString sCurFile; + ByteString sLine; + ByteString sFileKey; + + SvFileStream aFile; + + ByteString sOutputFileName = sOutputFile; + ByteString sInpath("."); + sInpath += Export::GetEnv("INPATH"); + ByteString sBlank(""); + + sOutputFileName.SearchAndReplaceAll( sInpath , sBlank ); + + String sDel = DirEntry::GetAccessDelimiter(); + ByteString sBDel( sDel.GetBuffer() , sDel.Len() , RTL_TEXTENCODING_UTF8 ); + if( bLocal ){ + xub_StrLen nPos = sOutputFileName.SearchBackward( sBDel.GetChar(0) ); + //if( nPos >= 0 ) + sOutputFileName = sOutputFileName.Copy( nPos+1 , sOutputFileName.Len()-nPos-1 ); + } + ByteStringBoolHashMap aFileHM; + // Read all possible files + while ( !aSDF.IsEof()) { + aSDF.ReadLine( sLine ); + sFileName = sLine.GetToken( 0, '\t' ); + sFileName += "#"; + sFileName += sLine.GetToken( 1, '\t' ); + aFileHM[sFileName]=true; + } + + // RECODE THIS !!!!!!!!!!!!!!!!!!!!! + for( ByteStringBoolHashMap::iterator iter = aFileHM.begin(); iter != aFileHM.end(); ++iter ){ + sFileKey = iter->first; + aSDF.Seek( 0 ); + aFile.Open( aEntry.GetFull(), STREAM_STD_WRITE |STREAM_TRUNC ); + + while ( !aSDF.IsEof()) { + aSDF.ReadLine( sLine ); + sFileName = sLine.GetToken( 0, '\t' ); + sFileName += "#"; + sFileName += sLine.GetToken( 1, '\t' ); + if( sFileName.Len() && ( sFileName.CompareTo(sFileKey) == COMPARE_EQUAL ) ){ + if ( aFile.IsOpen() && sLine.Len()) + aFile.WriteLine( sLine ); + } + } + if ( aFile.IsOpen()) + aFile.Close(); + + ByteString sPrj( sFileKey.GetToken( 0, '#' )); + ByteString sFile( sFileKey.GetToken( 1, '#' )); + ByteString sSDFFile( aFile.GetFileName(), RTL_TEXTENCODING_ASCII_US ); + + //printf("localize test sPrj = %s , sFile = %s , sSDFFile = %s sOutputFileName = %s\n",sPrj.GetBuffer(), sFile.GetBuffer() , sSDFFile.GetBuffer() , sOutputFileName.GetBuffer() ); + + // Test + bLocal = true; + // Test + + if( bLocal ){ + USHORT nPos = sFile.SearchBackward( '\\' ); + ByteString sTmp = sFile.Copy( nPos+1 , sFile.Len()-nPos-1 ); + //printf("'%s'='%s'\n",sTmp.GetBuffer(), sOutputFileName.GetBuffer()); + if( sTmp.CompareTo(sOutputFileName) == COMPARE_EQUAL ){ + bMerged = true; + if ( !MergeSingleFile( sPrj, sFile, sSDFFile )) + bReturn = FALSE; + //} + }else{ + bMerged = true; + //printf("MergeSingleFile('%s','%s','%s')\n",sPrj.GetBuffer(),sFile.GetBuffer(),sSDFFile.GetBuffer()); + if ( !MergeSingleFile( sPrj, sFile, sSDFFile )) + bReturn = FALSE; + } + } + } + //} + aEntry.Kill(); + // If Outputfile not included in the SDF file copy it without merge + + if( bLocal && !bMerged ){ + DirEntry aSourceFile( sOutputFileName.GetBuffer() ); + FSysError aErr = aSourceFile.CopyTo( DirEntry ( sOutputFile.GetBuffer() ) , FSYS_ACTION_COPYFILE ); + if( aErr != FSYS_ERR_OK ){ + printf("ERROR: Can't copy file '%s' to '%s' %d\n",sOutputFileName.GetBuffer(),sOutputFile.GetBuffer(),sal::static_int_cast<int>(aErr)); + } + } + return bReturn; + +} + +/*****************************************************************************/ +BOOL SourceTreeLocalizer::Merge( const ByteString &rSourceFile , const ByteString &rOutput ) +/*****************************************************************************/ +{ + sOutputFile = rOutput; + nMode = LOCALIZE_MERGE; + aSDF.Open( String( rSourceFile, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_READ ); + + BOOL bReturn = aSDF.IsOpen(); + if ( bReturn ) { + bReturn = ExecuteMerge(); + aSDF.Close(); + } + + nMode = LOCALIZE_NONE; + return bReturn; +} + + +#define STATE_NONE 0x0000 +#define STATE_EXPORT 0x0001 +#define STATE_MERGE 0x0002 +#define STATE_ISOCODE 0x0003 +#define STATE_LANGUAGES 0x0004 +#define STATE_FILENAME 0x0005 +#define STATE_OUTPUT 0x0006 + +/*****************************************************************************/ +void Help() +/*****************************************************************************/ +{ + fprintf( stdout, + "localize (c)2001 by Sun Microsystems\n" + "====================================\n" ); + fprintf( stdout, + "As part of the L10N framework, localize extracts and merges translations\n" + "out of and into the whole source tree.\n\n" + "Syntax: localize -e|-m -l l1[=f1][,l2[=f2]][...] -f FileName [-QQ][-skip_links]\n" + "Parameter:\n" + "\t-e: Extract mode\n" + "\t-m: Merge mode\n" + "\tFileName: Output file when extract mode, input file when merge mode\n" + "\tl1...ln: supported languages (\"all\" for all languages).\n" + "\tf1...fn: fallback languages for supported languages\n" + "\tQQ: quiet output)" + ); + + fprintf( stdout, + "Valid language codes for l1...ln and f1...fn are:\n" ); + fprintf( stdout, + "\nExample 1:\n" + "==========\n" + "localize -e -l en-US,de -f MyFile\n\n" + "All strings will be extracted for language de and language en-US.\n" + ); + fprintf( stdout, + "\nExample 2:\n" + "==========\n" + "localize -m -l es -f MyFile\n\n" + "All strings in MyFile will be merged into language es in the\n" + "source code.\n" + ); +} + +/*****************************************************************************/ +int Error() +/*****************************************************************************/ +{ + Help(); + return 1; +} + +/*****************************************************************************/ +BOOL CheckLanguages( ByteString &rLanguages ) +/*****************************************************************************/ +{ + ByteString sTmp( rLanguages ); + return true; +} + +/*****************************************************************************/ +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + String sTempBase( String::CreateFromAscii( "loc" )); + DirEntry::SetTempNameBase( sTempBase ); + USHORT nState = STATE_NONE; + + BOOL bExport = FALSE; + BOOL bMerge = FALSE; + bool bQuiet = false; + bool bQuiet2 = false; + bool bSkipLinks = false; + + ByteString sIsoCode; + ByteString sLanguages; + ByteString sFileName; + ByteString sOutput; + + for( int i = 1; i < argc; i++ ) { + ByteString sSwitch( argv[ i ] ); + sSwitch.ToUpperAscii(); + + if ( sSwitch.Equals( "-E" )) { + nState = STATE_EXPORT; + if ( bMerge ) + return Error(); + bExport = TRUE; + } + else if ( sSwitch.Equals( "-M" )) { + nState = STATE_MERGE; + if ( bExport ) + return Error(); + bMerge = TRUE; + } + else if( sSwitch.Equals( "-Q" )) { + bQuiet = true; + } + else if ( sSwitch.Equals( "-I" ) ) + nState = STATE_ISOCODE; + else if ( sSwitch.Equals( "-L" ) ) + nState = STATE_LANGUAGES; + else if ( sSwitch.Equals( "-F" ) ) + nState = STATE_FILENAME; + else if ( sSwitch.Equals( "-QQ" )) + bQuiet2 = true; + // else if ( ByteString( argv[ i ]).ToUpperAscii().Equals( "-SKIP_LINKS" )) + // bSkipLinks = true; + else if ( ByteString( argv[ i ]).ToUpperAscii().Equals( "-O" ) ) + nState = STATE_OUTPUT; + else { + switch ( nState ) { + case STATE_NONE: + return Error(); + case STATE_ISOCODE: + if ( sIsoCode.Len()) + return Error(); + sIsoCode = ByteString( argv[ i ] ); + nState = STATE_NONE; + break; + case STATE_OUTPUT: + if ( sOutput.Len()) + return Error(); + sOutput = ByteString( argv[ i ] ); + nState = STATE_NONE; + break; + case STATE_LANGUAGES: + if ( sLanguages.Len()) + return Error(); + sLanguages = ByteString( argv[ i ] ); + nState = STATE_NONE; + break; + case STATE_FILENAME: + if ( sFileName.Len()) + return Error(); + sFileName = ByteString( argv[ i ] ); + nState = STATE_NONE; + break; + default: + return Error(); + } + } + } + if ( !bMerge && !bExport ) { + Help(); + return 1; + } + + ByteString sRoot( Export::GetEnv( "SRC_ROOT" )); + DirEntry aRoot( String( sRoot, RTL_TEXTENCODING_ASCII_US )); + sRoot = ByteString( aRoot.GetFull(), RTL_TEXTENCODING_ASCII_US ); + ByteString sVersion( Export::GetEnv( "WORK_STAMP" )); + + if ( !sRoot.Len() || !sVersion.Len()) { + fprintf( stderr, "ERROR: No environment set!\n" ); + return 1; + } + + if ( !CheckLanguages( sLanguages )) + return 2; + + if ( !sFileName.Len()) { + fprintf( stderr, "ERROR: No filename given\n" ); + return 3; + } + + ByteString sMode( "merge" ); + if ( bExport ) + sMode = "extract"; + + ByteString sICode( sIsoCode ); + if ( !sICode.Len()) + sICode = "not given, support for language 99 disabled"; + if(!bQuiet && !bQuiet2 ){ + fprintf( stdout, + "\n" + "============================================================\n" + "Current settings:\n" + "============================================================\n" + "Mode: %s\n" + "Workspace: %s\n" + "Source tree: %s\n" + "Languages: %s\n" + "ISO code (99): %s\n" + "Filename: %s\n" + "Outputfile %s\n" + "============================================================\n" + "\n" + , + sMode.GetBuffer(), + sVersion.GetBuffer(), + sRoot.GetBuffer(), + sLanguages.GetBuffer(), + sICode.GetBuffer(), + sFileName.GetBuffer(), + sOutput.GetBuffer() + ); + } + SourceTreeLocalizer aIter( sRoot, sVersion , (sOutput.Len() > 0) , bQuiet2 , bSkipLinks ); + + aIter.SetLanguageRestriction( sLanguages ); + aIter.SetIsoCode99( sIsoCode ); + if ( bExport ){ + if( bQuiet2 ){ /*printf("");*/fflush( stdout );} + aIter.Extract( sFileName ); + if( bQuiet2 ){ printf("\n %d files found!\n",aIter.GetFileCnt());} + } + else { + + DirEntry aEntry( String( sFileName, RTL_TEXTENCODING_ASCII_US )); + if ( !aEntry.Exists()) + return FALSE; + printf("%s\n",sFileName.GetBuffer()); + aIter.Merge( sFileName , sOutput ); + } + + return 0; +} diff --git a/transex3/source/makefile.mk b/transex3/source/makefile.mk new file mode 100644 index 000000000000..68b94a5b58fa --- /dev/null +++ b/transex3/source/makefile.mk @@ -0,0 +1,208 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.46 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +INCPRE=$(MISC) + +PRJNAME=transex3 +TARGET=transex +TARGETTYPE=CUI +LIBTARGET=no +# --- Settings ----------------------------------------------------- +ENABLE_EXCEPTIONS=TRUE + +.INCLUDE : settings.mk +CDEFS+= -DYY_NEVER_INTERACTIVE=1 +#CDEFS+= -pg + +.IF "$(SYSTEM_EXPAT)" == "YES" +CFLAGS+=-DSYSTEM_EXPAT +.ENDIF + + +# --- Files -------------------------------------------------------- + +OBJFILES= \ + $(OBJ)$/export.obj \ + $(OBJ)$/export2.obj \ + $(OBJ)$/merge.obj \ + $(OBJ)$/srciter.obj \ + $(OBJ)$/utf8conv.obj \ + $(OBJ)$/xmlparse.obj \ + $(OBJ)$/helpmerge.obj \ + $(OBJ)$/helpex.obj \ + $(OBJ)$/file.obj \ + $(OBJ)$/directory.obj \ + $(OBJ)$/hw2fw.obj + +LIB1TARGET= $(LB)$/$(TARGET).lib +LIB1ARCHIV= $(LB)$/libtransex.a +#LIB1FILES= $(LB)$/transex3.lib +LIB1OBJFILES= $(OBJ)$/export.obj \ + $(OBJ)$/export2.obj \ + $(OBJ)$/merge.obj \ + $(OBJ)$/srciter.obj \ + $(OBJ)$/file.obj \ + $(OBJ)$/directory.obj \ + $(OBJ)$/utf8conv.obj \ + $(OBJ)$/hw2fw.obj + +APP1VERSIONMAP=exports.map + +# extractor and merger for *.src and *.hrc +APP1TARGET= transex3 +#APP1OBJS= $(OBJ)$/src_yy.obj +APP1OBJS= $(OBJ)$/src_yy_wrapper.obj + +APP1STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(OS)"=="MACOSX" +# static libs at end for OS X +.ENDIF + +APP1LIBS+= $(LB)$/$(TARGET).lib +APP1DEPN= $(OBJ)$/src_yy_wrapper.obj $(LB)$/$(TARGET).lib + +APP2TARGET= helpex +APP2OBJS= $(OBJ)$/helpmerge.obj $(OBJ)$/xmlparse.obj $(OBJ)$/export2.obj $(OBJ)$/utf8conv.obj $(OBJ)$/merge.obj $(OBJ)$/helpex.obj $(OBJ)$/hw2fw.obj +APP2RPATH= NONE + +.IF "$(OS)"!="MACOSX" +.ENDIF + +APP2STDLIBS+=$(SALLIB) $(EXPATASCII3RDLIB) $(TOOLSLIB) $(VOSLIB) + +.IF "$(OS)"=="MACOSX" +# static libs at end for OS X +.ENDIF + +# extractor and merger for *.lng and *.lng +APP3TARGET= ulfex +APP3OBJS= $(OBJ)$/lngmerge.obj $(OBJ)$/hw2fw.obj $(OBJ)$/merge.obj $(OBJ)$/export2.obj $(OBJ)$/lngex.obj $(OBJ)$/utf8conv.obj +APP3RPATH= NONE + +.IF "$(OS)"!="MACOSX" +#APP3STDLIBS+= $(BTSTRPLIB) +.ENDIF +APP3STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) +.IF "$(OS)"=="MACOSX" +# static libs at end for OS X +.ENDIF + +# encoding converter for *.gsi +APP4TARGET= gsiconv +APP4OBJS= $(OBJ)$/utf8conv.obj $(OBJ)$/gsiconv.obj +APP4STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +# tag checker for *.gsi +APP5TARGET= gsicheck +APP5OBJS= $(OBJ)$/gsicheck.obj $(OBJ)$/tagtest.obj +APP5STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +# extractor and merger for *.cfg +APP6TARGET= cfgex +APP6OBJS= $(OBJ)$/cfgmerge.obj $(OBJ)$/cfg_yy_wrapper.obj $(OBJ)$/hw2fw.obj $(OBJ)$/merge.obj $(OBJ)$/export2.obj $(OBJ)$/utf8conv.obj + +.IF "$(OS)"!="MACOSX" +#APP6STDLIBS+= $(BTSTRPLIB) +.ENDIF + +APP6STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(OS)"=="MACOSX" +# static libs at end for OS X +.ENDIF + +# extractor and merger for *.xrm +APP7TARGET= xrmex +APP7OBJS= $(OBJ)$/xrmmerge.obj $(OBJ)$/xrm_yy_wrapper.obj $(OBJ)$/hw2fw.obj $(OBJ)$/merge.obj $(OBJ)$/export2.obj $(OBJ)$/utf8conv.obj +APP7RPATH= NONE + +.IF "$(OS)"!="MACOSX" +.ENDIF + +APP7STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(OS)"=="MACOSX" +# static libs at end for OS X +.ENDIF + +# encoding converter for text files +APP8TARGET= txtconv +#APP8STACK= 16000 +APP8OBJS= $(OBJ)$/utf8conv.obj $(OBJ)$/txtconv.obj $(OBJ)$/hw2fw.obj +APP8STDLIBS=$(TOOLSLIB) $(SALLIB) + +# localizer for l10n framework +APP9TARGET= localize_sl +EXCEPTIONSFILES= \ + $(OBJ)$/localize.obj +APP9OBJS= $(OBJ)$/localize.obj $(OBJ)$/utf8conv.obj $(OBJ)$/srciter.obj $(OBJ)$/export2.obj $(OBJ)$/file.obj $(OBJ)$/directory.obj + +APP9STDLIBS+= \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +DEPOBJFILES=$(APP1OBJS) $(APP2OBJS) $(APP3OBJS) $(APP4OBJS) $(APP5OBJS) $(APP6OBJS) $(APP7OBJS) $(APP8OBJS) $(APP9OBJS) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +$(MISC)$/%_yy.c : %lex.l + flex -l -w -8 -o$@ $< + +# Helper to suppress warnings in lex generated c code, see #i57362# + +$(OBJ)$/src_yy_wrapper.obj: $(MISC)$/src_yy.c +$(OBJ)$/cfg_yy_wrapper.obj: $(MISC)$/cfg_yy.c +$(OBJ)$/xrm_yy_wrapper.obj: $(MISC)$/xrm_yy.c + diff --git a/transex3/source/merge.cxx b/transex3/source/merge.cxx new file mode 100644 index 000000000000..3546d7e3accd --- /dev/null +++ b/transex3/source/merge.cxx @@ -0,0 +1,433 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: merge.cxx,v $ + * $Revision: 1.29 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <tools/fsys.hxx> +#include "export.hxx" +#include "utf8conv.hxx" +#include <iostream> + +using namespace std; + +extern void ConvertHalfwitdhToFullwidth( String& rString ); + +// +// class PFormEntrys +// + +ByteString PFormEntrys::Dump(){ + ByteString sRet( "PFormEntrys\n" ); + //sRet.Append( Export::DumpMap( ByteString("sText") , sText ) ); + //sRet.Append("\n"); + ByteString a("sText"); + if ( sText.size() ) Export::DumpMap( a , sText ); + return sRet; +} + +/*****************************************************************************/ +BOOL PFormEntrys::GetText( ByteString &rReturn, + USHORT nTyp, const ByteString &nLangIndex, BOOL bDel ) +/*****************************************************************************/ +{ + + /*printf("DBG: PFormEntrys::GetText(nId=%s)\n",nLangIndex.GetBuffer() ); + + // DEBUG****************** + ByteStringHashMap::const_iterator idbg; + std::cout << "HASHKEYS : \n"; + for( idbg = sText.begin() ; idbg != sText.end(); ++idbg ) + std::cout << (idbg->first).GetBuffer() << "\n"; + std::cout << "\n\n"; + std::cout << "String sText[ nLangIndex ] = " << sText[ nLangIndex ].GetBuffer() << "\n"; + // DEBUG****************** +*/ + + BOOL bReturn=TRUE; + switch ( nTyp ) { + case STRING_TYP_TEXT : + rReturn = sText[ nLangIndex ]; + if ( bDel ) + sText[ nLangIndex ] = ""; + bReturn = bTextFirst[ nLangIndex ]; + bTextFirst[ nLangIndex ] = FALSE; + break; + case STRING_TYP_HELPTEXT : + rReturn = sHelpText; + break; + case STRING_TYP_QUICKHELPTEXT : + rReturn = sQuickHelpText[ nLangIndex ]; + if ( bDel ) + sQuickHelpText[ nLangIndex ] = ""; + bReturn = bQuickHelpTextFirst[ nLangIndex ]; + bQuickHelpTextFirst[ nLangIndex ] = FALSE; + break; + case STRING_TYP_TITLE : + rReturn = sTitle[ nLangIndex ]; + if ( bDel ) + sTitle[ nLangIndex ] = ""; + bReturn = bTitleFirst[ nLangIndex ]; + bTitleFirst[ nLangIndex ] = FALSE; + break; + } + //printf("Returning '%s'\n",rReturn.GetBuffer()); + return bReturn; +} + + +// +// class MergeData +// + +/*****************************************************************************/ +MergeData::~MergeData() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +PFormEntrys* MergeData::GetPFormEntrys( ResData *pResData ) +/*****************************************************************************/ +{ + + (void) pResData; // FIXME + if( aMap.find( ByteString("HACK") ) != aMap.end() ){ + return aMap[ ByteString("HACK") ]; + } + else{ + return 0; + } +} + +void MergeData::Insert( const ByteString& rPFO , PFormEntrys* pfEntrys ){ + (void) rPFO; // FIXME + aMap.insert( PFormEntrysHashMap::value_type( ByteString("HACK") , pfEntrys ) ); + +} +ByteString MergeData::Dump(){ + ByteString sRet( "MergeData\n" ); + + printf("MergeData sTyp = %s , sGid = %s , sLid =%s , sFilename = %s\n",sTyp.GetBuffer(),sGID.GetBuffer(),sLID.GetBuffer(), sFilename.GetBuffer() ); + + PFormEntrysHashMap::const_iterator idbg; + for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg ){ + printf("aMap[ %s ] = " ,idbg->first.GetBuffer()); + ( (PFormEntrys*)(idbg->second) )->Dump(); + printf("\n") ; + } + printf("\n") ; + return sRet; +} + +PFormEntrys* MergeData::GetPFObject( const ByteString& rPFO ){ + if( aMap.find( ByteString("HACK") ) != aMap.end() ){ + return aMap[ rPFO ]; + } + else{ + return 0; + } +} + + +/*****************************************************************************/ +PFormEntrys *MergeData::InsertEntry( const ByteString &rPForm ) +/*****************************************************************************/ +{ + PFormEntrys* pFEntrys = new PFormEntrys( rPForm ); + aMap.insert( PFormEntrysHashMap::value_type( rPForm , pFEntrys ) ); + return pFEntrys; +} + +/*****************************************************************************/ +BOOL MergeData::operator==( ResData *pData ) +/*****************************************************************************/ +{ + ByteString sResTyp_upper( pData->sResTyp ); + sResTyp_upper.ToUpperAscii(); + ByteString sTyp_upper( sTyp ); + sTyp_upper.ToUpperAscii(); + + return (( pData->sId == sLID ) && + ( pData->sGId == sGID ) && + ( sResTyp_upper == sTyp_upper ) + ); +} + +// +// class MergeDataFile +// + +#define FFORMAT_UNKNOWN 0x0000 +#define FFORMAT_NEW 0x0001 +#define FFORMAT_OLD 0x0002 + +/*****************************************************************************/ +MergeDataFile::MergeDataFile( const ByteString &rFileName, const ByteString& sFile ,BOOL bErrLog, +// CharSet aCharSet, BOOL bUTF8 , bool bCaseSensitive ) + CharSet aCharSet, bool bCaseSensitive ) + +/*****************************************************************************/ + : bErrorLog( bErrLog ) +{ + + SvFileStream aInputStream( String( rFileName, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); + aInputStream.SetStreamCharSet( aCharSet ); + ByteString sLine; +// printf("\nReading localize.sdf ...\n"); + ByteString sTYP; + ByteString sGID; + ByteString sLID; + ByteString sPFO; + ByteString nLANG; + ByteString sTEXT; + ByteString sQHTEXT; + ByteString sTITLE; + + const ByteString sEmpty(""); + + if( !aInputStream.IsOpen() ) { + printf("ERROR : Can't open %s\n", rFileName.GetBuffer()); + exit( -1 ); + } + while ( !aInputStream.IsEof()) { + aInputStream.ReadLine( sLine ); + sLine = sLine.Convert( RTL_TEXTENCODING_MS_1252, aCharSet ); + + if ( sLine.GetTokenCount( '\t' ) == 15 ) { + // Skip all wrong filenames + ByteString filename = sLine.GetToken( 1 , '\t' ); + filename = filename.Copy( filename.SearchCharBackward( "\\" )+1 , filename.Len() ); + + if( sFile.Equals( sEmpty ) || ( !sFile.Equals( sEmpty ) && filename.Equals( sFile ) ) ) + { + sTYP = sLine.GetToken( 3, '\t' ); + sGID = sLine.GetToken( 4, '\t' ); + sLID = sLine.GetToken( 5, '\t' ); + sPFO = sLine.GetToken( 7, '\t' ); + sPFO = ByteString("HACK"); + nLANG = sLine.GetToken( 9, '\t' ); + + sTEXT = sLine.GetToken( 10, '\t' ); + // printf("%s\n",sTEXT.GetBuffer()); + // Quote( sTEXT ); + // printf("%s\n",sTEXT.GetBuffer()); + + sQHTEXT = sLine.GetToken( 12, '\t' ); + sTITLE = sLine.GetToken( 13, '\t' ); + + nLANG.EraseLeadingAndTrailingChars(); + +#ifdef MERGE_SOURCE_LANGUAGES + if( true ){ +#else + if ( !nLANG.EqualsIgnoreCaseAscii("en-US") ){ +#endif + InsertEntry( sTYP, sGID, sLID, sPFO, nLANG, sTEXT, sQHTEXT, sTITLE , filename , bCaseSensitive ); + if( nLANG.Len() > 0 ){ + bool bFound = false; + for( unsigned int x = 0; x < aLanguages.size(); x++ ){ + if( aLanguages[ x ].Equals( nLANG ) ) + bFound = true; + } + // Remember read languages for -l all switch + if( !bFound ) aLanguages.push_back( nLANG ); + } + } + } + } + else if ( sLine.GetTokenCount( '\t' ) == 10 ){ + printf("ERROR: File format is obsolete and no longer supported!\n"); + } + } + aInputStream.Close(); +} +/*****************************************************************************/ +MergeDataFile::~MergeDataFile() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +//void MergeDataFile::WriteErrorLog( const ByteString &rFileName ) +/*****************************************************************************/ +//{ +// DEAD +//} + +ByteString MergeDataFile::Dump(){ + ByteString sRet( "MergeDataFile\n" ); + + //sRet.Append( Export::DumpMap( "aLanguageSet" , aLanguageSet ) ); + //sRet.Append( Export::DumpMap( "aLanguages" , aLanguages ) ); + printf("MergeDataFile\n"); + MergeDataHashMap::const_iterator idbg; + for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg ){ + /*sRet.Append( "aMap[" ); + sRet.Append( idbg->first ); + sRet.Append( "]= " ); + sRet.Append( ((MergeData*) (idbg->second))->Dump() ); + sRet.Append("\n");*/ + + printf("aMap[ %s ] = ",idbg->first.GetBuffer()); + ((MergeData*) (idbg->second))->Dump(); + printf("\n"); + } + printf("\n"); + //sRet.Append("\n"); + return sRet; +} + +/*****************************************************************************/ +void MergeDataFile::WriteError( const ByteString &rLine ) +/*****************************************************************************/ +{ + if ( bErrorLog ) { + if ( !aErrLog.IsOpen()) + aErrLog.Open( String( sErrorLog, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); + aErrLog.WriteLine( rLine ); + } + else + fprintf( stderr, "%s\n", rLine.GetBuffer()); +} +std::vector<ByteString> MergeDataFile::GetLanguages(){ + return aLanguages; +} + +/*****************************************************************************/ +MergeData *MergeDataFile::GetMergeData( ResData *pResData , bool bCaseSensitive ) +/*****************************************************************************/ +{ + ByteString sOldG = pResData->sGId; + ByteString sOldL = pResData->sId; + ByteString sGID = pResData->sGId; + ByteString sLID; + if ( !sGID.Len()) + sGID = pResData->sId; + else + sLID = pResData->sId; + pResData->sGId = sGID; + pResData->sId = sLID; + + ByteString sKey = CreateKey( pResData->sResTyp , pResData->sGId , pResData->sId , pResData->sFilename , bCaseSensitive ); + + //printf("DBG: Searching [%s]\n",sKey.GetBuffer()); + if( aMap.find( sKey ) != aMap.end() ){ + pResData->sGId = sOldG; + pResData->sId = sOldL; + //printf("DBG: Found[%s]\n",sKey.GetBuffer()); + return aMap[ sKey ]; + } + pResData->sGId = sOldG; + pResData->sId = sOldL; + //printf("DBG: Found[%s]\n",sKey.GetBuffer()); + return NULL; +} + + +/*****************************************************************************/ +PFormEntrys *MergeDataFile::GetPFormEntrys( ResData *pResData ) +/*****************************************************************************/ +{ + // search for requested PFormEntrys + MergeData *pData = GetMergeData( pResData ); + if ( pData ) + return pData->GetPFormEntrys( pResData ); + return NULL; +} + +/*****************************************************************************/ +PFormEntrys *MergeDataFile::GetPFormEntrysCaseSensitive( ResData *pResData ) +/*****************************************************************************/ +{ + // search for requested PFormEntrys + MergeData *pData = GetMergeData( pResData , true ); + if ( pData ) + return pData->GetPFormEntrys( pResData ); + return NULL; +} +/*****************************************************************************/ +void MergeDataFile::InsertEntry( + const ByteString &rTYP, const ByteString &rGID, + const ByteString &rLID, const ByteString &rPFO, + const ByteString &nLANG, const ByteString &rTEXT, + const ByteString &rQHTEXT, const ByteString &rTITLE , + const ByteString &rFilename , bool bCaseSensitive + ) +/*****************************************************************************/ +{ + MergeData *pData; + BOOL bFound = FALSE; + + // search for MergeData + + ByteString sKey = CreateKey( rTYP , rGID , rLID , rFilename , bCaseSensitive ); + ByteString sKey2; + + if( aMap.find( sKey ) != aMap.end() ){ + pData = aMap[ sKey ]; + }else{ + pData = new MergeData( rTYP, rGID, rLID , rFilename ); + aMap.insert( MergeDataHashMap::value_type( CreateKey( rTYP , rGID , rLID , rFilename , bCaseSensitive ) , pData ) ); + } + + bFound = FALSE; + PFormEntrys *pFEntrys = 0; + + // search for PFormEntrys + + pFEntrys = pData->GetPFObject( rPFO ); + if( !pFEntrys ){ + // create new PFormEntrys, cause no one exists with current properties + pFEntrys = new PFormEntrys( rPFO ); + pData->Insert( rPFO , pFEntrys ); + } + + // finaly insert the cur string + + pFEntrys->InsertEntry( nLANG , rTEXT, rQHTEXT, rTITLE ); + + //printf("DBG: MergeDataFile::Insert[]=( sKey=%s,nLang=%s,rTEXT=%s)\n",sKey2.GetBuffer(),nLANG.GetBuffer(),rTEXT.GetBuffer()); +} +ByteString MergeDataFile::CreateKey( const ByteString& rTYP , const ByteString& rGID , const ByteString& rLID , const ByteString& rFilename , bool bCaseSensitive ){ + + ByteString sKey( rTYP ); + sKey.Append( '-' ); + sKey.Append( rGID ); + sKey.Append( '-' ); + sKey.Append( rLID ); + sKey.Append( '-' ); + sKey.Append( rFilename ); + + if( bCaseSensitive ) return sKey; // officecfg case sensitive identifier + else return sKey.ToUpperAscii(); +} + + diff --git a/transex3/source/src_yy_wrapper.c b/transex3/source/src_yy_wrapper.c new file mode 100644 index 000000000000..d326b9a94e86 --- /dev/null +++ b/transex3/source/src_yy_wrapper.c @@ -0,0 +1,2 @@ +// Helper to suppress warnings in lex generated c code, see #i57362# +#include "src_yy.c" diff --git a/transex3/source/srciter.cxx b/transex3/source/srciter.cxx new file mode 100644 index 000000000000..d2cbb2352570 --- /dev/null +++ b/transex3/source/srciter.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: srciter.cxx,v $ + * $Revision: 1.14 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" + +#include "srciter.hxx" +#include <stdio.h> +#include <tools/fsys.hxx> + +// +// class SourceTreeIterator +// + +/*****************************************************************************/ +SourceTreeIterator::SourceTreeIterator( + const ByteString &rRootDirectory, const ByteString &rVersion , bool bLocal_in ) +/*****************************************************************************/ + : bInExecute( FALSE ) , bLocal( bLocal_in ) +{ + (void) rVersion ; + + if(!bLocal){ + rtl::OUString sRootDirectory( rRootDirectory.GetBuffer() , rRootDirectory.Len() , RTL_TEXTENCODING_UTF8 ); + aRootDirectory = transex::Directory( sRootDirectory ); + } +} + +/*****************************************************************************/ +SourceTreeIterator::~SourceTreeIterator() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +void SourceTreeIterator::ExecuteDirectory( transex::Directory& aDirectory ) +/*****************************************************************************/ +{ + if ( bInExecute ) { + rtl::OUString sDirName = aDirectory.getDirectoryName(); + + static rtl::OUString WCARD1 ( rtl::OUString::createFromAscii( "unxlng" ) ); + static rtl::OUString WCARD2 ( rtl::OUString::createFromAscii( "unxsol" ) ); + static rtl::OUString WCARD3 ( rtl::OUString::createFromAscii( "wntmsc" ) ); + static rtl::OUString WCARD4 ( rtl::OUString::createFromAscii( "common" ) ); + static rtl::OUString WCARD5 ( rtl::OUString::createFromAscii( "unxmac" ) ); + static rtl::OUString WCARD6 ( rtl::OUString::createFromAscii( "unxubt" ) ); + static rtl::OUString WCARD7 ( rtl::OUString::createFromAscii( ".svn" ) ); + + + if( sDirName.indexOf( WCARD1 , 0 ) > -1 || + sDirName.indexOf( WCARD2 , 0 ) > -1 || + sDirName.indexOf( WCARD3 , 0 ) > -1 || + sDirName.indexOf( WCARD4 , 0 ) > -1 || + sDirName.indexOf( WCARD5 , 0 ) > -1 || + sDirName.indexOf( WCARD6 , 0 ) > -1 || + sDirName.indexOf( WCARD7 , 0 ) > -1 + ) return; + //printf("**** %s \n", OUStringToOString( sDirName , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() ); + + rtl::OUString sDirNameTmp = aDirectory.getFullName(); + ByteString sDirNameTmpB( rtl::OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() ); + +#ifdef WNT + sDirNameTmpB.Append( ByteString("\\no_localization") ); +#else + sDirNameTmpB.Append( ByteString("/no_localization") ); +#endif + //printf("**** %s \n", OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() ); + + DirEntry aDE( sDirNameTmpB.GetBuffer() ); + if( aDE.Exists() ) + { + //printf("#### no_localization file found ... skipping"); + return; + } + + aDirectory.setSkipLinks( bSkipLinks ); + aDirectory.readDirectory(); + OnExecuteDirectory( aDirectory.getFullName() ); + if ( aDirectory.getSubDirectories().size() ) + for ( ULONG i=0;i < aDirectory.getSubDirectories().size();i++ ) + ExecuteDirectory( aDirectory.getSubDirectories()[ i ] ); + } +} + +/*****************************************************************************/ +BOOL SourceTreeIterator::StartExecute() +/*****************************************************************************/ +{ + + bInExecute = TRUE; // FIXME + ExecuteDirectory( aRootDirectory ); + + if ( bInExecute ) { // FIXME + bInExecute = FALSE; + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ +void SourceTreeIterator::EndExecute() +/*****************************************************************************/ +{ + bInExecute = FALSE; +} + +/*****************************************************************************/ +void SourceTreeIterator::OnExecuteDirectory( const rtl::OUString &rDirectory ) +/*****************************************************************************/ +{ + fprintf( stdout, "%s\n", rtl::OUStringToOString( rDirectory, RTL_TEXTENCODING_UTF8, rDirectory.getLength() ).getStr() ); +} diff --git a/transex3/source/srclex.l b/transex3/source/srclex.l new file mode 100644 index 000000000000..fef251e47224 --- /dev/null +++ b/transex3/source/srclex.l @@ -0,0 +1,308 @@ + +%{ +/* + * lexer for parsing ressource source files (*.src) + * + */ + + +/* enlarge token buffer to tokenize whole strings */ +#undef YYLMAX +#define YYLMAX 64000 + +/* to enable debug output define LEXDEBUG */ +#define LEXDEBUG 1 +#ifdef LEXDEBUG +#define OUTPUT fprintf +#else +#define OUTPUT(Par1,Par2); +#endif + +/* table of possible token ids */ +#include "tokens.h" +#include <stdlib.h> +#include <stdio.h> + +#if defined __GNUC__ +#pragma GCC system_header +#elif defined __SINPRO_CC +#pragma disable_warn +#elif defined _MSC_VER +#pragma warning(push, 1) +#endif + +/* external functions (C++ code, declared as extren "C" */ +extern int WorkOnTokenSet( int, char* ); +extern int InitExport( char * , char * ); +extern int Parse( int nTyp, char *pTokenText ); +extern int EndExport(); +extern int SetError(); +extern int GetError(); +extern char *GetOutputFile( int argc, char* argv[]); +extern FILE *GetNextFile(); +extern int isQuiet(); +extern void Close(); +extern char* getFilename(); + +/* forwards */ +void YYWarning(); +%} + +%p 24000 +%e 1200 +%n 500 + +%% + +^[\t ]*"#pragma".* { + WorkOnTokenSet( PRAGMA, yytext ); +} + +^[ \t]*\n { + WorkOnTokenSet( EMPTYLINE, yytext ); +} + +[\t ]+ | +^[\t ]*"#include".* | +^[\t ]*"#undef".* | +"//".* | +";" | +"<" | +">" | +\n { + WorkOnTokenSet( IGNOREDTOKENS, yytext ); +} +"/*" { + char c1 = 0, c2 = input(); + char pChar[2]; + pChar[1] = 0x00; + pChar[0] = c2; + + WorkOnTokenSet( COMMEND, yytext ); + WorkOnTokenSet( COMMEND, pChar ); + for(;;) { + if ( c2 == EOF ) + break; + if ( c1 == '*' && c2 == '/' ) + break; + c1 = c2; + c2 = input(); + pChar[0] = c2; + WorkOnTokenSet( COMMEND, pChar ); + } +} + +^[\t ]*"#ifndef".+$ | +^[\t ]*"#ifdef".+$ | +^[\t ]*"#if".+$ | +^[\t ]*"#elif".*$ | +^[\t ]*"#else".*$ | +^[\t ]*"#endif".*$ { + WorkOnTokenSet( CONDITION, yytext ); +} + +[a-zA-Z]+[\t ]+[^={\n]+[\t ] { +/* defined Res */ + WorkOnTokenSet( DEFINEDRES, yytext ); +} + +[a-zA-Z]+[ \t]+[^={;\n]+\n[ \t]*"#".*\n[ \t]*"{" | +[a-zA-Z]+[ \t]+[^={;\n]+\n?([ \t]*"//".*\n)*[ \t]*"{" { +/* RESSOURCE // String TTT_XX ... */ + WorkOnTokenSet( RESSOURCE, yytext ); +} + +^[\t ]*[a-zA-Z_]+[\t ]*"\\"?[\t ]*\n?[ \t]*"{"[\t ]*"\\"? { +/* SMALRESSOURCE // String ... */ + WorkOnTokenSet( SMALRESSOURCE, yytext ); +} + +[\t ]*[a-zA-Z0-9_]+[ \t]*("["[ \t]*[a-zA-Z0-9_\-]+[ \t]*"]"[ \t]*)?=[ \t]*L?\".*\".*\n? { +/* TEXTLINE // TextTyp = "A Text" */ + WorkOnTokenSet( TEXTLINE, yytext ); +} + +[\t ]*[a-zA-Z0-9_]+[ \t]*("["[ \t]*[a-zA-Z0-9_\-]+[ \t]*"]"[ \t]*)?(\n[ \t]*)?=([ \t]*\n)?(([a-zA-Z0-9_]+)|(\".*\")|([ \t\n]*))*\".*\"(([a-zA-Z0-9_]+)|(\".*\")|([ \t\n]*))*; { +/* LONGTEXTLINE // TextTyp = "A Text" HHH_XXX "A Text" ZZZ_TTT ... */ + WorkOnTokenSet( LONGTEXTLINE, yytext ); +} + +\".*\" { +/* TEXT // "A Text" */ + WorkOnTokenSet( TEXT, yytext ); +} + +"{"[ \t]*\\? { +/* LEVELUP */ + WorkOnTokenSet( LEVELUP, yytext ); +} + +"}"[ \t]*;([ \t]*\\)? { +/* LEVELDOWN */ + WorkOnTokenSet( LEVELDOWN, yytext ); +} + +[a-zA-Z0-9_]+[ \t]*"="[ \t]*"MAP_APPFONT"[ \t]*"(".+")".* { +/* APPFONTMAPPING Typ = MAP_APPFONT( ... ) */ + WorkOnTokenSet( APPFONTMAPPING, yytext ); +} + +[ \t]*[a-zA-Z0-9_]+[ \t]*=[ \t]*[0123456789]{1,5}[ \t]*";"?\\? { +/* TEXTREFID // TextTyp = 12345 */ + WorkOnTokenSet( TEXTREFID, yytext ); +} + +[a-zA-Z0-9_]+[ \t]*"="[\t ]*([ \t]*"//".*\n)*.* | +[a-zA-Z0-9_]+[ \t]*"=".* { +/* ASSIGNMENT Typ = ... */ + WorkOnTokenSet( ASSIGNMENT, yytext ); +} + + + +[a-zA-Z0-9_]+[ \t]*("["[ \t]*[a-zA-Z0-9_\-]+[ \t]*"]"[ \t]*)?"="[ \t]*(\\[ \t]*)?\n?[ \t]*"{"[ \t]*(\\[ \t]*)?\n?[ \t]*"<" { +/* LISTASSIGNMENT Typ [ ... ] = ... */ + WorkOnTokenSet( LISTASSIGNMENT, yytext ); +} + +"StringList"+[ \t]*("["[ \t]*[a-zA-Z0-9_\-]+[ \t]*"]"[ \t]*)?"="[ \t]*(\\[ \t]*)?\n?[ \t]*"{"[ \t]*(\\[ \t]*)?\n?[ \t]* { +/* LISTASSIGNMENT Typ [ ... ] = ... */ + WorkOnTokenSet( LISTASSIGNMENT, yytext ); +} + +"UIEntries"[ \t]*("["[ \t]*[a-zA-Z0-9_\-]+[ \t]*"]"[ \t]*)?"="[ \t]*(\\[ \t]*)?\n?[ \t]*"{" { +/* UIENTRIES */ + WorkOnTokenSet( UIENTRIES, yytext ); +} + +"<"?[ \t]*L?\".*\".*">" { +/* LISTTEXT */ + WorkOnTokenSet( LISTTEXT, yytext ); +} + +[ \t]*"#define"[ \t]+[a-zA-Z0-9_]+.*"\\" { +/* RSCDEFINE #define ... */ + WorkOnTokenSet( RSCDEFINE, yytext ); +} + +[ \t]*"#define"[ \t]+[a-zA-Z0-9_]+.+ { +/* #define ... */ + WorkOnTokenSet( NORMDEFINE, yytext ); +} + +"\\" { +/* RSCDEFINELEND */ + WorkOnTokenSet( RSCDEFINELEND, yytext ); +} + +[a-zA-Z0-9_]+[ \t]*; { +/* allowed other tokens like "49 ;" or "SFX_... ;" */ + WorkOnTokenSet( ANYTOKEN, yytext ); +} + +. { + WorkOnTokenSet( UNKNOWNCHAR, yytext ); +/* YYWarning( "Unknown Char" ); */ +} + +"{"?[ \t]*\".*\"[ \t]*";"[ \t]*"}" { +/* _LISTTEXT */ + WorkOnTokenSet( _LISTTEXT, yytext ); +} + +%% + +/*****************************************************************************/ +int yywrap(void) +/*****************************************************************************/ +{ + FILE *pFile; + pFile = GetNextFile(); + if ( pFile ) { + yyin = pFile; + yylineno = 0; + return 0; + } + + /* end of input reached */ + return 1; +} + +/*****************************************************************************/ +void YYWarning( char *s ) +/*****************************************************************************/ +{ + /* write warning to stderr */ + fprintf( stderr, "Warning: \"%s\" in line %d: \"%s\"\n", s, yylineno, yytext ); +} + +/*****************************************************************************/ +void yyerror( char *s ) +/*****************************************************************************/ +{ + /* write error to stderr */ + fprintf( stderr, "Error: \"%s\" in line %d: \"%s\"\n", s, yylineno, yytext ); + SetError(); +} + +/*****************************************************************************/ +int +#ifdef WNT +_cdecl +#endif +main( int argc, char* argv[]) +/*****************************************************************************/ +{ + /* error level */ + int nRetValue = 0; + char *pOutput; + FILE *pFile; + + pOutput = GetOutputFile( argc, argv ); + if( !isQuiet() ){ + fprintf( stdout, "\nTransEx 3.1 Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.\n" ); + fprintf( stdout, "========================================================================\n" ); + } + + if ( !pOutput ) { + fprintf( stdout, "Syntax:TRANSEX[-p Prj][-r PrjRoot]-i FileIn...[-o FileOut][-m DataBase][-e][-b][-u][-L l1,l2,...]\n" ); + fprintf( stdout, " Prj: Project\n" ); + fprintf( stdout, " PrjRoot: Path to project root (..\\.. etc.)\n" ); + fprintf( stdout, " FileIn: Source files (*.src)\n" ); + fprintf( stdout, " FileOut: Destination file (*.*)\n" ); + fprintf( stdout, " DataBase: Mergedata (*.sdf)\n" ); + fprintf( stdout, " -QQ: quiet output\n" ); + fprintf( stdout, " -e: Disable writing errorlog\n" ); + fprintf( stdout, " -b: Break when Token \"HelpText\" found in source\n" ); + fprintf( stdout, " -u: [english] and [german] are allowed, Id is Taken from DataBase \n" ); + fprintf( stdout, " -NOUTF8: disable UTF8 as language independent encoding\n" ); + fprintf( stdout, " -L: Restrict the handled languages. l1,l2,... are elements of (de,en-US...)\n" ); + fprintf( stdout, " A fallback language can be defined like this: l1=f1.\n" ); + fprintf( stdout, " f1, f2,... are also elements of (de,en-US...)\n" ); + fprintf( stdout, " Example: -L de,es=en-US\n" ); + fprintf( stdout, " Restriction to de and es, en-US will be fallback for es\n" ); + return 1; + } + + InitExport( pOutput , getFilename() ); + pFile = GetNextFile(); + if ( !pFile ) + return 1; + + yyin = pFile; + + /* create global instance of class Export */ + + /* start parser */ + yylex(); + Close(); + + /* get error info. and end export */ + nRetValue = GetError(); + EndExport(); + + if( !isQuiet() ) fprintf( stdout, "\n===================================\n\n" ); + + /* return error level */ + return nRetValue; +} diff --git a/transex3/source/tagtest.cxx b/transex3/source/tagtest.cxx new file mode 100644 index 000000000000..89c1ecf15488 --- /dev/null +++ b/transex3/source/tagtest.cxx @@ -0,0 +1,1577 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tagtest.cxx,v $ + * $Revision: 1.20 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <tools/string.hxx> +#include "tagtest.hxx" + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +#include "gsicheck.hxx" + +#define HAS_FLAG( nFlags, nFlag ) ( ( nFlags & nFlag ) != 0 ) +#define SET_FLAG( nFlags, nFlag ) ( nFlags |= nFlag ) +#define RESET_FLAG( nFlags, nFlag ) ( nFlags &= ~nFlag ) // ~ = Bitweises NOT + + + +TokenInfo::TokenInfo( TokenId pnId, USHORT nP, String paStr, ParserMessageList &rErrorList ) +: bClosed(FALSE) +, bCloseTag(FALSE) +, bIsBroken(FALSE) +, bHasBeenFixed(FALSE) +, bDone(FALSE) +, aTokenString( paStr ) +, nId( pnId ) +, nPos(nP) +{ + if ( nId == TAG_COMMONSTART || nId == TAG_COMMONEND ) + SplitTag( rErrorList ); +} + +enum tagcheck { TC_START, TC_HAS_TAG_NAME, TC_HAS_PROP_NAME_EQ, TC_HAS_PROP_NAME_EQ_SP, TC_HAS_PROP_NAME_SP, TC_INSIDE_STRING, TC_PROP_FINISHED, TC_CLOSED, TC_CLOSED_SPACE, TC_CLOSETAG, TC_CLOSETAG_HAS_TAG_NAME, TC_FINISHED, TC_ERROR }; + +/* + \< link href = \"text\" name = \"C\" \> +START ' ' -> HAS_TAG_NAME +START '/' -> CLOSED +START '/' -> CLOSETAG - no Portion (starting with /) +START '>' -> FINISHED +HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ +HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP +HAS_TAG_NAME '/' -> CLOSED +HAS_TAG_NAME '>' -> FINISHED +HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ +HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP +HAS_PROP_NAME_EQ '"' -> INSIDE_STRING +HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING +INSIDE_STRING ' ' -> INSIDE_STRING +INSIDE_STRING '=' -> INSIDE_STRING +INSIDE_STRING '>' -> INSIDE_STRING +INSIDE_STRING '"' -> PROP_FINISHED +PROP_FINISHED ' ' -> HAS_TAG_NAME +PROP_FINISHED '/' -> CLOSED +PROP_FINISHED '>' -> FINISHED +CLOSED ' ' -> CLOSED_SPACE +CLOSED '>' -> FINISHED +CLOSED_SPACE '>' -> FINISHED + +CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME +CLOSETAG '>' -> FINISHED +CLOSETAG_HAS_TAG_NAME '>' -> FINISHED + +*/ +void TokenInfo::SplitTag( ParserMessageList &rErrorList ) +{ + USHORT nLastPos = 2; // skip initial \< + USHORT nCheckPos = nLastPos; + String aDelims( String::CreateFromAscii( " \\=>/" ) ); + String aPortion; + String aValue; // store the value of a property + ByteString aName; // store the name of a property/tag + BOOL bCheckName = FALSE; + BOOL bCheckEmpty = FALSE; + sal_Unicode cDelim; + tagcheck aState = TC_START; + + // skip blanks + while ( nLastPos < aTokenString.Len() && aTokenString.GetChar( nLastPos ) == ' ') + nLastPos++; + + nCheckPos = aTokenString.SearchChar( aDelims.GetBuffer(), nLastPos ); + while ( nCheckPos != STRING_NOTFOUND && !( aState == TC_FINISHED || aState == TC_ERROR ) ) + { + aPortion = aTokenString.Copy( nLastPos, nCheckPos-nLastPos ); + + if ( aTokenString.GetChar( nCheckPos ) == '\\' ) + nCheckPos++; + + cDelim = aTokenString.GetChar( nCheckPos ); + nCheckPos++; + + switch ( aState ) + { +// START ' ' -> HAS_TAG_NAME +// START '/' -> CLOSED +// START '>' -> FINISHED + case TC_START: + aTagName = aPortion; + switch ( cDelim ) + { + case ' ': aState = TC_HAS_TAG_NAME; + bCheckName = TRUE; + break; + case '/': + { + if ( aPortion.Len() == 0 ) + { + aState = TC_CLOSETAG; + } + else + { + aState = TC_CLOSED; + bCheckName = TRUE; + } + } + break; + case '>': aState = TC_FINISHED; + bCheckName = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ +// HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP +// HAS_TAG_NAME '/' -> CLOSED +// HAS_TAG_NAME '>' -> FINISHED + case TC_HAS_TAG_NAME: + switch ( cDelim ) + { + case '=': aState = TC_HAS_PROP_NAME_EQ; + bCheckName = TRUE; + break; + case ' ': aState = TC_HAS_PROP_NAME_SP; + bCheckName = TRUE; + break; + case '/': aState = TC_CLOSED; + bCheckEmpty = TRUE; + break; + case '>': aState = TC_FINISHED; + bCheckEmpty = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ + case TC_HAS_PROP_NAME_SP: + switch ( cDelim ) + { + case '=': aState = TC_HAS_PROP_NAME_EQ; + bCheckEmpty = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP +// HAS_PROP_NAME_EQ '"' -> INSIDE_STRING + case TC_HAS_PROP_NAME_EQ: + switch ( cDelim ) + { + case ' ': aState = TC_HAS_PROP_NAME_EQ_SP; + bCheckEmpty = TRUE; + break; + case '\"': aState = TC_INSIDE_STRING; + bCheckEmpty = TRUE; + aValue.Erase(); + break; + default: aState = TC_ERROR; + } + break; + +// HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING + case TC_HAS_PROP_NAME_EQ_SP: + switch ( cDelim ) + { + case '\"': aState = TC_INSIDE_STRING; + bCheckEmpty = TRUE; + aValue.Erase(); + break; + default: aState = TC_ERROR; + } + break; + +// INSIDE_STRING * -> INSIDE_STRING +// INSIDE_STRING '"' -> PROP_FINISHED + case TC_INSIDE_STRING: + switch ( cDelim ) + { + case '\"': + { + aState = TC_PROP_FINISHED; + aValue += aPortion; + if ( aProperties.find( aName ) == aProperties.end() ) + { + if ( !IsPropertyValueValid( aName, aValue ) ) + { + rErrorList.AddError( 25, ByteString("Property '").Append(aName).Append("' has invalid value '").Append(ByteString( aValue, RTL_TEXTENCODING_UTF8 )).Append("' "), *this ); + bIsBroken = TRUE; + } + aProperties[ aName ] = aValue; + } + else + { + rErrorList.AddError( 25, ByteString("Property '").Append(aName).Append("' defined twice "), *this ); + bIsBroken = TRUE; + } + } + break; + default: + { + aState = TC_INSIDE_STRING; + aValue += aPortion; + aValue += cDelim; + } + } + break; + +// PROP_FINISHED ' ' -> HAS_TAG_NAME +// PROP_FINISHED '/' -> CLOSED +// PROP_FINISHED '>' -> FINISHED + case TC_PROP_FINISHED: + switch ( cDelim ) + { + case ' ': aState = TC_HAS_TAG_NAME; + bCheckEmpty = TRUE; + break; + case '/': aState = TC_CLOSED; + bCheckEmpty = TRUE; + break; + case '>': aState = TC_FINISHED; + bCheckEmpty = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// CLOSED ' ' -> CLOSED_SPACE +// CLOSED '>' -> FINISHED + case TC_CLOSED: + switch ( cDelim ) + { + case ' ': aState = TC_CLOSED_SPACE; + bCheckEmpty = TRUE; + bClosed = TRUE; + break; + case '>': aState = TC_FINISHED; + bCheckEmpty = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// CLOSED_SPACE '>' -> FINISHED + case TC_CLOSED_SPACE: + switch ( cDelim ) + { + case '>': aState = TC_FINISHED; + bCheckEmpty = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME +// CLOSETAG '>' -> FINISHED + case TC_CLOSETAG: + bCloseTag = TRUE; + switch ( cDelim ) + { + case ' ': aState = TC_CLOSETAG_HAS_TAG_NAME; + aTagName = aPortion; + bCheckName = TRUE; + break; + case '>': aState = TC_FINISHED; + aTagName = aPortion; + bCheckName = TRUE; + break; + default: aState = TC_ERROR; + } + break; + +// CLOSETAG_HAS_TAG_NAME '>' -> FINISHED + case TC_CLOSETAG_HAS_TAG_NAME: + switch ( cDelim ) + { + case '>': aState = TC_FINISHED; + bCheckEmpty = TRUE; + break; + default: aState = TC_ERROR; + } + break; + + + default: rErrorList.AddError( 99, "Internal error Parsing Tag ", *this ); + bIsBroken = TRUE; + + } + + if ( bCheckName ) + { + if ( aPortion.Len() == 0 ) + { + rErrorList.AddError( 25, "Tag/Property name missing ", *this ); + bIsBroken = TRUE; + } + else + { + aName = ByteString( aPortion, RTL_TEXTENCODING_UTF8 ); + // "a-zA-Z_-.0-9" + xub_StrLen nCount; + BOOL bBroken = FALSE; + const sal_Char* aBuf = aName.GetBuffer(); + for ( nCount = 0 ; !bBroken && nCount < aName.Len() ; nCount++ ) + { + bBroken = ! ( ( aBuf[nCount] >= 'a' && aBuf[nCount] <= 'z' ) + ||( aBuf[nCount] >= 'A' && aBuf[nCount] <= 'Z' ) + ||( aBuf[nCount] >= '0' && aBuf[nCount] <= '9' ) + ||( aBuf[nCount] == '_' ) + ||( aBuf[nCount] == '-' ) + ||( aBuf[nCount] == '.' ) + ); + } + + if ( bBroken ) + { + rErrorList.AddError( 25, "Found illegal character in Tag/Property name ", *this ); + bIsBroken = TRUE; + } + } + + bCheckName = FALSE; + } + + if ( bCheckEmpty ) + { + if ( aPortion.Len() ) + { + rErrorList.AddError( 25, ByteString("Found displaced characters '").Append(ByteString( aPortion, RTL_TEXTENCODING_UTF8 )).Append("' in Tag "), *this ); + bIsBroken = TRUE; + } + bCheckEmpty = FALSE; + } + + + nLastPos = nCheckPos; + + // skip further blanks + if ( cDelim == ' ' && aState != TC_INSIDE_STRING ) + while ( nLastPos < aTokenString.Len() && aTokenString.GetChar( nLastPos ) == ' ') + nLastPos++; + + nCheckPos = aTokenString.SearchChar( aDelims.GetBuffer(), nLastPos ); + } + if ( aState != TC_FINISHED ) + { + rErrorList.AddError( 25, "Parsing error in Tag ", *this ); + bIsBroken = TRUE; + } +} + +BOOL TokenInfo::IsPropertyRelevant( const ByteString &aName, const String &aValue ) const +{ + if ( aTagName.EqualsAscii( "alt" ) && aName.Equals( "xml-lang" ) ) + return FALSE; + if ( aTagName.EqualsAscii( "ahelp" ) && aName.Equals( "visibility" ) && aValue.EqualsAscii("visible") ) + return FALSE; + if ( aTagName.EqualsAscii( "image" ) && (aName.Equals( "width" ) || aName.Equals( "height" )) ) + return FALSE; + + return TRUE; +} + +BOOL TokenInfo::IsPropertyValueValid( const ByteString &aName, const String &aValue ) const +{ +/* removed due to i56740 + if ( aTagName.EqualsAscii( "switchinline" ) && aName.Equals( "select" ) ) + { + return aValue.EqualsAscii("sys") || + aValue.EqualsAscii("appl") || + aValue.EqualsAscii("distrib"); + } */ + if ( aTagName.EqualsAscii( "caseinline" ) && aName.Equals( "select" ) ) + { + return /*!aValue.EqualsAscii("OS2") && removed due to i56740 */ + !aValue.EqualsAscii(""); + } + + // we don't know any better so we assume it to be OK + return TRUE; +} + +BOOL TokenInfo::IsPropertyInvariant( const ByteString &aName, const String &aValue ) const +{ + if ( aTagName.EqualsAscii( "link" ) && aName.Equals( "name" ) ) + return FALSE; + if ( aTagName.EqualsAscii( "link" ) && aName.Equals( "href" ) ) + { // check for external reference + if ( aValue.Copy( 0, 5 ).EqualsIgnoreCaseAscii( "http:" ) + || aValue.Copy( 0, 6 ).EqualsIgnoreCaseAscii( "https:" ) + || aValue.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "ftp:" ) ) + return FALSE; + else + return TRUE; + } + return TRUE; +} + +BOOL TokenInfo::IsPropertyFixable( const ByteString &aName ) const +{ + // name everything that is allowed to be fixed automatically here + if ( (aTagName.EqualsAscii( "ahelp" ) && aName.Equals( "hid" )) + || (aTagName.EqualsAscii( "link" ) && aName.Equals( "href" )) + || (aTagName.EqualsAscii( "alt" ) && aName.Equals( "id" )) + || (aTagName.EqualsAscii( "variable" ) && aName.Equals( "id" )) + || (aTagName.EqualsAscii( "image" ) && aName.Equals( "src" )) + || (aTagName.EqualsAscii( "image" ) && aName.Equals( "id" ) )) + return TRUE; + return FALSE; +} + +BOOL TokenInfo::MatchesTranslation( TokenInfo& rInfo, BOOL bGenErrors, ParserMessageList &rErrorList, BOOL bFixTags ) const +{ + // check if tags are equal + // check if all existing properties are in the translation as well and + // wether they have a matching content (the same in most cases) + + if ( nId != rInfo.nId ) + return FALSE; + + if ( !aTagName.Equals( rInfo.aTagName ) ) + return FALSE; + + // If one of the tags has formating errors already it does make no sense to check here, so return right away + if ( bGenErrors && ( bIsBroken || rInfo.bIsBroken ) ) + return TRUE; + + StringHashMap::const_iterator iProp; + for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp ) + { + if ( rInfo.aProperties.find( iProp->first ) != rInfo.aProperties.end() ) + { + if ( IsPropertyRelevant( iProp->first, iProp->second ) || IsPropertyRelevant( iProp->first, rInfo.aProperties.find( iProp->first )->second ) ) + { + if ( IsPropertyInvariant( iProp->first, iProp->second ) ) + { + if ( !rInfo.aProperties.find( iProp->first )->second.Equals( iProp->second ) ) + { + if ( bGenErrors ) + { + if ( bFixTags && IsPropertyFixable( iProp->first ) ) + { + rInfo.aProperties.find( iProp->first )->second = iProp->second; + rInfo.SetHasBeenFixed(); + rErrorList.AddWarning( 25, ByteString("Property '").Append(iProp->first).Append("': FIXED different value in Translation "), *this ); + } + else + rErrorList.AddError( 25, ByteString("Property '").Append(iProp->first).Append("': value different in Translation "), *this ); + } + else return FALSE; + } + } + } + } + else + { + if ( IsPropertyRelevant( iProp->first, iProp->second ) ) + { + if ( bGenErrors ) + rErrorList.AddError( 25, ByteString("Property '").Append(iProp->first).Append("' missing in Translation "), *this ); + else return FALSE; + } + } + } + for( iProp = rInfo.aProperties.begin() ; iProp != rInfo.aProperties.end(); ++iProp ) + { + if ( aProperties.find( iProp->first ) == aProperties.end() ) + { + if ( IsPropertyRelevant( iProp->first, iProp->second ) ) + { + if ( bGenErrors ) + rErrorList.AddError( 25, ByteString("Extra Property '").Append(iProp->first).Append("' in Translation "), rInfo ); + else return FALSE; + } + } + } + + // if we reach here eather + // the tags match completely or + // the tags match but not the properties and we generated errors for that + return TRUE; +} + +String TokenInfo::GetTagName() const +{ + return aTagName; +} + +String TokenInfo::MakeTag() const +{ + String aRet; + aRet.AppendAscii("\\<"); + if ( bCloseTag ) + aRet.AppendAscii("/"); + aRet.Append( GetTagName() ); + StringHashMap::const_iterator iProp; + + for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp ) + { + aRet.AppendAscii(" "); + aRet.Append( String( iProp->first, RTL_TEXTENCODING_UTF8 ) ); + aRet.AppendAscii("=\\\""); + aRet.Append( iProp->second ); + aRet.AppendAscii("\\\""); + } + if ( bClosed ) + aRet.AppendAscii("/"); + aRet.AppendAscii("\\>"); + return aRet; +} + + +void ParserMessageList::AddError( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag ) +{ + Insert( new ParserError( nErrorNr, aErrorText, rTag ), LIST_APPEND ); +} + +void ParserMessageList::AddWarning( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag ) +{ + Insert( new ParserWarning( nErrorNr, aErrorText, rTag ), LIST_APPEND ); +} + +BOOL ParserMessageList::HasErrors() +{ + USHORT i; + for ( i=0 ; i < Count() ; i++ ) + if ( GetObject( i )->IsError() ) + return TRUE; + return FALSE; +} + +struct Tag +{ + String GetName() const { return String::CreateFromAscii( pName ); }; + const char* pName; + TokenId nTag; +}; + + +static const Tag aKnownTags[] = +{ +/* commenting oldstyle tags +// { "<#GROUP_FORMAT>", TAG_GROUP_FORMAT }, + { "<#BOLD>", TAG_BOLDON }, + { "<#/BOLD>", TAG_BOLDOFF }, + { "<#ITALIC>", TAG_ITALICON }, + { "<#/ITALIC>", TAG_ITALICOFF }, + { "<#UNDER>", TAG_UNDERLINEON }, + { "<#/UNDER>", TAG_UNDERLINEOFF }, + +// { "<#GROUP_NOTALLOWED>", TAG_GROUP_NOTALLOWED }, + { "<#HELPID>", TAG_HELPID }, + { "<#MODIFY>", TAG_MODIFY }, + { "<#REFNR>", TAG_REFNR }, + +// { "<#GROUP_STRUCTURE>", TAG_GROUP_STRUCTURE }, + { "<#NAME>", TAG_NAME }, + { "<#HREF>", TAG_HREF }, + { "<#AVIS>", TAG_AVIS }, + { "<#AHID>", TAG_AHID }, + { "<#AEND>", TAG_AEND }, + + { "<#TITEL>", TAG_TITEL }, + { "<#KEY>", TAG_KEY }, + { "<#INDEX>", TAG_INDEX }, + + { "<#REFSTART>", TAG_REFSTART }, + + { "<#GRAPHIC>", TAG_GRAPHIC }, + { "<#NEXTVERSION>", TAG_NEXTVERSION }, + + // { "<#GROUP_SYSSWITCH>", TAG_GROUP_SYSSWITCH }, + { "<#WIN>", TAG_WIN }, + { "<#UNIX>", TAG_UNIX }, + { "<#MAC>", TAG_MAC }, + { "<#OS2>", TAG_OS2 }, + +// { "<#GROUP_PROGSWITCH>", TAG_GROUP_PROGSWITCH }, + { "<#WRITER>", TAG_WRITER }, + { "<#CALC>", TAG_CALC }, + { "<#DRAW>", TAG_DRAW }, + { "<#IMPRESS>", TAG_IMPRESS }, + { "<#SCHEDULE>", TAG_SCHEDULE }, + { "<#IMAGE>", TAG_IMAGE }, + { "<#MATH>", TAG_MATH }, + { "<#CHART>", TAG_CHART }, + { "<#OFFICE>", TAG_OFFICE }, + */ +// { "<#TAG_GROUP_META>", TAG_GROUP_META }, + { "$[officefullname]", TAG_OFFICEFULLNAME }, + { "$[officename]", TAG_OFFICENAME }, + { "$[officepath]", TAG_OFFICEPATH }, + { "$[officeversion]", TAG_OFFICEVERSION }, + { "$[portalname]", TAG_PORTALNAME }, + { "$[portalfullname]", TAG_PORTALFULLNAME }, + { "$[portalpath]", TAG_PORTALPATH }, + { "$[portalversion]", TAG_PORTALVERSION }, + { "$[portalshortname]", TAG_PORTALSHORTNAME }, +/* commenting oldstyle tags +// { "<#TAG_GROUP_SINGLE>", TAG_GROUP_SINGLE }, + { "<#REFINSERT>", TAG_REFINSERT }, + +// { "<#GROUP_MULTI>", TAG_GROUP_MULTI }, + { "<#END>", TAG_END }, + { "<#ELSE>", TAG_ELSE }, + { "<#VERSIONEND>", TAG_VERSIONEND }, + { "<#ENDGRAPHIC>", TAG_ENDGRAPHIC },*/ + { "<Common Tag>", TAG_COMMONSTART }, + { "</Common Tag>", TAG_COMMONEND }, + + { "<no more tags>", TAG_NOMORETAGS }, + { "", TAG_UNKNOWN_TAG }, +}; + + +SimpleParser::SimpleParser() +: nPos( 0 ) +, aNextTag( TAG_NOMORETAGS, TOK_INVALIDPOS ) +{ +} + +void SimpleParser::Parse( String PaSource ) +{ + aSource = PaSource; + nPos = 0; + aLastToken.Erase(); + aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS ); + aTokenList.Clear(); +}; + +TokenInfo SimpleParser::GetNextToken( ParserMessageList &rErrorList ) +{ + TokenInfo aResult; + USHORT nTokenStartPos = 0; + if ( aNextTag.nId != TAG_NOMORETAGS ) + { + aResult = aNextTag; + aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS ); + } + else + { + aLastToken = GetNextTokenString( rErrorList, nTokenStartPos ); + if ( aLastToken.Len() == 0 ) + return TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS ); + + // do we have a \< ... \> style tag? + if ( aLastToken.Copy(0,2).EqualsAscii( "\\<" ) ) + { + // check for paired \" \" + bool bEven = true; + USHORT nQuotePos = 0; + USHORT nQuotedQuotesPos = aLastToken.SearchAscii( "\\\"" ); + USHORT nQuotedBackPos = aLastToken.SearchAscii( "\\\\" ); // this is only to kick out quoted backslashes + while ( nQuotedQuotesPos != STRING_NOTFOUND ) + { + if ( nQuotedBackPos <= nQuotedQuotesPos ) + nQuotePos = nQuotedBackPos+2; + else + { + nQuotePos = nQuotedQuotesPos+2; + bEven = !bEven; + } + nQuotedQuotesPos = aLastToken.SearchAscii( "\\\"", nQuotePos ); + nQuotedBackPos = aLastToken.SearchAscii( "\\\\", nQuotePos ); // this is only to kick out quoted backslashes + } + if ( !bEven ) + { + rErrorList.AddError( 24, "Missing quotes ( \\\" ) in Tag", TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken ) ); + } + + // check if we have an end-tag or a start-tag + USHORT nNonBlankStartPos,nNonBlankEndPos; + nNonBlankStartPos = 2; + while ( aLastToken.GetChar(nNonBlankStartPos) == ' ' ) + nNonBlankStartPos++; + if ( aLastToken.GetChar(nNonBlankStartPos) == '/' ) + aResult = TokenInfo( TAG_COMMONEND, nTokenStartPos, aLastToken, rErrorList ); + else + { + aResult = TokenInfo( TAG_COMMONSTART, nTokenStartPos, aLastToken, rErrorList ); + nNonBlankEndPos = aLastToken.Len() -3; + while ( aLastToken.GetChar(nNonBlankEndPos) == ' ' ) + nNonBlankEndPos--; + if ( aLastToken.GetChar( nNonBlankEndPos ) == '/' ) + aNextTag = TokenInfo( TAG_COMMONEND, nTokenStartPos, String::CreateFromAscii("\\</").Append(aResult.GetTagName()).AppendAscii("\\>"), rErrorList ); + } + } + else + { + USHORT i = 0; + while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG && + aLastToken != aKnownTags[i].GetName() ) + i++; + aResult = TokenInfo( aKnownTags[i].nTag, nTokenStartPos ); + } + } + + if ( aResult.nId == TAG_UNKNOWN_TAG ) + aResult = TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken ); + aTokenList.Insert( aResult, LIST_APPEND ); + return aResult; +} + +String SimpleParser::GetNextTokenString( ParserMessageList &rErrorList, USHORT &rTagStartPos ) +{ +// USHORT nStyle1StartPos = aSource.SearchAscii( "<#", nPos ); + USHORT nStyle2StartPos = aSource.SearchAscii( "$[", nPos ); + USHORT nStyle3StartPos = aSource.SearchAscii( "\\<", nPos ); + USHORT nStyle4StartPos = aSource.SearchAscii( "\\\\", nPos ); // this is only to kick out quoted backslashes + + rTagStartPos = 0; + +/* removing since a \<... is not likely + // check if the tag starts with a letter to avoid things like <> <= ... > + while ( STRING_NOTFOUND != nStyle3StartPos && !( aSource.Copy( nStyle3StartPos+2, 1 ).IsAlphaAscii() || aSource.GetChar( nStyle3StartPos+2 ) == '/' ) ) + nStyle3StartPos = aSource.SearchAscii( "\\<", nStyle3StartPos+1 ); +*/ + if ( STRING_NOTFOUND == nStyle2StartPos && STRING_NOTFOUND == nStyle3StartPos ) + return String(); // no more tokens + + if ( nStyle4StartPos < nStyle2StartPos && nStyle4StartPos <= nStyle3StartPos ) // <= to make sure \\ is always handled first + { // Skip quoted Backslash + nPos = nStyle4StartPos +2; + return GetNextTokenString( rErrorList, rTagStartPos ); + } + +/* if ( nStyle1StartPos < nStyle2StartPos && nStyle1StartPos <= nStyle3StartPos ) // <= to make sure our spechial tags are recognized before all others + { // test for <# ... > style tokens + USHORT nEndPos = aSource.SearchAscii( ">", nStyle1StartPos ); + if ( nEndPos == STRING_NOTFOUND ) + { // Token is incomplete. Skip start and search for better ones + nPos = nStyle1StartPos +2; + return GetNextTokenString( rErrorList, rTagStartPos ); + } + nPos = nEndPos; + rTagStartPos = nStyle1StartPos; + return aSource.Copy( nStyle1StartPos, nEndPos-nStyle1StartPos +1 ).ToUpperAscii(); + } + else*/ if ( nStyle2StartPos < nStyle3StartPos ) + { // test for $[ ... ] style tokens + USHORT nEndPos = aSource.SearchAscii( "]", nStyle2StartPos); + if ( nEndPos == STRING_NOTFOUND ) + { // Token is incomplete. Skip start and search for better ones + nPos = nStyle2StartPos +2; + return GetNextTokenString( rErrorList, rTagStartPos ); + } + nPos = nEndPos; + rTagStartPos = nStyle2StartPos; + return aSource.Copy( nStyle2StartPos, nEndPos-nStyle2StartPos +1 ); + } + else + { // test for \< ... \> style tokens + USHORT nEndPos = aSource.SearchAscii( "\\>", nStyle3StartPos); + USHORT nQuotedBackPos = aSource.SearchAscii( "\\\\", nStyle3StartPos ); // this is only to kick out quoted backslashes + while ( nQuotedBackPos <= nEndPos && nQuotedBackPos != STRING_NOTFOUND ) + { + nEndPos = aSource.SearchAscii( "\\>", nQuotedBackPos +2); + nQuotedBackPos = aSource.SearchAscii( "\\\\", nQuotedBackPos +2 ); // this is only to kick out quoted backslashes + } + if ( nEndPos == STRING_NOTFOUND ) + { // Token is incomplete. Skip start and search for better ones + nPos = nStyle3StartPos +2; + ByteString sTmp( "Tag Start '\\<' without Tag End '\\>': " ); + rErrorList.AddError( 24, "Tag Start '\\<' without Tag End '\\>'", TokenInfo( TAG_UNKNOWN_TAG, nStyle3StartPos, aSource.Copy( nStyle3StartPos-10, 20 ) ) ); + return GetNextTokenString( rErrorList, rTagStartPos ); + } + // check for paired quoted " --> \"sometext\" + + nPos = nEndPos; + rTagStartPos = nStyle3StartPos; + return aSource.Copy( nStyle3StartPos, nEndPos-nStyle3StartPos +2 ); + } +} + +String SimpleParser::GetLexem( TokenInfo const &aToken ) +{ + if ( aToken.aTokenString.Len() ) + return aToken.aTokenString; + else + { + USHORT i = 0; + while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG && + aKnownTags[i].nTag != aToken.nId ) + i++; + + return aKnownTags[i].GetName(); + } +} + +TokenParser::TokenParser() +: pErrorList( NULL ) +{} + +void TokenParser::Parse( const String &aCode, ParserMessageList* pList ) +{ + pErrorList = pList; + + //Scanner initialisieren + aParser.Parse( aCode ); + + //erstes Symbol holen + aTag = aParser.GetNextToken( *pErrorList ); + + nPfCaseOptions = 0; + nAppCaseOptions = 0; + bPfCaseActive = FALSE; + bAppCaseActive = FALSE; + + nActiveRefTypes = 0; + + //Ausfuehren der Start-Produktion + Paragraph(); + + //Es wurde nicht die ganze Kette abgearbeitet, bisher ist aber + //kein Fehler aufgetreten + //=> es wurde ein einleitendes Tag vergessen + if ( aTag.nId != TAG_NOMORETAGS ) + { + switch ( aTag.nId ) + { + case TAG_END: + { + ParseError( 3, "Extra Tag <#END>. Switch or <#HREF> expected.", aTag ); + } + break; + case TAG_BOLDOFF: + { + ParseError( 4, "<#BOLD> expected before <#/BOLD>.", aTag ); + } + break; + case TAG_ITALICOFF: + { + ParseError( 5, "<#ITALIC> expected before <#/ITALIC>.", aTag ); + } + break; + case TAG_UNDERLINEOFF: + { + ParseError( 17, "<#UNDER> expected before <#/UNDER>.", aTag ); + } + break; +/* case TAG_MISSPARENTHESIS: + { + ParseError( 14, "missing closing parenthesis '>'", aTag ); + } + break;*/ + case TAG_AEND: + { + ParseError( 5, "Extra Tag <#AEND>. <#AVIS> or <#AHID> expected.", aTag ); + } + break; + case TAG_ELSE: + { + ParseError( 16, "Application-tag or platform-tag expected before <#ELSE>.", aTag ); + } + break; + case TAG_UNKNOWN_TAG: + { + ParseError( 6, "unknown Tag", aTag ); + } + break; + default: + { + ParseError( 6, "unexpected Tag", aTag ); + } + } + } + pErrorList = NULL; +} + +void TokenParser::Paragraph() +{ + switch ( aTag.nId ) + { + case TAG_GRAPHIC: + case TAG_NEXTVERSION: + { + TagRef(); + Paragraph(); + } + break; + case TAG_AVIS: + case TAG_AHID: + { + TagRef(); + Paragraph(); + } + break; + case TAG_HELPID: + { + SimpleTag(); + Paragraph(); + } + break; + case TAG_OFFICEFULLNAME: + case TAG_OFFICENAME: + case TAG_OFFICEPATH: + case TAG_OFFICEVERSION: + case TAG_PORTALNAME: + case TAG_PORTALFULLNAME: + case TAG_PORTALPATH: + case TAG_PORTALVERSION: + case TAG_PORTALSHORTNAME: + { + SimpleTag(); + Paragraph(); + } + break; + case TAG_REFINSERT: + { + SimpleTag(); + Paragraph(); + } + break; + case TAG_BOLDON: + case TAG_ITALICON: + case TAG_UNDERLINEON: + case TAG_COMMONSTART: + { + TagPair(); + Paragraph(); + } + break; + case TAG_HREF: + case TAG_NAME: + case TAG_KEY: + case TAG_INDEX: + case TAG_TITEL: + case TAG_REFSTART: + { + TagRef(); + Paragraph(); + } + break; + case TAG_OS2: + case TAG_WIN: + case TAG_UNIX: + case TAG_MAC: //... + { + if ( ! bPfCaseActive ) + { + //PfCases duerfen nicht verschachtelt sein: + bPfCaseActive = TRUE; + PfCase(); + + //So jetzt kann wieder ein PfCase kommen: + bPfCaseActive = FALSE; + Paragraph(); + } + } + break; + case TAG_WRITER: + case TAG_CALC: + case TAG_DRAW: + case TAG_IMPRESS: + case TAG_SCHEDULE: + case TAG_IMAGE: + case TAG_MATH: + case TAG_CHART: + case TAG_OFFICE: + { + if ( !bAppCaseActive ) + { + //AppCases duerfen nicht verschachtelt sein: + bAppCaseActive = TRUE; + AppCase(); + + //jetzt koennen wieder AppCases kommen: + bAppCaseActive = FALSE; + Paragraph(); + } + } + break; + + //Case TAG_BOLDOFF, TAG_ITALICOFF, TAG_BUNDERLINE, TAG_END + //nichts tun wg. epsilon-Prod. + } +} + +void TokenParser::PfCase() +{ + + //Produktion: + //PfCase -> PfCaseBegin Paragraph (PfCase | PfCaseEnd) + + PfCaseBegin(); + + //Jetzt ist eine PfCase-Produktion aktiv: + Paragraph(); + switch ( aTag.nId ) + { + case TAG_ELSE: + case TAG_END: + { + CaseEnd(); + } + break; + case TAG_OS2: + case TAG_WIN: + case TAG_UNIX: + case TAG_MAC: //First (PfBegin) + { + PfCase(); + } + break; + default: + ParseError( 8, "<#ELSE> or <#END> or platform-tag expected.", aTag ); + } + //Die gemerkten Tags wieder loeschen fuer naechstes PfCase: + nPfCaseOptions = 0; +} + +void TokenParser::PfCaseBegin() +{ + switch ( aTag.nId ) + { + case TAG_OS2: + case TAG_WIN: + case TAG_UNIX: + case TAG_MAC: + { + //Token darf noch nicht vorgekommen sein im + //aktuellen Plattform-Case: + if ( !HAS_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) ) ) + { + SET_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) ); + match( aTag, aTag ); + } + else { + ParseError( 9, "Tag defined twice in the same platform-case", aTag ); + } + } + } +} + +void TokenParser::AppCase() +{ + + //Produktion: + //AppCase -> AppCaseBegin Paragraph (AppCase | AppCaseEnd) + + + AppCaseBegin(); + + Paragraph(); + + switch ( aTag.nId ) + { + case TAG_ELSE: + case TAG_END: + { + CaseEnd(); + } + break; + case TAG_WRITER: + case TAG_DRAW: + case TAG_CALC: + case TAG_IMAGE: + case TAG_MATH: + case TAG_CHART: + case TAG_OFFICE: + case TAG_IMPRESS: + case TAG_SCHEDULE: //First (AppBegin) + { + AppCase(); + } + break; + default: + ParseError( 1, "<#ELSE> or <#END> or application-case-tag expected.", aTag ); + } + + //Die gemerkten Tags wieder loeschen fuer naechstes AppCase: + nAppCaseOptions = 0; +} + +void TokenParser::AppCaseBegin() +{ + switch ( aTag.nId ) + { + case TAG_WRITER: + case TAG_DRAW: + case TAG_CALC: + case TAG_IMAGE: + case TAG_MATH: + case TAG_CHART: + case TAG_OFFICE: + case TAG_IMPRESS: + case TAG_SCHEDULE: + { + //Token darf noch nicht vorgekommen sein im + //aktuellen Plattform-Case: + if ( !HAS_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) ) ) + { + SET_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) ); + match( aTag, aTag ); + } + else { + ParseError( 13, "Tag defined twice in the same application-case.", aTag ); + } + } + } +} + +void TokenParser::CaseEnd() +{ + //Produktion: + //CaseEnd -> <#ELSE> Paragraph <#END> | <#END> + + switch ( aTag.nId ) + { + case TAG_ELSE: + { + match( aTag, TAG_ELSE ); + Paragraph(); + match( aTag, TAG_END ); + } + break; + case TAG_END: + { + match( aTag, TAG_END ); + } + break; + default: + ParseError( 2, "<#ELSE> or <#END> expected.", aTag ); + } +} + +void TokenParser::SimpleTag() +{ + + switch ( aTag.nId ) + { + case TAG_HELPID: + { + match( aTag, TAG_HELPID ); + } + break; + case TAG_OFFICEFULLNAME: + case TAG_OFFICENAME: + case TAG_OFFICEPATH: + case TAG_OFFICEVERSION: + case TAG_PORTALNAME: + case TAG_PORTALFULLNAME: + case TAG_PORTALPATH: + case TAG_PORTALVERSION: + case TAG_PORTALSHORTNAME: + + case TAG_REFINSERT: + { + match( aTag, aTag ); + } + break; + default: + ParseError( 15, "[<#SimpleTag>] expected.", aTag ); + } +} + +void TokenParser::TagPair() +{ + switch ( aTag.nId ) + { + case TAG_BOLDON: + { + match( aTag, TAG_BOLDON ); + Paragraph(); + match( aTag, TAG_BOLDOFF ); + } + break; + case TAG_ITALICON: + { + match( aTag, TAG_ITALICON ); + Paragraph(); + match( aTag, TAG_ITALICOFF ); + } + break; + case TAG_UNDERLINEON: + { + match( aTag, TAG_UNDERLINEON ); + Paragraph(); + match( aTag, TAG_UNDERLINEOFF ); + } + break; + case TAG_COMMONSTART: + { + //remember tag so we can give the original tag in case of an error + TokenInfo aEndTag( aTag ); + aEndTag.nId = TAG_COMMONEND; + match( aTag, TAG_COMMONSTART ); + Paragraph(); + match( aTag, aEndTag ); + } + break; + default: + ParseError( 10, "<#BOLD>, <#ITALIC>, <#UNDER> expected.", aTag ); + } +} + + +void TokenParser::TagRef() +{ + switch ( aTag.nId ) + { + case TAG_GRAPHIC: + case TAG_NEXTVERSION: + { + if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) ) + { + TokenId aThisToken = aTag.nId; + SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); + match( aTag, aTag ); + Paragraph(); + if ( aThisToken == TAG_GRAPHIC ) + match( aTag, TAG_ENDGRAPHIC ); + else + match( aTag, TAG_VERSIONEND ); + // don't reset since alowed only once per paragraph + // RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); + } + else + { + ParseError( 11, "Tags <#GRAPHIC>,<#NEXTVERSION> allowed only once per paragraph at", aTag ); + } + } + break; + case TAG_AVIS: + case TAG_AHID: + { + if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) ) + { + TokenId aThisToken = aTag.nId; + SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); + match( aTag, aTag ); + Paragraph(); + match( aTag, TAG_AEND ); + RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); + } + else + { + ParseError( 11, "Nested <#AHID>,<#AVIS> not allowed.", aTag ); + } + } + break; + case TAG_HREF: + case TAG_NAME: + { + + } + // NOBREAK + case TAG_KEY: + case TAG_INDEX: + case TAG_TITEL: + case TAG_REFSTART: + { + if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) ) + { + TokenId aThisToken = aTag.nId; + match( aTag, aTag ); + if ( aThisToken != TAG_NAME ) + { // TAG_NAME has no TAG_END + SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); + Paragraph(); + match( aTag, TAG_END ); + RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) ); + } + } + else + { + ParseError( 11, "Nested <#HREF>,<#NAME> or <#KEY> not allowed.", aTag ); + } + } + break; + default: + ParseError( 12, "<#HREF>,<#NAME> or <#KEY> expected.", aTag ); + } +} + +BOOL TokenParser::match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken ) +{ + return match( aCurrentToken, TokenInfo( aExpectedToken, TOK_INVALIDPOS ) ); +} + +BOOL TokenParser::match( const TokenInfo &aCurrentToken, const TokenInfo &rExpectedToken ) +{ + TokenInfo aExpectedToken( rExpectedToken ); + if ( aCurrentToken.nId == aExpectedToken.nId ) + { + if ( ( aCurrentToken.nId == TAG_COMMONEND + && aCurrentToken.GetTagName().Equals( aExpectedToken.GetTagName() ) ) + || aCurrentToken.nId != TAG_COMMONEND ) + { + aTag = aParser.GetNextToken( *pErrorList ); + return TRUE; + } + } + + if ( aExpectedToken.nId == TAG_COMMONEND ) + { + aExpectedToken.aTokenString.Insert( String::CreateFromAscii( "Close tag for " ), 0 ); + } + + ByteString sTmp( "Expected Symbol" ); + if ( aCurrentToken.nId == TAG_NOMORETAGS ) + { + ParseError( 7, sTmp, aExpectedToken ); + } + else + { + sTmp += ": "; + sTmp += ByteString( aParser.GetLexem( aExpectedToken ), RTL_TEXTENCODING_UTF8 ); + sTmp += " near "; + ParseError( 7, sTmp, aCurrentToken ); + } + return FALSE; +} + +void TokenParser::ParseError( USHORT nErrNr, ByteString aErrMsg, const TokenInfo &rTag ) +{ + pErrorList->AddError( nErrNr, aErrMsg, rTag); + + // Das Fehlerhafte Tag ueberspringen + aTag = aParser.GetNextToken( *pErrorList ); +} + + +ParserMessage::ParserMessage( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ) + : nErrorNr( PnErrorNr ) + , aErrorText( PaErrorText ) + , nTagBegin( 0 ) + , nTagLength( 0 ) +{ + String aLexem( SimpleParser::GetLexem( rTag ) ); + aErrorText.Append(": "); + aErrorText += ByteString( aLexem, RTL_TEXTENCODING_UTF8 ); + if ( rTag.nId == TAG_NOMORETAGS ) + aErrorText.Append(" at end of line "); + else if ( rTag.nPos != TOK_INVALIDPOS ) + { + aErrorText.Append(" at Position "); + aErrorText.Append( ByteString::CreateFromInt32( rTag.nPos ) ); + } + nTagBegin = rTag.nPos; + nTagLength = aLexem.Len(); +} + +ParserError::ParserError( USHORT ErrorNr, ByteString ErrorText, const TokenInfo &rTag ) +: ParserMessage( ErrorNr, ErrorText, rTag ) +{} + +ParserWarning::ParserWarning( USHORT ErrorNr, ByteString ErrorText, const TokenInfo &rTag ) +: ParserMessage( ErrorNr, ErrorText, rTag ) +{} + +BOOL LingTest::IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens ) +{ + TokenId aTokenId = aToken.nId; + TokenId aTokenGroup = TAG_GROUP( aTokenId ); + if ( TAG_GROUP_PROGSWITCH == aTokenGroup + || TAG_REFINSERT == aTokenId + || TAG_REFSTART == aTokenId + || TAG_NAME == aTokenId + || TAG_HREF == aTokenId + || TAG_AVIS == aTokenId + || TAG_AHID == aTokenId + || TAG_GRAPHIC == aTokenId + || TAG_NEXTVERSION == aTokenId + || ( TAG_GROUP_META == aTokenGroup && (aMetaTokens & aTokenId) == aTokenId ) ) + { + if ( TAG_GROUP_META == aTokenGroup ) + aMetaTokens |= aTokenId; + return TRUE; + } + else if ( TAG_COMMONSTART == aTokenId + || TAG_COMMONEND == aTokenId ) + { + String aTagName = aToken.GetTagName(); + return !(aTagName.EqualsIgnoreCaseAscii( "comment" ) + || aTagName.EqualsIgnoreCaseAscii( "bookmark_value" ) + || aTagName.EqualsIgnoreCaseAscii( "emph" ) + || aTagName.EqualsIgnoreCaseAscii( "item" ) + || aTagName.EqualsIgnoreCaseAscii( "br" ) ); + } + return FALSE; +} + +void LingTest::CheckTags( TokenList &aReference, TokenList &aTestee, BOOL bFixTags ) +{ + ULONG i=0,j=0; + // Clean old Warnings + while ( aCompareWarningList.Count() ) + { + delete aCompareWarningList.GetCurObject(); + aCompareWarningList.Remove(); + } + + /* in xml tags, do not require the following tags + comment + bookmark_value + emph + item + br + */ + + // filter uninteresting Tags + TokenId aMetaTokens = 0; + for ( i=0 ; i < aReference.Count() ; i++ ) + { + if ( !IsTagMandatory( aReference.GetObject( i ), aMetaTokens ) ) + aReference.GetObject( i ).SetDone(); + } + + aMetaTokens = 0; + for ( i=0 ; i < aTestee.Count() ; i++ ) + { + if ( !IsTagMandatory( aTestee.GetObject( i ), aMetaTokens ) ) + aTestee.GetObject( i ).SetDone(); + } + + // remove all matching tags + for ( i=0 ; i < aReference.Count() ; i++ ) + { + if ( aReference.GetObject( i ).IsDone() ) + continue; + + BOOL bTagFound = FALSE; + for ( j=0 ; j < aTestee.Count() && !bTagFound ; j++ ) + { + if ( aTestee.GetObject( j ).IsDone() ) + continue; + + if ( aReference.GetObject( i ).MatchesTranslation( aTestee.GetObject( j ), FALSE, aCompareWarningList ) ) + { + aReference.GetObject( i ).SetDone(); + aTestee.GetObject( j ).SetDone(); + bTagFound = TRUE; + } + } + } + + BOOL bCanFix = TRUE; + + if ( bFixTags ) + { + // we fix only if its a really simple case + USHORT nTagCount = 0; + for ( i=0 ; i < aReference.Count() ; i++ ) + if ( !aReference.GetObject( i ).IsDone() ) + nTagCount++; + if ( nTagCount > 1 ) + bCanFix = FALSE; + + nTagCount = 0; + for ( i=0 ; i < aTestee.Count() ; i++ ) + if ( !aTestee.GetObject( i ).IsDone() ) + nTagCount++; + if ( nTagCount > 1 ) + bCanFix = FALSE; + } + + // generate errors for tags that have differing attributes + for ( i=0 ; i < aReference.Count() ; i++ ) + { + if ( aReference.GetObject( i ).IsDone() ) + continue; + + BOOL bTagFound = FALSE; + for ( j=0 ; j < aTestee.Count() && !bTagFound ; j++ ) + { + if ( aTestee.GetObject( j ).IsDone() ) + continue; + + if ( aReference.GetObject( i ).MatchesTranslation( aTestee.GetObject( j ), TRUE, aCompareWarningList, bCanFix && bFixTags ) ) + { + aReference.GetObject( i ).SetDone(); + aTestee.GetObject( j ).SetDone(); + bTagFound = TRUE; + } + } + } + + // list remaining tags as errors + for ( i=0 ; i < aReference.Count() ; i++ ) + { + if ( aReference.GetObject( i ).IsDone() ) + continue; + + aCompareWarningList.AddError( 20, "Missing Tag in Translation", aReference.GetObject( i ) ); + } + for ( i=0 ; i < aTestee.Count() ; i++ ) + { + if ( aTestee.GetObject( i ).IsDone() ) + continue; + + aCompareWarningList.AddError( 21, "Extra Tag in Translation", aTestee.GetObject( i ) ); + } + + for ( i=0 ; i < aReference.Count() ; i++ ) + aReference.GetObject( i ).SetDone( FALSE ); + + for ( i=0 ; i < aTestee.Count() ; i++ ) + aTestee.GetObject( i ).SetDone( FALSE ); +} + +void LingTest::CheckReference( GSILine *aReference ) +{ + aReferenceParser.Parse( aReference->GetUText(), aReference->GetMessageList() ); +} + +void LingTest::CheckTestee( GSILine *aTestee, BOOL bHasSourceLine, BOOL bFixTags ) +{ + aFixedTestee = aTestee->GetUText(); + aTesteeParser.Parse( aFixedTestee, aTestee->GetMessageList() ); + + if ( bHasSourceLine ) + CheckTags( aReferenceParser.GetTokenList(), aTesteeParser.GetTokenList(), bFixTags ); + + if ( bFixTags ) + { + TokenList& aTesteeTokens = aTesteeParser.GetTokenList(); + BOOL bFixesDone = FALSE; + // count backwards to allow replacing from right to left + int i; + for ( i=aTesteeTokens.Count()-1 ; i>=0 ; i-- ) + { + if ( aTesteeTokens.GetObject( i ).HasBeenFixed() ) + { + bFixesDone = TRUE; + aFixedTestee.Replace( aTesteeTokens.GetObject( i ).nPos, aTesteeTokens.GetObject( i ).aTokenString.Len(), aTesteeTokens.GetObject( i ).MakeTag() ); + } + } + if ( bFixesDone ) + { + aTestee->SetUText( aFixedTestee ); + aTestee->SetFixed(); + } + } +} + diff --git a/transex3/source/txtconv.cxx b/transex3/source/txtconv.cxx new file mode 100644 index 000000000000..2f442b80a83d --- /dev/null +++ b/transex3/source/txtconv.cxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: txtconv.cxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <tools/fsys.hxx> +#include <tools/stream.hxx> + +// local includes +#include "utf8conv.hxx" + +extern void ConvertHalfwitdhToFullwidth( String& rString ); + +/*****************************************************************************/ +void Help() +/*****************************************************************************/ +{ + fprintf( stdout, "\n" ); + fprintf( stdout, "txtconv (c)2001 by StarOffice Entwicklungs GmbH\n" ); + fprintf( stdout, "===============================================\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "txtconv converts textfiles from or to UTF-8\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "Syntax: txtconv -t|-f charset filename (destinationfile)\n" ); + fprintf( stdout, "Switches: -t => conversion from charset to UTF-8\n" ); + fprintf( stdout, " -f => conversion from UTF-8 to charset\n" ); + fprintf( stdout, "\n" ); + fprintf( stdout, "Allowed charsets:\n" ); + fprintf( stdout, " MS_932 => Japanese\n" ); + fprintf( stdout, " MS_936 => Chinese Simplified\n" ); + fprintf( stdout, " MS_949 => Korean\n" ); + fprintf( stdout, " MS_950 => Chinese Traditional\n" ); + fprintf( stdout, " MS_1250 => East Europe\n" ); + fprintf( stdout, " MS_1251 => Cyrillic\n" ); + fprintf( stdout, " MS_1252 => West Europe\n" ); + fprintf( stdout, " MS_1253 => Greek\n" ); + fprintf( stdout, " MS_1254 => Turkish\n" ); + fprintf( stdout, " MS_1255 => Hebrew\n" ); + fprintf( stdout, " MS_1256 => Arabic\n" ); + fprintf( stdout, " HW2FW => Only with -t, converts half to full width katakana" ); + fprintf( stdout, "\n" ); +} + +/*****************************************************************************/ +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + if (( argc != 4 ) && ( argc != 5 )) { + Help(); + exit ( 0 ); + } + + if ( ByteString( argv[ 1 ] ) == "-t" || ByteString( argv[ 1 ] ) == "-f" ) { + rtl_TextEncoding nEncoding = RTL_TEXTENCODING_MS_1252; + + BOOL bHW2FW = FALSE; + + ByteString sCharset( argv[ 2 ] ); + sCharset.ToUpperAscii(); + + if ( sCharset == "MS_932" ) nEncoding = RTL_TEXTENCODING_MS_932; + else if ( sCharset == "MS_936" ) nEncoding = RTL_TEXTENCODING_MS_936; + else if ( sCharset == "MS_949" ) nEncoding = RTL_TEXTENCODING_MS_949; + else if ( sCharset == "MS_950" ) nEncoding = RTL_TEXTENCODING_MS_950; + else if ( sCharset == "MS_1250" ) nEncoding = RTL_TEXTENCODING_MS_1250; + else if ( sCharset == "MS_1251" ) nEncoding = RTL_TEXTENCODING_MS_1251; + else if ( sCharset == "MS_1252" ) nEncoding = RTL_TEXTENCODING_MS_1252; + else if ( sCharset == "MS_1253" ) nEncoding = RTL_TEXTENCODING_MS_1253; + else if ( sCharset == "MS_1254" ) nEncoding = RTL_TEXTENCODING_MS_1254; + else if ( sCharset == "MS_1255" ) nEncoding = RTL_TEXTENCODING_MS_1255; + else if ( sCharset == "MS_1256" ) nEncoding = RTL_TEXTENCODING_MS_1256; + else if ( sCharset == "MS_1257" ) nEncoding = RTL_TEXTENCODING_MS_1257; + else if (( sCharset == "HW2FW" ) && ( ByteString( argv[ 1 ] ) == "-t" )) bHW2FW = TRUE; + + else { + Help(); + exit ( 1 ); + } + + DirEntry aSource = DirEntry( String( argv[ 3 ], RTL_TEXTENCODING_ASCII_US )); + if ( !aSource.Exists()) { + fprintf( stderr, "\nERROR: File %s not found!\n\n", ByteString( argv[ 3 ] ).GetBuffer()); + exit ( 2 ); + } + + String sOutput; + SvFileStream aOutput; + if ( argc == 5 ) { + sOutput= String( argv[ 4 ], RTL_TEXTENCODING_ASCII_US ); + aOutput.Open( sOutput, STREAM_STD_WRITE | STREAM_TRUNC ); + if ( !aOutput.IsOpen()) { + fprintf( stderr, "\nERROR: Could not open output file %s!\n\n", argv[ 4 ]); + exit ( 3 ); + } + } + + String sGSI( argv[ 3 ], RTL_TEXTENCODING_ASCII_US ); + SvFileStream aGSI( sGSI, STREAM_STD_READ ); + if ( !aGSI.IsOpen()) { + fprintf( stderr, "\nERROR: Could not open input file %s!\n\n", argv[ 3 ]); + exit ( 3 ); + } + + ByteString sGSILine; + while ( !aGSI.IsEof()) { + + aGSI.ReadLine( sGSILine ); + if ( bHW2FW ) { + String sConverter( sGSILine, RTL_TEXTENCODING_UTF8 ); + ConvertHalfwitdhToFullwidth( sConverter ); + sGSILine = ByteString( sConverter, RTL_TEXTENCODING_UTF8 ); + } + else { + if ( ByteString( argv[ 1 ] ) == "-t" ) + sGSILine = UTF8Converter::ConvertToUTF8( sGSILine, nEncoding ); + else + sGSILine = UTF8Converter::ConvertFromUTF8( sGSILine, nEncoding ); + } + + if ( aOutput.IsOpen()) + aOutput.WriteLine( sGSILine ); + else + fprintf( stdout, "%s\n", sGSILine.GetBuffer()); + } + + aGSI.Close(); + if ( aOutput.IsOpen()) + aOutput.Close(); + } + else { + Help(); + exit( 1 ); + } + + return 0; +} diff --git a/transex3/source/utf8conv.cxx b/transex3/source/utf8conv.cxx new file mode 100644 index 000000000000..8fc61f9bb5cc --- /dev/null +++ b/transex3/source/utf8conv.cxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: utf8conv.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include "utf8conv.hxx" + +// +// class UTF8Converter +// + +#define MAX_CONV_BUFFER_SIZE 0xFF00 + +#define TO_CVTFLAGS (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |\ + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |\ + RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT) + +#define FROM_CVTFLAGS (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |\ + RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |\ + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |\ + RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0) + +/*****************************************************************************/ +void UTF8Converter::Convert( ByteString &rBuffer, + rtl_TextEncoding nSourceENC, rtl_TextEncoding nDestENC ) +/*****************************************************************************/ +{ + String sTemp( rBuffer, nSourceENC ); + rBuffer = ByteString( sTemp, nDestENC ); +} + +/*****************************************************************************/ +ByteString UTF8Converter::ConvertToUTF8( + const ByteString &rASCII, rtl_TextEncoding nEncoding ) +/*****************************************************************************/ +{ + ByteString sReturn( rASCII ); + Convert( sReturn, nEncoding, RTL_TEXTENCODING_UTF8 ); + return sReturn; +} + +/*****************************************************************************/ +ByteString UTF8Converter::ConvertFromUTF8( + const ByteString &rUTF8, rtl_TextEncoding nEncoding ) +/*****************************************************************************/ +{ + ByteString sReturn( rUTF8 ); + Convert( sReturn, RTL_TEXTENCODING_UTF8, nEncoding ); + return sReturn; +} diff --git a/transex3/source/wrdtrans.cxx b/transex3/source/wrdtrans.cxx new file mode 100644 index 000000000000..71866cd0e618 --- /dev/null +++ b/transex3/source/wrdtrans.cxx @@ -0,0 +1,248 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wrdtrans.cxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" + +/* +#include "wrdtrans.hxx" + + +// NOT FULLY DECLARED SERVICES +#include <vector> +#include <vos/macros.hxx> + + +#include <tools/stream.hxx> +#include "wtratree.hxx" + +#include <tools/string.hxx> +*/ +//************** Declaration WordTrans_ErrorList ******************// +/* +typedef NAMESPACE_STD(vector)<ByteString> Stl_ByteStringList; + +class WordTrans_ErrorList +{ + public: + // OPERATIONS + void AddError( + WordTransformer::E_Error + i_eType, + const char * i_sErrorDescription ); + void Clear(); /// Empties the list. + + // INQUIRY + USHORT NrOfErrors() const; + WordTransformer::E_Error + GetError( + USHORT i_nNr, /// [0 .. NrOfErrors()-1], other values return an empty error. + ByteString * o_pErrorText ) const; /// If o_pErrorText != 0, the String is filled with the description of the error. + private: + // DATA + Stl_ByteStringList aErrors; +}; + +*/ + +//************** Implementation WordTransformer ******************// + +/* +WordTransformer::WordTransformer() + : dpTransformer(0), + dpErrors(new WordTrans_ErrorList) +{ +} + +WordTransformer::~WordTransformer() +{ + if (dpTransformer != 0) + delete dpTransformer; + delete dpErrors; +} + +BOOL +WordTransformer::LoadWordlist( const ByteString & i_sWordlist_Filepath, + CharSet i_nWorkingCharSet, + CharSet i_nFileCharSet ) +{ + if (dpTransformer != 0) + return FALSE; + + SvFileStream aFile(String(i_sWordlist_Filepath,RTL_TEXTENCODING_ASCII_US),STREAM_STD_READ); + if (! aFile.IsOpen()) + return FALSE; + aFile.SetStreamCharSet( i_nFileCharSet ) ; +// aFile.SetTargetCharSet( i_nWorkingCharSet ); + + dpTransformer = new WordTransTree; + + ByteString sTrans; + while ( aFile.ReadLine(sTrans) ) + { + dpTransformer->AddWordPair(sTrans.GetToken(0,';'),sTrans.GetToken(1,';')); + } + + aFile.Close(); + return TRUE; +} + +USHORT +WordTransformer::Transform(ByteString & io_sText) +{ + // Initialization and precondition testing: + dpErrors->Clear(); + if (dpTransformer == 0) + { + dpErrors->AddError(ERROR_NO_WORDLIST,"Error: No wordlist was loaded."); + return dpErrors->NrOfErrors(); + } + else if (io_sText.Len() > 63 * 1024) + { + dpErrors->AddError(ERROR_OUTPUTSTRING_TOO_LONG,"Error: Inputstring was too long (bigger than 63 KB)."); + return dpErrors->NrOfErrors(); + } + else if (io_sText.Len() == 0) + { + return 0; + } + + // Transform: + dpTransformer->InitTransformation( + io_sText.GetBuffer(), + io_sText.Len() ); + + for ( ; !dpTransformer->TextEndReached(); ) + { + if (dpTransformer->TransformNextToken() != WordTransTree::OK) + { + CreateError(); + } + } + io_sText = dpTransformer->Output(); + return dpErrors->NrOfErrors(); +} + +USHORT +WordTransformer::NrOfErrors() const +{ + return dpErrors->NrOfErrors(); +} + +WordTransformer::E_Error +WordTransformer::GetError( USHORT i_nNr, + ByteString * o_pErrorText) const +{ + return dpErrors->GetError(i_nNr,o_pErrorText); +} + +void +WordTransformer::CreateError() +{ + ByteString sErr; + + switch (dpTransformer->CurResult()) + { + case WordTransTree::OK: + break; + case WordTransTree::HOTKEY_LOST: + sErr = ByteString("Error: By replacement of string "); + sErr += dpTransformer->CurReplacedString(); + sErr += " by "; + sErr += dpTransformer->CurReplacingString(); + sErr += "the hotkey at char '"; + sErr += dpTransformer->CurHotkey(); + sErr += "' was lost."; + dpErrors->AddError( ERROR_HOTKEY,sErr.GetBufferAccess()); + sErr.ReleaseBufferAccess(); + break; + case WordTransTree::OUTPUT_OVERFLOW: + dpErrors->AddError(ERROR_OUTPUTSTRING_TOO_LONG,"Error: Output buffer overflow."); + break; + default: + dpErrors->AddError(OTHER_ERROR,"Error: Unknown error."); + } +} +*/ +//************** Implementation WordTrans_ErrorList ******************// +/* +void +WordTrans_ErrorList::AddError( WordTransformer::E_Error i_eType, + const char * i_sErrorDescription ) +{ + ByteString sErrorType = "xxx"; + char * pErrorChars = sErrorType.GetBufferAccess(); + pErrorChars[0] = char(i_eType / 100 + '0'); + pErrorChars[1] = char( (i_eType % 100) / 10 + '0'); + pErrorChars[2] = char(i_eType % 10 + '0'); + sErrorType += i_sErrorDescription; + + aErrors.push_back(sErrorType); + sErrorType.ReleaseBufferAccess(); +} + +void +WordTrans_ErrorList::Clear() +{ + aErrors.erase(aErrors.begin(),aErrors.end()); +} + +USHORT +WordTrans_ErrorList::NrOfErrors() const +{ + return aErrors.size(); +} + +WordTransformer::E_Error +WordTrans_ErrorList::GetError( USHORT i_nNr, + ByteString * o_pErrorText ) const +{ + if ( i_nNr < aErrors.size() ) + { + const ByteString & rError = aErrors[i_nNr]; + const char * pErrorChars = rError.GetBuffer(); + + USHORT nError = USHORT( (pErrorChars[0] - '0') ) * 100 + + (pErrorChars[1] - '0') * 10 + + pErrorChars[2] - '0'; + + if (o_pErrorText != 0) + *o_pErrorText = pErrorChars+3; + + return WordTransformer::E_Error(nError); + } + else + { + if (o_pErrorText != 0) + *o_pErrorText = ""; + return WordTransformer::OK; + } +} +*/ diff --git a/transex3/source/wtranode.cxx b/transex3/source/wtranode.cxx new file mode 100644 index 000000000000..0383ffa7feac --- /dev/null +++ b/transex3/source/wtranode.cxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wtranode.cxx,v $ + * $Revision: 1.4 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" + + +#include "wtranode.hxx" + + +// NOT FULLY DECLARED SERVICES + + +const ByteString sEmptyString(""); + + +WTT_Node::WTT_Node( UINT8 i_nValue, + WTT_Node * i_pDefaultBranch, + WTT_Node * i_pDefaultBranchForAlphas ) + : nValue(i_nValue), + eType(token_to_keep), + sReplaceString(sEmptyString), + // aBranches, + bIsOnDeleting(char(0)) +{ + int i = 0; + for ( ; i < C_BR_ALPHABASE; i++ ) + { + aBranches[i] = i_pDefaultBranch; + } // end for + for ( ; i < C_NR_OF_BRANCHES; i++ ) + { + aBranches[i] = i_pDefaultBranchForAlphas; + } +} + +void +WTT_Node::SetBranch( UINT8 i_cBranch, + WTT_Node * i_pNode ) +{ + if (i_cBranch < C_NR_OF_BRANCHES) + { + aBranches[i_cBranch] = i_pNode; + } +} + +void +WTT_Node::SetAsTokenToReplace(const ByteString & i_sReplaceString) +{ + sReplaceString = i_sReplaceString; + eType = token_to_replace; +} + +WTT_Node::~WTT_Node() +{ + // Delete the tree hanging below this node: + + bIsOnDeleting = TRUE; // Avoid double deleting of multiple used nodes. + + for (int i = 0; i < C_NR_OF_BRANCHES; i++) + { + if (aBranches[i] != 0 ? ! aBranches[i]->IsOnDeleting() : FALSE) + { + delete aBranches[i]; + } + } // end for +} + + + + + + + + + + + + + + + + + diff --git a/transex3/source/wtratree.cxx b/transex3/source/wtratree.cxx new file mode 100644 index 000000000000..fea67215ba51 --- /dev/null +++ b/transex3/source/wtratree.cxx @@ -0,0 +1,421 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: wtratree.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" + + +#include "wtratree.hxx" + + + +/** @ATTENTION + For reasons of speed, class WordTransTree works with two simple + char arrays, sOutput and sInput, instead of secure containers or + streams. So be extremely careful, when changing this code!!! +**/ + + + +// NOT FULLY DECLARED SERVICES +#include <string.h> +#include <stdio.h> +#include <ctype.h> +#include "wtranode.hxx" + + +const BRANCH_T BR_END = 0; +const BRANCH_T BR_NONALPHA = 1; +const BRANCH_T BR_HOTKEY = 2; +const BRANCH_T BR_BACKSLASH = 3; +const BRANCH_T BR_ALPHABASE = 4; /// @ATTENTION All branches not valid for words must be smaller than this value! +const BRANCH_T BR_AE = 30; +const BRANCH_T BR_OE = 31; +const BRANCH_T BR_UE = 32; +const BRANCH_T BR_SZ = 33; +const BRANCH_T BR_MAX = 34; /// @ATTENTION Must be updated always! + +const BRANCH_T BR_START = 0; + + + + + +WordTransTree::WordTransTree(CharSet i_nWorkingCharSet) + : sInput(0), + nInputLength(0), + pInputEnd(0), + sOutput(0), + nOutputMaxLength(0), + dpParsingTreeTop(0), + pUnknownAlpha(0), + // cChar2Branch + c_AE(u_char('\xC4')), c_OE(u_char('\xD6')), c_UE(u_char('\xDC')), + c_ae(u_char('\xE4')), c_oe(u_char('\xF6')), c_ue(u_char('\xFC')), + pInputCurTokenStart(0), + pInputPosition(0), + pOutputPosition(0), + pCurParseNode(0), + eCurResult(OK), + cCurHotkey(0), + cCurHotkeySign(u_char('~')) +{ + // Initialize parsing tree: + pUnknownAlpha = new WTT_Node(BR_ALPHABASE,0,0); // This will be deleted as part of the parsing tree. + for ( UINT8 i = BR_ALPHABASE; i < C_NR_OF_BRANCHES; i++) + { + pUnknownAlpha->SetBranch(i,pUnknownAlpha); + } // end for + + dpParsingTreeTop = new WTT_Node(BR_START,0,pUnknownAlpha); + + WTT_Node * dpNonAlpha = new WTT_Node(BR_NONALPHA,0,0); + + dpNonAlpha->SetBranch(BR_NONALPHA,dpNonAlpha); + dpParsingTreeTop->SetBranch(BR_NONALPHA,dpNonAlpha); + + WTT_Node * dpBackslash = new WTT_Node(BR_BACKSLASH,dpNonAlpha,dpNonAlpha); + dpBackslash->SetBranch(BR_END,0); + + dpParsingTreeTop->SetBranch(BR_BACKSLASH,dpBackslash); + dpNonAlpha->SetBranch(BR_BACKSLASH,dpBackslash); + + + // Initialize character set: + SetCharSet(i_nWorkingCharSet); + + if (C_BR_ALPHABASE != BR_ALPHABASE || C_NR_OF_BRANCHES != BR_MAX) + { + fprintf(stderr, "Assertion failed: file %s line %d.", __FILE__, __LINE__); + exit(1); + } +} + +void +WordTransTree::SetCharSet(CharSet i_nWorkingCharSet) +{ + ByteString sConvert("\xC4\xD6\xDC\xE4\xF6\xFC\xDF"); + const u_char * pConvert = (const u_char * ) ( sConvert.Convert(RTL_TEXTENCODING_MS_1252, i_nWorkingCharSet).GetBuffer() ); + + INT16 i = 0; + for ( ; i < C_NR_OF_POSSIBLE_CHARS; ++i ) + { + cChar2Branch[i] = BR_NONALPHA; + } // end for + for ( i = 'a'; i <= 'z'; ++i ) + { + cChar2Branch[i] = BR_ALPHABASE + i - 'a'; + } // end for + for ( i = 'A'; i <= 'Z'; ++i ) + { + cChar2Branch[i] = BR_ALPHABASE + i - 'A'; + } // end for + cChar2Branch[pConvert[0]] = BR_AE; + cChar2Branch[pConvert[1]] = BR_OE; + cChar2Branch[pConvert[2]] = BR_UE; + cChar2Branch[pConvert[3]] = BR_AE; + cChar2Branch[pConvert[4]] = BR_OE; + cChar2Branch[pConvert[5]] = BR_UE; + cChar2Branch[pConvert[6]] = BR_SZ; + + cChar2Branch[u_char('~')] = BR_HOTKEY; + cChar2Branch[u_char('&')] = BR_HOTKEY; + + + c_AE = pConvert[0]; + c_OE = pConvert[1]; + c_UE = pConvert[2]; + c_ae = pConvert[3]; + c_oe = pConvert[4]; + c_ue = pConvert[5]; +} + +WordTransTree::~WordTransTree() +{ + delete dpParsingTreeTop; + if (sOutput != 0) + delete [] sOutput; +} + +void +WordTransTree::AddWordPair( const ByteString & i_sOldString, + const ByteString & i_sReplaceString ) +{ + if (i_sOldString.Len() == 0) + return; + + pCurParseNode = dpParsingTreeTop; + WTT_Node * pBranch = 0; + char cBranch = 0; + + for ( constr pOld = i_sOldString.GetBuffer(); + *pOld != 0; + pOld++ ) + { + cBranch = CalculateBranch(*pOld); + pBranch = pCurParseNode->GetNextNode(cBranch); + if (pBranch == 0 || pBranch == pUnknownAlpha) + { + pBranch = new WTT_Node(cBranch,0,pUnknownAlpha); + pCurParseNode->SetBranch(cBranch,pBranch); + } + pCurParseNode = pBranch; + } // end for + pCurParseNode->SetAsTokenToReplace(i_sReplaceString); +} + +void +WordTransTree::InitTransformation( const char * i_sInput, + UINT32 i_nInputLength, + UINT32 i_nOutputMaxLength ) +{ + sInput = (const u_char *)i_sInput; + nInputLength = i_nInputLength; + pInputEnd = &sInput[i_nInputLength]; + + pInputCurTokenStart = sInput; + pInputPosition = sInput; + + if (nOutputMaxLength < i_nOutputMaxLength) + { + if (sOutput != 0) + delete [] sOutput; + sOutput = new unsigned char[i_nOutputMaxLength]; + nOutputMaxLength = i_nOutputMaxLength; + } + pOutputPosition = sOutput; +} + +/** pInputCurTokenStart and CurParseNode are updated just when + starting this function. After its end they must not be changed + till this functon is called again. + Outside this function pInputPositon and pOutputPosition are both + on the first not transformed char in their respective array. +**/ +WordTransTree::E_Result +WordTransTree::TransformNextToken() +{ + pInputCurTokenStart = pInputPosition; + pCurParseNode = dpParsingTreeTop; + cCurHotkey = 0; + eCurResult = OK; + + WTT_Node * pBranch = 0; + UINT8 cBranch = 0; + + for ( pCurParseNode = dpParsingTreeTop; + pInputPosition != pInputEnd; + ++pInputPosition ) + { + cBranch = CalculateBranch(*pInputPosition); + pBranch = pCurParseNode->GetNextNode( cBranch ); + if (pBranch != 0) + { + pCurParseNode = pBranch; + } + else + { + if (cBranch == BR_HOTKEY) // current letter is '~' or '&'. + { + // Logic of the following. There are 9 possible cases - + // A = alphabetic letter, NA = non alphabetic, TB = token begin, + // Eot = end of text: + // 1. A~A set hotkey to following letter, continue + // 2. A~NA token end + // 3. A~Eot token end + // 4. NA~A token end + // 5. NA~NA continue + // 6. A~Eof continue + // 7. TB~A set hotkey to following letter, continue + // 8. TB~NA continue + // 9. TB~Eot continue + + // bNext and Prev are true, if there are alphabetic letters: + BOOL bNext = pInputPosition + 1 != pInputEnd + ? CalculateBranch(pInputPosition[1]) >= BR_ALPHABASE + : FALSE; + BOOL bPrev = pCurParseNode->Value() >= BR_ALPHABASE; + + if ( bNext && (bPrev || pCurParseNode == dpParsingTreeTop) ) + { // case 1. and 7. + Handle_Hotkey(); + continue; + } + else if (!bPrev && !bNext) + { // case 5.,6.,8.,9. + continue; + } + + // Case 2.,3.,4. : + // so this should be handled as an end of a token. + } + if (pCurParseNode->TokenType() == WTT_Node::token_to_keep) + { + Handle_TokenToKeep(); + return eCurResult; + } + else + { + Handle_TokenToTransform(); + return eCurResult; + } // endif (pCurParseNode->TokenType() == WTT_Node::token_to_keep) + } // endif (pBranch == 0) else + } // end for + + // If here, the text end is reached + if (pCurParseNode->TokenType() == WTT_Node::token_to_keep) + { + Handle_TokenToKeep(); + return eCurResult; + } + else + { + Handle_TokenToTransform(); + return eCurResult; + } +} + +ByteString +WordTransTree::CurReplacingString() const +{ + return pCurParseNode->ReplaceString(); +} + +void +WordTransTree::Handle_Hotkey() +{ + if (cCurHotkey == 0) // Avoid to replace the first found hotkey by + // a later one - though this shouldn't happen anyway. + { + cCurHotkey = (pInputPosition+1) != pInputEnd ? pInputPosition[1] : 0; + cCurHotkeySign = *pInputPosition; + } +} + +void +WordTransTree::Handle_TokenToKeep() +{ + UINT32 nTokenLength = pInputPosition-pInputCurTokenStart; + + memcpy(pOutputPosition,pInputCurTokenStart,nTokenLength); + + pOutputPosition += nTokenLength; + *pOutputPosition = '\0'; +} + +void +WordTransTree::Handle_TokenToTransform() +{ + BOOL bHaveHotkey = CalculateBranch(cCurHotkey) >= BR_ALPHABASE; + const ByteString & rReplace = pCurParseNode->ReplaceString(); + + // Find position of hotkey in replace-string: + USHORT nHotkeyPos = bHaveHotkey + ? rReplace.Search(char(cCurHotkey)) + : STRING_NOTFOUND; + if (nHotkeyPos == STRING_NOTFOUND && bHaveHotkey) + { + if (cCurHotkey < 128) + { + if (islower(cCurHotkey)) + nHotkeyPos = rReplace.Search(toupper(char(cCurHotkey))); + else + nHotkeyPos = rReplace.Search(tolower(char(cCurHotkey))); + } + else // cCurHotkey >= 128 + { + if (cCurHotkey == c_ae) + nHotkeyPos = rReplace.Search(char(c_AE)); + else if (cCurHotkey == c_oe) + nHotkeyPos = rReplace.Search(char(c_OE)); + else if (cCurHotkey == c_ue) + nHotkeyPos = rReplace.Search(char(c_UE)); + else if (cCurHotkey == c_AE) + nHotkeyPos = rReplace.Search(char(c_ae)); + else if (cCurHotkey == c_OE) + nHotkeyPos = rReplace.Search(char(c_oe)); + else if (cCurHotkey == c_UE) + nHotkeyPos = rReplace.Search(char(c_ue)); + } // endif (cCurHotkey < 128) else + + if (nHotkeyPos == STRING_NOTFOUND) + { + eCurResult = HOTKEY_LOST; + bHaveHotkey = FALSE; + } + } // endif (nHotkeyPos == STRING_NOT_FOUND && bHaveHotkey) + + + UINT32 nOutputTokenLength = rReplace.Len() + (bHaveHotkey ? 1 : 0); + + if (bHaveHotkey) + { + memcpy( pOutputPosition, + pCurParseNode->ReplaceString().GetBuffer(), + nHotkeyPos ); + *(pOutputPosition + nHotkeyPos) = cCurHotkeySign; + memcpy( pOutputPosition + nHotkeyPos + 1, + pCurParseNode->ReplaceString().GetBuffer() + nHotkeyPos, + nOutputTokenLength - nHotkeyPos - 1); + } + else + { + memcpy( pOutputPosition, + pCurParseNode->ReplaceString().GetBuffer(), + nOutputTokenLength ); + } + + // Convert first letter into upper if necessary: + u_char cInStart = CalculateBranch(*pInputCurTokenStart) == BR_HOTKEY + ? pInputCurTokenStart[1] + : pInputCurTokenStart[0] ; + u_char * pOutStart = nHotkeyPos == 0 + ? pOutputPosition + 1 + : pOutputPosition ; + if (isupper(cInStart) || cInStart > 127) + { // Possibly cInStart is upper character: + if (isupper(cInStart) || cInStart == c_AE || cInStart == c_OE || cInStart == c_UE) + { // Surely cInStart is upper character: + u_char cOutStart = *pOutStart; + if (cOutStart < 128) + *pOutStart = toupper(cOutStart); + else if (cOutStart == c_ae) + *pOutStart = c_AE; + else if (cOutStart == c_oe) + *pOutStart = c_OE; + else if (cOutStart == c_ue) + *pOutStart = c_UE; + } + } // endif (isupper(cInStart) || cInStart > 127) + + pOutputPosition += nOutputTokenLength; + *pOutputPosition = '\0'; +} + diff --git a/transex3/source/xgfconv.cxx b/transex3/source/xgfconv.cxx new file mode 100644 index 000000000000..76ea1a2906a8 --- /dev/null +++ b/transex3/source/xgfconv.cxx @@ -0,0 +1,66 @@ +#include <stdio.h> + +#include "export.hxx" +#include "utf8conv.hxx" + +/*****************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#if defined(UNX) || defined(OS2) +int main( int argc, char *argv[] ) +#else +int _cdecl main( int argc, char *argv[] ) +#endif +/*****************************************************************************/ +{ + if ( argc != 3 ) { + fprintf( stderr, "xgfconv InputFile OutputFile\n" ); + return ( 5 ); + } + + ByteString sInput( argv[ 1 ] ); + ByteString sOutput( argv[ 2 ] ); + + SvFileStream aInput( String( sInput, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); + if ( !aInput.IsOpen()) { + fprintf( stderr, "ERROR: Unable to open input file!\n" ); + return ( 5 ); + } + + SvFileStream aOutput( String( sOutput, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); + if ( !aOutput.IsOpen()) { + fprintf( stderr, "ERROR: Unable to open output file!\n" ); + aInput.Close(); + return ( 5 ); + } + + ByteString sLine; + BOOL bFirst = TRUE; + while ( !aInput.IsEof()) { + aInput.ReadLine( sLine ); + ByteString sLangId = sLine.GetToken( 0, '\t' ); + ByteString sFile = sLine.GetToken( 1, '\t' ); + ByteString sText = sLine.Copy( sLangId.Len() + sFile.Len() + 2 ); + + USHORT nLangId = sLangId.ToInt32(); + CharSet aCharSet = Export::GetCharSet( nLangId ); + if ( aCharSet != 0xFFFF && sText.Len()) { + sText = UTF8Converter::ConvertToUTF8( sText, aCharSet ); + ByteString sOutput = sFile; + sOutput += "\t"; + sOutput += sText; + if ( !bFirst ) { + ByteString sEmpty; + aOutput.WriteLine( sEmpty ); + } + else + bFirst = FALSE; + aOutput.Write( sOutput.GetBuffer(), sOutput.Len()); + } + } + aInput.Close(); + aOutput.Close(); + return ( 0 ); +} + diff --git a/transex3/source/xmlparse.cxx b/transex3/source/xmlparse.cxx new file mode 100644 index 000000000000..921f1d329f67 --- /dev/null +++ b/transex3/source/xmlparse.cxx @@ -0,0 +1,1456 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xmlparse.cxx,v $ + * $Revision: 1.24 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <iterator> /* std::iterator*/ + +#include <stdio.h> +#include <sal/alloca.h> + +#include "xmlparse.hxx" +#include <fstream> +#include <iostream> +#include <osl/mutex.hxx> +#include <osl/thread.hxx> +#ifdef __MINGW32__ +#include <tools/prewin.h> +#include <tools/postwin.h> +#endif +using namespace std; +using namespace osl; + +// +// class XMLChildNode +// + +/*****************************************************************************/ +XMLChildNode::XMLChildNode( XMLParentNode *pPar ) +/*****************************************************************************/ + : pParent( pPar ) +{ + if ( pParent ) + pParent->AddChild( this ); +} + + +/*****************************************************************************/ +XMLChildNode::XMLChildNode( const XMLChildNode& obj) +/*****************************************************************************/ +: XMLNode(obj), + pParent(obj.pParent){} + +/*****************************************************************************/ +XMLChildNode& XMLChildNode::operator=(const XMLChildNode& obj){ +/*****************************************************************************/ + if(this != &obj){ + pParent=obj.pParent; + } + return *this; +} +// +// class XMLParentNode +// + + +/*****************************************************************************/ +XMLParentNode::~XMLParentNode() +/*****************************************************************************/ +{ + if( pChildList ){ + RemoveAndDeleteAllChilds(); + delete pChildList; + pChildList = NULL; + } + pChildList = NULL; +} +/*****************************************************************************/ +XMLParentNode::XMLParentNode( const XMLParentNode& obj) +/*****************************************************************************/ +: XMLChildNode( obj ) +{ + if( obj.pChildList ){ + pChildList=new XMLChildNodeList(); + XMLChildNode* pNode = NULL; + for ( ULONG i = 0; i < obj.pChildList->Count(); i++ ){ + pNode = obj.pChildList->GetObject( i ); + if( pNode != NULL){ + switch(pNode->GetNodeType()){ + case XML_NODE_TYPE_ELEMENT: + AddChild( new XMLElement( *static_cast<XMLElement* >(pNode) ) ); break; + case XML_NODE_TYPE_DATA: + AddChild( new XMLData ( *static_cast<XMLData* > (pNode) ) ); break; + case XML_NODE_TYPE_COMMENT: + AddChild( new XMLComment( *static_cast<XMLComment* >(pNode) ) ); break; + case XML_NODE_TYPE_DEFAULT: + AddChild( new XMLDefault( *static_cast<XMLDefault* >(pNode) ) ); break; + default: fprintf(stdout,"XMLParentNode::XMLParentNode( const XMLParentNode& obj) strange obj"); + } + } + } + }else pChildList = NULL; +} +/*****************************************************************************/ +XMLParentNode& XMLParentNode::operator=(const XMLParentNode& obj){ +/*****************************************************************************/ + if(this!=&obj){ + XMLChildNode::operator=(obj); + if( pChildList ){ + RemoveAndDeleteAllChilds(); + delete pChildList; + pChildList = NULL; + } + if( obj.pChildList ){ + pChildList=new XMLChildNodeList(); + for ( ULONG i = 0; i < obj.pChildList->Count(); i++ ) + AddChild( obj.pChildList->GetObject( i ) ); + }else pChildList = NULL; + + } + return *this; +} +/*****************************************************************************/ +void XMLParentNode::AddChild( XMLChildNode *pChild ) +/*****************************************************************************/ +{ + if ( !pChildList ) + pChildList = new XMLChildNodeList(); + pChildList->Insert( pChild, LIST_APPEND ); +} + +/*****************************************************************************/ +void XMLParentNode::AddChild( XMLChildNode *pChild , int pos ) +/*****************************************************************************/ +{ + if ( !pChildList ) + pChildList = new XMLChildNodeList(); + pChildList->Insert( pChild, pos ); +} + +/*****************************************************************************/ +int XMLParentNode::GetPosition( ByteString id ){ +/*****************************************************************************/ + XMLElement* a; + + static const ByteString sEnusStr = ByteString(String::CreateFromAscii(ENGLISH_US_ISO).ToLowerAscii() , RTL_TEXTENCODING_ASCII_US ).ToLowerAscii(); + static const ByteString sDeStr = ByteString(String::CreateFromAscii(GERMAN_ISO2).ToLowerAscii() , RTL_TEXTENCODING_ASCII_US ).ToLowerAscii(); + + if ( pChildList ){ + for ( ULONG i = 0; i < pChildList->Count(); i++ ) { + XMLChildNode *pChild = pChildList->GetObject( i ); + if ( pChild->GetNodeType() == XML_NODE_TYPE_ELEMENT ){ + a = static_cast<XMLElement* >(pChild); + ByteString elemid( a->GetId() ); + elemid.ToLowerAscii(); + if ( elemid.Equals( id.ToLowerAscii() ) ){ + ByteString elemLID( a->GetLanguageId() ); + elemLID.ToLowerAscii(); + if( elemLID.Equals( sEnusStr) ) { + return i; + } + else if( elemLID.Equals( sDeStr) ) { + return i; + } + } + } + } + } + return -1; +} + +/*****************************************************************************/ +int XMLParentNode::RemoveChild( XMLElement *pRefElement ) +/*****************************************************************************/ +{ + XMLElement* a; + if ( pChildList ){ + for ( ULONG i = 0; i < pChildList->Count(); i++ ) { + XMLChildNode *pChild = pChildList->GetObject( i ); + if ( pChild->GetNodeType() == XML_NODE_TYPE_ELEMENT ){ + a = static_cast<XMLElement* >(pChild); + ByteString elemid( a->GetId() ); + elemid.ToLowerAscii(); + ByteString elemLID( a->GetLanguageId() ); + elemLID.ToLowerAscii(); + ByteString pRefLID( pRefElement->GetLanguageId() ); + pRefLID.ToLowerAscii(); + if ( elemid.Equals(pRefElement->GetId()) + && elemLID.Equals( pRefLID ) ) + { + if( pRefElement->ToOString().compareTo( a->ToOString() )==0 ){ + pChildList->Remove( i ); + delete a; // Test + return i; + } + } + } + + } + } + return -1; +} + +/*****************************************************************************/ +void XMLParentNode::RemoveAndDeleteAllChilds(){ +/*****************************************************************************/ + if ( pChildList ) { + for ( ULONG i = 0; i < pChildList->Count(); i++ ) + delete pChildList->GetObject( i ); + pChildList->Clear(); + } +} + +/*****************************************************************************/ +XMLElement *XMLParentNode::GetChildElement( XMLElement *pRefElement ) +/*****************************************************************************/ +{ + for ( ULONG i = 0; i < pChildList->Count(); i++ ) { + XMLChildNode *pChild = pChildList->GetObject( i ); + if ( pChild->GetNodeType() == XML_NODE_TYPE_ELEMENT ) + if ((( XMLElement * ) pChild )->GetName() == + pRefElement->GetName()) + { + XMLAttributeList *pList = pRefElement->GetAttributeList(); + if ( !pList ) + return ( XMLElement * ) pChild; + + BOOL bMatch = FALSE; + for ( ULONG j = 0; j < pList->Count() && bMatch; j++ ) { + XMLAttribute *pAttribute = pList->GetObject( j ); + XMLAttribute *pCandidate = + (( XMLElement * ) pChild )->GetAttribute( + *pAttribute ); + if ( !pCandidate || !pAttribute->IsEqual( *pCandidate )) + bMatch = FALSE; + } + if ( bMatch ) + return ( XMLElement * ) pChild; + } + } + return NULL; +} + +// +// class XMLFile +// + +/*****************************************************************************/ +USHORT XMLFile::GetNodeType() +/*****************************************************************************/ +{ + return XML_NODE_TYPE_FILE; +} + +/*****************************************************************************/ +BOOL XMLFile::Write( ByteString &aFilename ) +/*****************************************************************************/ +{ + + if ( aFilename.Len()) { + // retry harder if there is a NFS problem, + for( int x = 1 ; x < 3 ; x++ ){ // this looks strange...yes! + ofstream aFStream( aFilename.GetBuffer() , ios::out | ios::trunc ); + + if( !aFStream ) // From time to time the stream can not be opened the first time on NFS volumes, + { // I wasn't able to track this down. I think this is an NFS issue ..... + //cerr << "ERROR: - helpex - Can't write to tempfile " << aFilename.GetBuffer() << " No#" << x << "\n"; + TimeValue aTime; + aTime.Seconds = 3; + aTime.Nanosec = 0; + + osl::Thread::wait( aTime ); + } + else + { + // write out + Write( aFStream ); + aFStream.close(); + + // check! + DirEntry aTarget( aFilename ); + FileStat aFileStat( aTarget ); + + if( aFileStat.GetSize() < 1 ) + { + //retry + //cerr << "WARNING: - helpex - Can't create file " << aFilename.GetBuffer() << " No#" << x << "\n"; + aTarget.Kill(); + } + else + { + //everything ok! + return true; + } + } + } + cerr << "ERROR: - helpex - Can't create file " << aFilename.GetBuffer() << "\nPossible reason: Disk full ? Mounted NFS volume broken ? Wrong permissions ?\n"; + exit( -1 ); + } + cerr << "ERROR: - helpex - Empty file name\n"; + exit( -1 ); +} + + + +void XMLFile::WriteString( ofstream &rStream, const String &sString ) +{ + ByteString sText( sString, RTL_TEXTENCODING_UTF8 ); + rStream << sText.GetBuffer(); +} + + +BOOL XMLFile::Write( ofstream &rStream , XMLNode *pCur ) +{ + XMLUtil& xmlutil = XMLUtil::Instance(); + (void) xmlutil; + + if ( !pCur ) + Write( rStream, this ); + else { + switch( pCur->GetNodeType()) { + case XML_NODE_TYPE_FILE: { + if( GetChildList()) + for ( ULONG i = 0; i < GetChildList()->Count(); i++ ) + Write( rStream, GetChildList()->GetObject( i )); + } + break; + case XML_NODE_TYPE_ELEMENT: { + XMLElement *pElement = ( XMLElement * ) pCur; + rStream << "<"; + WriteString( rStream, pElement->GetName()); + if ( pElement->GetAttributeList()) + for ( ULONG j = 0; j < pElement->GetAttributeList()->Count(); j++ ) { + rStream << " "; + String sData(*pElement->GetAttributeList()->GetObject( j )); + xmlutil.QuotHTML( sData ); + WriteString( rStream , sData ); + rStream << "=\""; + sData=pElement->GetAttributeList()->GetObject( j )->GetValue(); + xmlutil.QuotHTML( sData ); + WriteString( rStream , sData ); + rStream << "\""; + } + if ( !pElement->GetChildList()) + rStream << "/>"; + else { + rStream << ">"; + for ( ULONG k = 0; k < pElement->GetChildList()->Count(); k++ ) + Write( rStream, pElement->GetChildList()->GetObject( k )); + rStream << "</"; + WriteString( rStream, pElement->GetName()); + rStream << ">"; + } + } + break; + case XML_NODE_TYPE_DATA: { + XMLData *pData = ( XMLData * ) pCur; + String sData( pData->GetData()); + xmlutil.QuotHTML( sData ); + WriteString( rStream, sData ); + } + break; + case XML_NODE_TYPE_COMMENT: { + XMLComment *pComment = ( XMLComment * ) pCur; + rStream << "<!--"; + WriteString( rStream, pComment->GetComment()); + rStream << "-->"; + } + break; + case XML_NODE_TYPE_DEFAULT: { + XMLDefault *pDefault = ( XMLDefault * ) pCur; + WriteString( rStream, pDefault->GetDefault()); + } + break; + } + } + return TRUE; +} + + +void XMLFile::Print( XMLNode *pCur, USHORT nLevel ) +{ + + if ( !pCur ) + Print( this ); + else { + switch( pCur->GetNodeType()) { + case XML_NODE_TYPE_FILE: { + if( GetChildList()) + for ( ULONG i = 0; i < GetChildList()->Count(); i++ ) + Print( GetChildList()->GetObject( i )); + } + break; + case XML_NODE_TYPE_ELEMENT: { + XMLElement *pElement = ( XMLElement * ) pCur; + + fprintf( stdout, "<%s", ByteString( pElement->GetName(), RTL_TEXTENCODING_UTF8 ).GetBuffer()); + if ( pElement->GetAttributeList()) + for ( ULONG j = 0; j < pElement->GetAttributeList()->Count(); j++ ){ + ByteString aAttrName( *pElement->GetAttributeList()->GetObject( j ), RTL_TEXTENCODING_UTF8 ); + if( !aAttrName.EqualsIgnoreCaseAscii( XML_LANG ) ) { + fprintf( stdout, " %s=\"%s\"", + aAttrName.GetBuffer(), + ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(), + RTL_TEXTENCODING_UTF8 ).GetBuffer()); + } + } + if ( !pElement->GetChildList()) + fprintf( stdout, "/>" ); + else { + fprintf( stdout, ">" ); + for ( ULONG k = 0; k < pElement->GetChildList()->Count(); k++ ) + Print( pElement->GetChildList()->GetObject( k ), nLevel + 1 ); + fprintf( stdout, "</%s>", ByteString( pElement->GetName(), RTL_TEXTENCODING_UTF8 ).GetBuffer()); + } + } + break; + case XML_NODE_TYPE_DATA: { + XMLData *pData = ( XMLData * ) pCur; + String sData = pData->GetData(); + fprintf( stdout, "%s", ByteString( sData, RTL_TEXTENCODING_UTF8 ).GetBuffer()); + } + break; + case XML_NODE_TYPE_COMMENT: { + XMLComment *pComment = ( XMLComment * ) pCur; + fprintf( stdout, "<!--%s-->", ByteString( pComment->GetComment(), RTL_TEXTENCODING_UTF8 ).GetBuffer()); + } + break; + case XML_NODE_TYPE_DEFAULT: { + XMLDefault *pDefault = ( XMLDefault * ) pCur; + fprintf( stdout, "%s", ByteString( pDefault->GetDefault(), RTL_TEXTENCODING_UTF8 ).GetBuffer()); + } + break; + } + } +} +XMLFile::~XMLFile() +{ + if( XMLStrings != NULL ){ + XMLHashMap::iterator pos = XMLStrings->begin(); + for( ; pos != XMLStrings->end() ; ++pos ){ + delete pos->second; // Check and delete content also ? + } + delete XMLStrings; + XMLStrings = NULL; + } +} +/*****************************************************************************/ +XMLFile::XMLFile( const String &rFileName ) // the file name, empty if created from memory stream +/*****************************************************************************/ + : XMLParentNode( NULL ), + sFileName ( rFileName ), + ID ( "id" ), + OLDREF ( "oldref" ), + XML_LANG ( "xml-lang" ), + XMLStrings ( NULL ) + +{ +// nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("bookmark_value"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("bookmark"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("variable"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("paragraph"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("alt"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("caption"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("title"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); + nodes_localize.insert( TagMap::value_type(ByteString(String::CreateFromAscii("link"),RTL_TEXTENCODING_ASCII_US) , TRUE) ); +} +/*****************************************************************************/ +void XMLFile::Extract( XMLFile *pCur ) +/*****************************************************************************/ +{ + if( XMLStrings != NULL ) delete XMLStrings; // Elements ? + + XMLStrings = new XMLHashMap(); + if ( !pCur ) + SearchL10NElements( this ); + else { + if( pCur->GetNodeType()==XML_NODE_TYPE_FILE) { + SearchL10NElements(pCur); + } + } +} + +/*****************************************************************************/ +void XMLFile::View(){ +/*****************************************************************************/ + XMLElement* cur; + for(XMLHashMap::iterator pos=XMLStrings->begin(); pos!=XMLStrings->end();++pos){ + fprintf(stdout,"\nid=%s\n",(pos->first).GetBuffer()); + LangHashMap* elem=pos->second; + for(LangHashMap::iterator pos2=elem->begin(); pos2!=elem->end();++pos2){ + fprintf( stdout,"\nlanguage=%s\n",(pos2->first).GetBuffer() ); + cur=pos2->second; + fprintf(stdout,"\n%s\n",((XMLElement*)cur)->ToOString().getStr()); + + } + } +} + +/*****************************************************************************/ +void XMLFile::InsertL10NElement( XMLElement* pElement ){ +/*****************************************************************************/ + ByteString tmpStr,id,oldref,language(""); + LangHashMap* elem; + + if( pElement->GetAttributeList() != NULL ){ + for ( ULONG j = 0; j < pElement->GetAttributeList()->Count(); j++ ){ + tmpStr=ByteString( *pElement->GetAttributeList()->GetObject( j ),RTL_TEXTENCODING_UTF8 ); + if( tmpStr.CompareTo(ID)==COMPARE_EQUAL ){ // Get the "id" Attribute + id = ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 ); + } + if( tmpStr.CompareTo( XML_LANG ) == COMPARE_EQUAL ){ // Get the "xml-lang" Attribute + language = ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 ); + } + + } + }else{ + fprintf(stdout,"XMLFile::InsertL10NElement: No AttributeList found"); + fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++"); + Print( pElement , 0 ); + fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + + XMLHashMap::iterator pos = XMLStrings->find( id ); + if( pos == XMLStrings->end() ){ // No instanze , create new one + elem = new LangHashMap(); + (*elem)[ language ]=pElement; + XMLStrings->insert( XMLHashMap::value_type( id , elem ) ); + order.push_back( id ); + }else{ // Already there + elem=pos->second; + if ( (*elem)[ language ] ) + { + fprintf(stdout,"Error: Duplicated entry. ID = %s LANG = %s in File %s\n", id.GetBuffer(), language.GetBuffer(), ByteString( sFullName,RTL_TEXTENCODING_ASCII_US ).GetBuffer() ); + exit( -1 ); + } + (*elem)[ language ]=pElement; + } +} +/*****************************************************************************/ +void XMLFile::showType(XMLParentNode* node){ +/*****************************************************************************/ + switch (node->GetNodeType()){ + case XML_NODE_TYPE_ELEMENT: fprintf(stdout,"ELEMENT\n") ;break; + case XML_NODE_TYPE_FILE: fprintf(stdout,"FILE\n") ;break; + case XML_NODE_TYPE_COMMENT: fprintf(stdout,"COMMENT\n") ;break; + case XML_NODE_TYPE_DATA: fprintf(stdout,"DATA\n") ;break; + case XML_NODE_TYPE_DEFAULT: fprintf(stdout,"DEFAULT\n") ;break; + default: break; + } +} +XMLFile::XMLFile() +/*****************************************************************************/ + : XMLParentNode( NULL ), + ID ( "id" ), + OLDREF ( "oldref" ), + XML_LANG ( "xml-lang" ), + XMLStrings ( NULL ){}; + + +XMLFile::XMLFile( const XMLFile& obj ) +/*****************************************************************************/ + : XMLParentNode( obj ), + sFileName ( obj.sFileName ), + ID ( "id" ), + OLDREF ( "oldref" ), + XML_LANG ( "xml-lang" ), + XMLStrings ( NULL ) +{ + if( this!=&obj ) + { + nodes_localize =obj.nodes_localize; + order =obj.order; + + } +} +/*****************************************************************************/ +XMLFile& XMLFile::operator=(const XMLFile& obj){ +/*****************************************************************************/ + if( this!=&obj ){ + + XMLParentNode::operator=(obj); + + nodes_localize =obj.nodes_localize; + order =obj.order; + + if( XMLStrings ) delete XMLStrings; + + if( obj.XMLStrings ) + { + XMLStrings = new XMLHashMap(); + for( XMLHashMap::iterator pos = obj.XMLStrings->begin() ; pos != obj.XMLStrings->end() ; ++pos ) + { + LangHashMap* elem=pos->second; + LangHashMap* newelem = new LangHashMap(); + for(LangHashMap::iterator pos2=elem->begin(); pos2!=elem->end();++pos2){ + (*newelem)[ pos2->first ] = new XMLElement( *pos2->second ); + printf("*"); + } + (*XMLStrings)[ pos->first ] = newelem; + } + } + } + printf("done!\n"); + return *this; +} + + +/*****************************************************************************/ +void XMLFile::SearchL10NElements( XMLParentNode *pCur , int pos) +/*****************************************************************************/ +{ + static const ByteString LOCALIZE("localize"); + static const ByteString THEID("id"); + bool bInsert = true; + if ( !pCur ) + SearchL10NElements( this ); + else { + switch( pCur->GetNodeType()) { + case XML_NODE_TYPE_FILE: { + XMLParentNode* pElement; + if( GetChildList()){ + for ( ULONG i = 0; i < GetChildList()->Count(); i++ ){ + pElement = (XMLParentNode*) GetChildList()->GetObject( i ); + if( pElement->GetNodeType() == XML_NODE_TYPE_ELEMENT ) SearchL10NElements( pElement , i); + } + } + } + break; + case XML_NODE_TYPE_ELEMENT: { + XMLElement *pElement = ( XMLElement * ) pCur; + ByteString sName(pElement->GetName(),RTL_TEXTENCODING_ASCII_US); + ByteString language,tmpStrVal,oldref; + if ( pElement->GetAttributeList()){ + for ( ULONG j = 0 , cnt = pElement->GetAttributeList()->Count(); j < cnt && bInsert; j++ ){ + const ByteString tmpStr( *pElement->GetAttributeList()->GetObject( j ),RTL_TEXTENCODING_UTF8 ); + if( tmpStr.CompareTo(THEID)==COMPARE_EQUAL ){ // Get the "id" Attribute + tmpStrVal=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 ); + //printf("Checking id = %s\n",tmpStrVal.GetBuffer() ); + } + if( tmpStr.CompareTo(LOCALIZE)==COMPARE_EQUAL ){ // Get the "localize" Attribute + bInsert=false; + } + if( tmpStr.CompareTo(XML_LANG)==COMPARE_EQUAL ){ // Get the "xml-lang" Attribute + language=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 ); + } + if( tmpStr.CompareTo(OLDREF)==COMPARE_EQUAL ){ // Get the "oldref" Attribute + oldref=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 ); + } + } + pElement->SetLanguageId ( language ); + pElement->SetId ( tmpStrVal.GetBuffer() ); + pElement->SetOldRef ( oldref ); + pElement->SetPos( pos ); + } + + if ( bInsert && ( nodes_localize.find( sName.ToLowerAscii() ) != nodes_localize.end() ) ) + InsertL10NElement(pElement); + else if ( bInsert && pElement->GetChildList() ){ + for ( ULONG k = 0; k < pElement->GetChildList()->Count(); k++ ) + SearchL10NElements( (XMLParentNode*) pElement->GetChildList()->GetObject( k ) , k); + } + } + break; + case XML_NODE_TYPE_DATA: { + } + break; + case XML_NODE_TYPE_COMMENT: { + } + break; + case XML_NODE_TYPE_DEFAULT: { + } + break; + } + } +} + +/*****************************************************************************/ +bool XMLFile::CheckExportStatus( XMLParentNode *pCur ) +/*****************************************************************************/ +{ + static bool bStatusExport = true; + const ByteString LOCALIZE("localize"); + const ByteString STATUS("status"); + const ByteString PUBLISH("PUBLISH"); + const ByteString DEPRECATED("DEPRECATED"); + + const ByteString TOPIC("topic"); + bool bInsert = true; + if ( !pCur ) + CheckExportStatus( this ); + else { + switch( pCur->GetNodeType()) { + case XML_NODE_TYPE_FILE: { + XMLParentNode* pElement; + if( GetChildList()){ + for ( ULONG i = 0; i < GetChildList()->Count(); i++ ){ + pElement = (XMLParentNode*) GetChildList()->GetObject( i ); + if( pElement->GetNodeType() == XML_NODE_TYPE_ELEMENT ) CheckExportStatus( pElement );//, i); + } + } + } + break; + case XML_NODE_TYPE_ELEMENT: { + XMLElement *pElement = ( XMLElement * ) pCur; + ByteString sName(pElement->GetName(),RTL_TEXTENCODING_ASCII_US); + if( sName.EqualsIgnoreCaseAscii( TOPIC ) ){ + if ( pElement->GetAttributeList()){ + for ( ULONG j = 0 , cnt = pElement->GetAttributeList()->Count(); j < cnt && bInsert; j++ ){ + const ByteString tmpStr( *pElement->GetAttributeList()->GetObject( j ),RTL_TEXTENCODING_UTF8 ); + if( tmpStr.EqualsIgnoreCaseAscii( STATUS ) ){ + ByteString tmpStrVal=ByteString( pElement->GetAttributeList()->GetObject( j )->GetValue(),RTL_TEXTENCODING_UTF8 ); + if( !tmpStrVal.EqualsIgnoreCaseAscii( PUBLISH ) && + !tmpStrVal.EqualsIgnoreCaseAscii( DEPRECATED )){ + bStatusExport = false; + } + } + + } + } + } + else if ( pElement->GetChildList() ){ + for ( ULONG k = 0; k < pElement->GetChildList()->Count(); k++ ) + CheckExportStatus( (XMLParentNode*) pElement->GetChildList()->GetObject( k ) );//, k); + } + } + break; + } + } + return bStatusExport; +} + +/*****************************************************************************/ +USHORT XMLElement::GetNodeType() +/*****************************************************************************/ +{ + return XML_NODE_TYPE_ELEMENT; +} + +/*****************************************************************************/ +XMLElement::XMLElement(const XMLElement& obj) +/*****************************************************************************/ + : + XMLParentNode ( obj ), + sElementName ( obj.sElementName ), + pAttributes ( NULL ), + project ( obj.project ), + filename ( obj.filename ), + id ( obj.id ), + sOldRef ( obj.sOldRef ), + resourceType ( obj.resourceType ), + languageId ( obj.languageId ), + nPos ( obj.nPos ) + +{ + if ( obj.pAttributes ){ + pAttributes = new XMLAttributeList(); + for ( ULONG i = 0; i < obj.pAttributes->Count(); i++ ) + AddAttribute( *obj.pAttributes->GetObject( i ) , obj.pAttributes->GetObject( i )->GetValue() ); + } +} + +/*****************************************************************************/ +XMLElement& XMLElement::operator=(const XMLElement& obj){ +/*****************************************************************************/ + if( this!=&obj ){ + XMLParentNode::operator=(obj); + sElementName =obj.sElementName; + project =obj.project; + filename =obj.filename; + id =obj.id; + sOldRef =obj.sOldRef; + resourceType =obj.resourceType; + languageId =obj.languageId; + nPos =obj.nPos; + + if ( pAttributes ){ + for ( ULONG i = 0; i < pAttributes->Count(); i++ ) + delete pAttributes->GetObject( i ); + delete pAttributes; + } + if ( obj.pAttributes ){ + pAttributes =new XMLAttributeList(); + for ( ULONG i = 0; i < obj.pAttributes->Count(); i++ ) + AddAttribute( *obj.pAttributes->GetObject( i ) , obj.pAttributes->GetObject( i )->GetValue() ); + } + } + return *this; +} + +/*****************************************************************************/ +void XMLElement::AddAttribute( const String &rAttribute, const String &rValue ) +/*****************************************************************************/ +{ + if ( !pAttributes ) + pAttributes = new XMLAttributeList(); + pAttributes->Insert( new XMLAttribute( rAttribute, rValue ), LIST_APPEND ); +} + +/*****************************************************************************/ +void XMLElement::ChangeLanguageTag( const String &rValue ){ +/*****************************************************************************/ + static const String rName = String::CreateFromAscii("xml-lang"); + SetLanguageId( ByteString(rValue,RTL_TEXTENCODING_UTF8) ); + if ( pAttributes ){ + for ( ULONG i = 0; i < pAttributes->Count(); i++ ){ + if ( *pAttributes->GetObject( i ) == rName ){ + pAttributes->GetObject( i )->setValue(rValue); + } + } + } + XMLChildNode* pNode = NULL; + XMLElement* pElem = NULL; + XMLChildNodeList* pCList = GetChildList(); + + if( pCList != NULL ){ + for ( ULONG i = 0; i < pCList->Count(); i++ ){ + pNode = pCList->GetObject( i ); + if( pNode != NULL && pNode->GetNodeType() == XML_NODE_TYPE_ELEMENT ){ + pElem = static_cast< XMLElement* >(pNode); + pElem->ChangeLanguageTag( rValue ); + pElem->SetLanguageId( ByteString(rValue,RTL_TEXTENCODING_UTF8) ); + pElem = NULL; + pNode = NULL; + } + } + pCList = NULL; + } +} +/*****************************************************************************/ +XMLAttribute *XMLElement::GetAttribute( const String &rName ) +/*****************************************************************************/ +{ + if ( pAttributes ) + for ( ULONG i = 0; i < pAttributes->Count(); i++ ) + if ( *pAttributes->GetObject( i ) == rName ) + return pAttributes->GetObject( i ); + + return NULL; +} + +/*****************************************************************************/ +XMLElement::~XMLElement() +/*****************************************************************************/ +{ + if ( pAttributes ) { + for ( ULONG i = 0; i < pAttributes->Count(); i++ ) + delete pAttributes->GetObject( i ); + + delete pAttributes; + pAttributes = NULL; + } +} +/*****************************************************************************/ +bool XMLElement::Equals(OUString refStr){ +/*****************************************************************************/ + return refStr.equals( ToOUString() ); +} + +/*****************************************************************************/ +OString XMLElement::ToOString(){ +/*****************************************************************************/ + OUString ouEmpty; + + OUStringBuffer* buffer = new OUStringBuffer(); + Print( this, *buffer , true ); + + OString result( (sal_Unicode* )buffer->getStr(), buffer->getLength() , RTL_TEXTENCODING_UTF8 ); + delete buffer; + return result; +} +/*****************************************************************************/ +OUString XMLElement::ToOUString(){ +/*****************************************************************************/ + OUStringBuffer* buffer = new OUStringBuffer(); + Print(this,*buffer,true); + OUString result=buffer->makeStringAndClear(); + String xy(result.getStr()); + result=OUString(xy); + delete buffer; + return result; +} +/*****************************************************************************/ +void XMLElement::Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement ){ +/*****************************************************************************/ + //YD FIXME somewhere COMMENT is defined as 4! + static const String _COMMENT = String::CreateFromAscii("comment"); + static const OUString XML_LANG ( OUString::createFromAscii("xml-lang") ); + + if(pCur!=NULL){ + if(rootelement){ + XMLElement *pElement = ( XMLElement * ) pCur; + if ( pElement->GetAttributeList()){ + if ( pElement->GetChildList()){ + XMLChildNode* tmp=NULL; + for ( ULONG k = 0; k < pElement->GetChildList()->Count(); k++ ){ + tmp=pElement->GetChildList()->GetObject( k ); + Print( tmp, buffer , false); + } + } + } + } + else{ + + switch( pCur->GetNodeType()) { + case XML_NODE_TYPE_ELEMENT: { + XMLElement *pElement = ( XMLElement * ) pCur; + + if( !pElement->GetName().EqualsIgnoreCaseAscii( _COMMENT ) ){ + buffer.append( OUString::createFromAscii("\\<") ); + buffer.append( pElement->GetName() ); + if ( pElement->GetAttributeList()){ + for ( ULONG j = 0; j < pElement->GetAttributeList()->Count(); j++ ){ + + OUString aAttrName( *pElement->GetAttributeList()->GetObject( j ) ); + if( !aAttrName.equalsIgnoreAsciiCase( XML_LANG ) ) { + buffer.append( OUString::createFromAscii(" ") ); + buffer.append( aAttrName ); + buffer.append( OUString::createFromAscii("=") ); + buffer.append( OUString::createFromAscii("\\\"") ); + buffer.append( pElement->GetAttributeList()->GetObject( j )->GetValue() ); + buffer.append( OUString::createFromAscii("\\\"") ); + } + } + } + if ( !pElement->GetChildList()) + buffer.append( OUString::createFromAscii("/\\>") ); + else { + buffer.append( OUString::createFromAscii("\\>") ); + XMLChildNode* tmp=NULL; + for ( ULONG k = 0; k < pElement->GetChildList()->Count(); k++ ){ + tmp=pElement->GetChildList()->GetObject( k ); + Print( tmp, buffer , false); + } + buffer.append( OUString::createFromAscii("\\</") ); + buffer.append( pElement->GetName() ); + buffer.append( OUString::createFromAscii("\\>") ); + } + } + } + break; + case XML_NODE_TYPE_DATA: { + XMLData *pData = ( XMLData * ) pCur; + String sData = pData->GetData(); + buffer.append( sData ); + } + break; + case XML_NODE_TYPE_COMMENT: { + XMLComment *pComment = ( XMLComment * ) pCur; + buffer.append( OUString::createFromAscii("<!--") ); + buffer.append( pComment->GetComment() ); + buffer.append( OUString::createFromAscii("-->") ); + } + break; + case XML_NODE_TYPE_DEFAULT: { + XMLDefault *pDefault = ( XMLDefault * ) pCur; + buffer.append( pDefault->GetDefault() ); + } + break; + } + } + }else { + fprintf(stdout,"\n#+------Error: NULL Pointer in XMLELement::Print------+#\n"); + return; + } +} + + +// +// class XMLData +// +/*****************************************************************************/ +XMLData::XMLData(const XMLData& obj) +/*****************************************************************************/ + : XMLChildNode( obj ), + sData( obj.sData ) , + isNewCreated ( obj.isNewCreated ){} + +/*****************************************************************************/ +XMLData& XMLData::operator=(const XMLData& obj){ +/*****************************************************************************/ + if( this!=&obj ){ + XMLChildNode::operator=( obj ); + sData = obj.sData; + isNewCreated = obj.isNewCreated; + } + return *this; +} +/*****************************************************************************/ +void XMLData::AddData( const String &rData) { +/*****************************************************************************/ + sData += rData; +} + +/*****************************************************************************/ +USHORT XMLData::GetNodeType() +/*****************************************************************************/ +{ + return XML_NODE_TYPE_DATA; +} + +// +// class XMLComment +// + +/*****************************************************************************/ +USHORT XMLComment::GetNodeType() +/*****************************************************************************/ +{ + return XML_NODE_TYPE_COMMENT; +} +/*****************************************************************************/ +XMLComment::XMLComment(const XMLComment& obj) +/*****************************************************************************/ + : XMLChildNode( obj ), + sComment( obj.sComment ){} + +/*****************************************************************************/ +XMLComment& XMLComment::operator=(const XMLComment& obj){ +/*****************************************************************************/ + if( this!=&obj ){ + XMLChildNode::operator=( obj ); + sComment = obj.sComment; + } + return *this; +} + +// +// class XMLDefault +// + +/*****************************************************************************/ +USHORT XMLDefault::GetNodeType() +/*****************************************************************************/ +{ + return XML_NODE_TYPE_DEFAULT; +} +/*****************************************************************************/ +XMLDefault::XMLDefault(const XMLDefault& obj) +/*****************************************************************************/ + : XMLChildNode( obj ), + sDefault( obj.sDefault){} + +/*****************************************************************************/ +XMLDefault& XMLDefault::operator=(const XMLDefault& obj){ +/*****************************************************************************/ + if( this!=&obj ){ + XMLChildNode::operator=( obj ); + sDefault = obj.sDefault; + } + return *this; +} + + +// +// class SimpleXMLParser +// + +#define XML_CHAR_TO_OUSTRING(x) OStringToOUString(OString(x), RTL_TEXTENCODING_UTF8) +#define XML_CHAR_N_TO_OUSTRING(x,n) OStringToOUString(OString(x,n), RTL_TEXTENCODING_UTF8 ) + + +/*****************************************************************************/ +SimpleXMLParser::SimpleXMLParser() +/*****************************************************************************/ + : pXMLFile( NULL ) +{ + aParser = XML_ParserCreate( NULL ); + XML_SetUserData( aParser, this ); + XML_SetElementHandler( aParser, (XML_StartElementHandler) StartElementHandler, (XML_EndElementHandler) EndElementHandler ); + XML_SetCharacterDataHandler( aParser, (XML_CharacterDataHandler) CharacterDataHandler ); + XML_SetCommentHandler( aParser, (XML_CommentHandler) CommentHandler ); + XML_SetDefaultHandler( aParser, (XML_DefaultHandler) DefaultHandler ); +} + +/*****************************************************************************/ +SimpleXMLParser::~SimpleXMLParser() +/*****************************************************************************/ +{ + XML_ParserFree( aParser ); +} + +/*****************************************************************************/ +void SimpleXMLParser::StartElementHandler( + void *userData, const XML_Char *name, const XML_Char **atts ) +/*****************************************************************************/ +{ + (( SimpleXMLParser * ) userData )->StartElement( name, atts ); +} + + +/*****************************************************************************/ +void SimpleXMLParser::EndElementHandler( + void *userData, const XML_Char *name ) +/*****************************************************************************/ +{ + (( SimpleXMLParser * ) userData )->EndElement( name ); +} + +/*****************************************************************************/ +void SimpleXMLParser::CharacterDataHandler( + void *userData, const XML_Char *s, int len ) +/*****************************************************************************/ +{ + (( SimpleXMLParser * ) userData )->CharacterData( s, len ); +} + +/*****************************************************************************/ +void SimpleXMLParser::CommentHandler( + void *userData, const XML_Char *data ) +/*****************************************************************************/ +{ + (( SimpleXMLParser * ) userData )->Comment( data ); +} + +/*****************************************************************************/ +void SimpleXMLParser::DefaultHandler( + void *userData, const XML_Char *s, int len ) +/*****************************************************************************/ +{ + (( SimpleXMLParser * ) userData )->Default( s, len ); +} + +/*****************************************************************************/ +void SimpleXMLParser::StartElement( + const XML_Char *name, const XML_Char **atts ) +/*****************************************************************************/ +{ + String sElementName = String( XML_CHAR_TO_OUSTRING( name )); + XMLElement *pElement = new XMLElement( sElementName, ( XMLParentNode * ) pCurNode ); + pCurNode = pElement; + pCurData = NULL; + + int i = 0; + while( atts[i] ) { + pElement->AddAttribute( + String( XML_CHAR_TO_OUSTRING( atts[ i ] )), + String( XML_CHAR_TO_OUSTRING( atts[ i + 1 ] ))); + i += 2; + } +} + +/*****************************************************************************/ +void SimpleXMLParser::EndElement( const XML_Char *name ) +/*****************************************************************************/ +{ + // This variable is not used at all, but the the sax C interface can't be changed + // To prevent warnings this dummy assignment is used + // +++ + (void) name; + + pCurNode = pCurNode->GetParent(); + pCurData = NULL; +} + +/*****************************************************************************/ +void SimpleXMLParser::CharacterData( + const XML_Char *s, int len ) +/*****************************************************************************/ +{ + if ( !pCurData ){ + String x=String( XML_CHAR_N_TO_OUSTRING( s, len )); + XMLUtil::UnQuotHTML(x); + pCurData = new XMLData( x , pCurNode ); + }else{ + String x=String( XML_CHAR_N_TO_OUSTRING( s, len )); + XMLUtil::UnQuotHTML(x); + pCurData->AddData( x ); + + } +} + +/*****************************************************************************/ +void SimpleXMLParser::Comment( + const XML_Char *data ) +/*****************************************************************************/ +{ + pCurData = NULL; + new XMLComment( String( XML_CHAR_TO_OUSTRING( data )), pCurNode ); +} + +/*****************************************************************************/ +void SimpleXMLParser::Default( + const XML_Char *s, int len ) +/*****************************************************************************/ +{ + pCurData = NULL; + new XMLDefault( + String( XML_CHAR_N_TO_OUSTRING( s, len )), pCurNode ); +} + +/*****************************************************************************/ +XMLFile *SimpleXMLParser::Execute( const String &rFullFileName , const String &rFileName, XMLFile* pXMLFileIn ) +/*****************************************************************************/ +{ +// printf("DBG: SimpleXMLParser::Execute( %s )", ByteString( rFileName , RTL_TEXTENCODING_ASCII_US ).GetBuffer() ); + aErrorInformation.eCode = XML_ERROR_NONE; + aErrorInformation.nLine = 0; + aErrorInformation.nColumn = 0; + aErrorInformation.sMessage = String::CreateFromAscii( "ERROR: Unable to open file " ); + aErrorInformation.sMessage += rFileName; + + SvFileStream aStream( rFileName, STREAM_STD_READ ); + + if ( !aStream.IsOpen()) + return NULL; + + SvMemoryStream aMemStream; + aStream >> aMemStream; + aMemStream.Seek( 0 ); + + aStream.Close(); + + pXMLFile = pXMLFileIn; + pXMLFile->SetName( rFileName ); + pXMLFile->SetFullName( rFullFileName ); + + return Execute( &aMemStream ); +} + +/*****************************************************************************/ +XMLFile *SimpleXMLParser::Execute( SvMemoryStream *pStream ) +/*****************************************************************************/ +{ + if ( !pXMLFile ) + pXMLFile = new XMLFile( String()); + + pCurNode = pXMLFile; + pCurData = NULL; + + ULONG nPos = pStream->Tell(); + pStream->Seek( STREAM_SEEK_TO_END ); + + aErrorInformation.eCode = XML_ERROR_NONE; + aErrorInformation.nLine = 0; + aErrorInformation.nColumn = 0; + if ( pXMLFile->GetName().Len()) { + aErrorInformation.sMessage = String::CreateFromAscii( "File " ); + aErrorInformation.sMessage += pXMLFile->GetName(); + aErrorInformation.sMessage += String::CreateFromAscii( " parsed succesfully" ); + } + else + aErrorInformation.sMessage = String::CreateFromAscii( "XML-File parsed successfully" ); + + if ( !XML_Parse( + aParser, ( char * ) pStream->GetData() + nPos, pStream->Tell() - nPos, TRUE )) + { + aErrorInformation.eCode = XML_GetErrorCode( aParser ); + aErrorInformation.nLine = XML_GetErrorLineNumber( aParser ); + aErrorInformation.nColumn = XML_GetErrorColumnNumber( aParser ); + + aErrorInformation.sMessage = String::CreateFromAscii( "ERROR: " ); + if ( pXMLFile->GetName().Len()) + aErrorInformation.sMessage += pXMLFile->GetName(); + else + aErrorInformation.sMessage += String::CreateFromAscii( "XML-File" ); + aErrorInformation.sMessage += String::CreateFromAscii( " (" ); + aErrorInformation.sMessage += String::CreateFromInt64( aErrorInformation.nLine ); + aErrorInformation.sMessage += String::CreateFromAscii( "," ); + aErrorInformation.sMessage += String::CreateFromInt64( aErrorInformation.nColumn ); + aErrorInformation.sMessage += String::CreateFromAscii( "): " ); + + switch( aErrorInformation.eCode ) { + case XML_ERROR_NO_MEMORY: aErrorInformation.sMessage += String::CreateFromAscii( "No memory" ); break; + case XML_ERROR_SYNTAX: aErrorInformation.sMessage += String::CreateFromAscii( "Syntax" ); break; + case XML_ERROR_NO_ELEMENTS: aErrorInformation.sMessage += String::CreateFromAscii( "No elements" ); break; + case XML_ERROR_INVALID_TOKEN: aErrorInformation.sMessage += String::CreateFromAscii( "Invalid token" ); break; + case XML_ERROR_UNCLOSED_TOKEN: aErrorInformation.sMessage += String::CreateFromAscii( "Unclosed token" ); break; + case XML_ERROR_PARTIAL_CHAR: aErrorInformation.sMessage += String::CreateFromAscii( "Partial char" ); break; + case XML_ERROR_TAG_MISMATCH: aErrorInformation.sMessage += String::CreateFromAscii( "Tag mismatch" ); break; + case XML_ERROR_DUPLICATE_ATTRIBUTE: aErrorInformation.sMessage += String::CreateFromAscii( "Dublicat attribute" ); break; + case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: aErrorInformation.sMessage += String::CreateFromAscii( "Junk after doc element" ); break; + case XML_ERROR_PARAM_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Param entity ref" ); break; + case XML_ERROR_UNDEFINED_ENTITY: aErrorInformation.sMessage += String::CreateFromAscii( "Undefined entity" ); break; + case XML_ERROR_RECURSIVE_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Recursive entity ref" ); break; + case XML_ERROR_ASYNC_ENTITY: aErrorInformation.sMessage += String::CreateFromAscii( "Async_entity" ); break; + case XML_ERROR_BAD_CHAR_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Bad char ref" ); break; + case XML_ERROR_BINARY_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Binary entity" ); break; + case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: aErrorInformation.sMessage += String::CreateFromAscii( "Attribute external entity ref" ); break; + case XML_ERROR_MISPLACED_XML_PI: aErrorInformation.sMessage += String::CreateFromAscii( "Misplaced xml pi" ); break; + case XML_ERROR_UNKNOWN_ENCODING: aErrorInformation.sMessage += String::CreateFromAscii( "Unknown encoding" ); break; + case XML_ERROR_INCORRECT_ENCODING: aErrorInformation.sMessage += String::CreateFromAscii( "Incorrect encoding" ); break; + case XML_ERROR_UNCLOSED_CDATA_SECTION: aErrorInformation.sMessage += String::CreateFromAscii( "Unclosed cdata section" ); break; + case XML_ERROR_EXTERNAL_ENTITY_HANDLING: aErrorInformation.sMessage += String::CreateFromAscii( "External entity handling" ); break; + case XML_ERROR_NOT_STANDALONE: aErrorInformation.sMessage += String::CreateFromAscii( "Not standalone" ); break; + case XML_ERROR_NONE: break; + default: + break; + + } + delete pXMLFile; + pXMLFile = NULL; + } + pStream->Seek( nPos ); + + return pXMLFile; +} + +/*****************************************************************************/ +void XMLUtil::QuotHTML( String &rString ) +/*****************************************************************************/ +{ + OUStringBuffer sReturn; + static const String LT(String::CreateFromAscii("<")); + static const String QLT(String::CreateFromAscii("<")); + static const String GT(String::CreateFromAscii(">")); + static const String QGT(String::CreateFromAscii(">")); + static const String QUOT(String::CreateFromAscii("\\")); + static const String QQUOT(String::CreateFromAscii(""")); + static const String APOS(String::CreateFromAscii("\"")); + static const String QAPOS(String::CreateFromAscii("'")); + static const String AMP(String::CreateFromAscii("&")); + static const String QAMP(String::CreateFromAscii("&")); + static const String SLASH(String::CreateFromAscii("\\")); + + for ( USHORT i = 0; i < rString.Len(); i++) { + if ( i < rString.Len()) { + switch ( rString.GetChar( i )) { + case '\\': if( i+1 <= rString.Len() ){ + switch( rString.GetChar( i+1 ) ){ + case '<': sReturn.append( LT );i++;break; + case '>': sReturn.append( GT );i++;break; + case '\\': sReturn.append( QUOT );i++;break; + case '\"': sReturn.append( APOS );i++;break; + //case '\'': sReturn += "\'";i++;break; + //case '&' : sRetrun += "&";i++;break; + default: sReturn.append( SLASH );break; + + } + } + break; + + case '<': + sReturn.append( QLT ); + break; + + case '>': + sReturn.append( QGT ); + break; + + case '\"': + sReturn.append( QQUOT ); + break; + +/* case '\'': + sReturn += "'"; + break; +*/ + case '&': + if ( + ( ( i + 4 ) < rString.Len()) && + ( String( rString.Copy( i, 5 ) ).Equals( QAMP ) ) + ) + sReturn.append( rString.GetChar( i ) ); + else + sReturn.append( QAMP ); + break; + + default: + sReturn.append( rString.GetChar( i ) ); + break; + } + } + } + rString = String( sReturn.makeStringAndClear() ); +} + +void XMLUtil::UnQuotHTML( String &rString ){ + UnQuotData( rString ); +} + +void XMLUtil::UnQuotData( String &rString_in ){ + ByteString sReturn; + ByteString sString( rString_in , RTL_TEXTENCODING_UTF8 ); + while ( sString.Len()) { + if ( sString.Copy( 0, 1 ) == "\\" ) { + sReturn += "\\\\"; + sString.Erase( 0, 1 ); + } + else if ( sString.Copy( 0, 5 ) == "&" ) { + sReturn += "&"; + sString.Erase( 0, 5 ); + } + else if ( sString.Copy( 0, 4 ) == "<" ) { + sReturn += "<"; + sString.Erase( 0, 4 ); + } + else if ( sString.Copy( 0, 4 ) == ">" ) { + sReturn += ">"; + sString.Erase( 0, 4 ); + } + else if ( sString.Copy( 0, 6 ) == """ ) { + sReturn += "\""; + sString.Erase( 0, 6 ); + } + else if ( sString.Copy( 0, 6 ) == "'" ) { + sReturn += "\'"; + sString.Erase( 0, 6 ); + } + else { + sReturn += sString.GetChar( 0 ); + sString.Erase( 0, 1 ); + } + } + rString_in = String(sReturn , RTL_TEXTENCODING_UTF8 ); + + +} + +XMLUtil::XMLUtil(){ +} + + +/*****************************************************************************/ +void XMLUtil::dump(){ +/*****************************************************************************/ + int cnt=1; + printf("size=%lu\n",static_cast<unsigned long>(lMap.size())); + for(HashMap::iterator pos = lMap.begin(); pos != lMap.end() ; ++pos){ + fprintf(stdout,"key=%s , value=%d , no=%d\n",pos->first.GetBuffer(),pos->second,cnt++); + } +} +/*****************************************************************************/ +XMLUtil& XMLUtil::Instance(){ +/*****************************************************************************/ + static XMLUtil instance; + return instance; +} +/*****************************************************************************/ +XMLUtil::~XMLUtil(){} +/*****************************************************************************/ +/*****************************************************************************/ +ByteString XMLUtil::GetIsoLangByIndex( USHORT nIndex ) +/*****************************************************************************/ +{ + if(nIndex > 0 && MAX_LANGUAGES >= nIndex ) + return isoArray[nIndex]; + return ""; +} + diff --git a/transex3/source/xrm_yy_wrapper.c b/transex3/source/xrm_yy_wrapper.c new file mode 100644 index 000000000000..6a304d0d09dc --- /dev/null +++ b/transex3/source/xrm_yy_wrapper.c @@ -0,0 +1,2 @@ +// Helper to suppress warnings in lex generated c code, see #i57362# +#include "xrm_yy.c" diff --git a/transex3/source/xrmlex.l b/transex3/source/xrmlex.l new file mode 100644 index 000000000000..efc8bf1f7d91 --- /dev/null +++ b/transex3/source/xrmlex.l @@ -0,0 +1,228 @@ +%{ +/* + * lexer for parsing xml-property source files (*.xml) + * + */ + + +/* enlarge token buffer to tokenize whole strings */ +#undef YYLMAX +#define YYLMAX 64000 + +/* to enable debug output define LEXDEBUG */ +#define LEXDEBUG 1 +#ifdef LEXDEBUG +#define OUTPUT fprintf +#else +#define OUTPUT(Par1,Par2); +#endif + +/* table of possible token ids */ +#include "tokens.h" +#include <stdlib.h> +#include <stdio.h> + +#if defined __GNUC__ +#pragma GCC system_header +#elif defined __SINPRO_CC +#pragma disable_warn +#elif defined _MSC_VER +#pragma warning(push, 1) +#endif + +/* external functions (C++ code, declared as extren "C" */ +extern int WorkOnTokenSet( int, char* ); +extern int Argument( char * ); +extern int InitXrmExport( char * , char * ); +extern int EndXrmExport(); +extern int GetError(); +extern int SetError(); +extern char *GetOutputFile( int argc, char* argv[]); +extern FILE *GetXrmFile(); +extern int isQuiet(); +extern void removeTempFile(); +extern char* getFilename(); + +/* forwards */ +void YYWarning(); + +int bText=0; +%} + +%p 24000 +%e 1200 +%n 500 + +%% + +"<Readme"[^\>]*\> { + WorkOnTokenSet( XRM_README_START, yytext ); +} + +"</Readme>" { + WorkOnTokenSet( XRM_README_END, yytext ); +} + +"<apochelp"[^\>]*\> { + WorkOnTokenSet( XRM_README_START, yytext ); +} + +"</apochelp>" { + WorkOnTokenSet( XRM_README_END, yytext ); +} + +"<Section"[^\>]*\> { + WorkOnTokenSet( XRM_SECTION_START, yytext ); +} + +"</Section>" { + WorkOnTokenSet( XRM_SECTION_END, yytext ); +} + +"<Paragraph"[^\>]*\> { + WorkOnTokenSet( XRM_PARAGRAPH_START, yytext ); +} + +"</Paragraph>" { + WorkOnTokenSet( XRM_PARAGRAPH_END, yytext ); +} + +"<Text"[^\>]*\> { + WorkOnTokenSet( XRM_TEXT_START, yytext ); +} + +"</Text>" { + WorkOnTokenSet( XRM_TEXT_END, yytext ); +} + +"<List"[^\>]*\> { + WorkOnTokenSet( XRM_LIST_START, yytext ); +} + +"</List>" { + WorkOnTokenSet( XRM_LIST_END, yytext ); +} + +"<!--" { + char c1 = 0, c2 = 0, c3 = input(); + char pChar[2]; + pChar[1] = 0x00; + pChar[0] = c3; + + WorkOnTokenSet( COMMEND, yytext ); + WorkOnTokenSet( COMMEND, pChar ); + + for(;;) { + if ( c3 == EOF ) + break; + if ( c1 == '-' && c2 == '-' && c3 == '>' ) + break; + c1 = c2; + c2 = c3; + c3 = input(); + pChar[0] = c3; + WorkOnTokenSet( COMMEND, pChar ); + } +} + +.|\n { + if ( bText == 1 ) + WorkOnTokenSet( XML_TEXTCHAR, yytext ); + else + WorkOnTokenSet( UNKNOWNCHAR, yytext ); +} + + +%% + +/*****************************************************************************/ +int yywrap(void) +/*****************************************************************************/ +{ + return 1; +} + +/*****************************************************************************/ +void YYWarning( char *s ) +/*****************************************************************************/ +{ + /* write warning to stderr */ + fprintf( stderr, + "Warning: \"%s\" in line %d: \"%s\"\n", s, yylineno, yytext ); +} + +/*****************************************************************************/ +#ifdef GCC +void yyerror ( char *s, ... ) +#else +void yyerror ( char *s ) +#endif +/*****************************************************************************/ +{ + /* write error to stderr */ + fprintf( stderr, + "Error: \"%s\" in line %d: \"%s\"\n", s, yylineno, yytext ); + SetError(); +} + +/*****************************************************************************/ +int +#ifdef WNT +_cdecl +#endif +main( int argc, char* argv[]) +/*****************************************************************************/ +{ + /* error level */ + int nRetValue = 0; + char *pOutput; + FILE *pFile; + + pOutput = GetOutputFile( argc, argv ); + if( !isQuiet() ){ + fprintf( stdout, "\nXrmEx 0.9 Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.\n" ); + fprintf( stdout, "======================================================================\n" ); + } + + if ( !pOutput ) { + fprintf( stdout, "Syntax: XRMEX[-p Prj][-r PrjRoot]-i FileIn [-o FileOut][-m DataBase][-e][-b][-u][-NOUTF8][-L l1,l2,...]\n" ); + fprintf( stdout, " Prj: Project\n" ); + fprintf( stdout, " PrjRoot: Path to project root (..\\.. etc.)\n" ); + fprintf( stdout, " FileIn: Source files (*.src)\n" ); + fprintf( stdout, " FileOut: Destination file (*.*)\n" ); + fprintf( stdout, " DataBase: Mergedata (*.sdf)\n" ); + fprintf( stdout, " -e: Disable writing errorlog\n" ); + fprintf( stdout, " -b: Break when Token \"HelpText\" found in source\n" ); + fprintf( stdout, " -u: [english] and [german] are allowed, Id is Taken from DataBase \n" ); + fprintf( stdout, " -NOUTF8: disable UTF8 as language independent encoding\n" ); + fprintf( stdout, " -L: Restrict the handled languages. l1,l2,... are elements of (de,en-US,es...)\n" ); + fprintf( stdout, " A fallback language can be defined like this: l1=f1.\n" ); + fprintf( stdout, " f1, f2,... are also elements of (de,en-US,es...)\n" ); + fprintf( stdout, " Example: -L en-US,es=de\n" ); + fprintf( stdout, " Restriction to es and en-US, de will be fallback for 99\n" ); +// fprintf( stdout, " -ISO99: IsoCode is the full qualified ISO language code for language 99" ); + return 1; + } + pFile = GetXrmFile(); + InitXrmExport( pOutput , getFilename() ); + + if ( !pFile ) + return 1; + + yyin = pFile; + + /* create global instance of class XmlExport */ + //InitXrmExport( pOutput ); + + /* start parser */ + yylex(); + + /* get error info. and end export */ + nRetValue = GetError(); + EndXrmExport(); + + if( !isQuiet() ) fprintf( stdout, "\n===================================\n\n" ); + removeTempFile(); + /* return error level */ + return nRetValue; +} diff --git a/transex3/source/xrmmerge.cxx b/transex3/source/xrmmerge.cxx new file mode 100644 index 000000000000..4daf94e2357a --- /dev/null +++ b/transex3/source/xrmmerge.cxx @@ -0,0 +1,758 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xrmmerge.cxx,v $ + * $Revision: 1.20 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_transex3.hxx" +#include <stdio.h> +#include <tools/string.hxx> +#include <tools/fsys.hxx> + +// local includes +#include "export.hxx" +#include "xrmmerge.hxx" +#include "utf8conv.hxx" +#include "tokens.h" +#include <iostream> +#include <vector> + +using namespace std; + +extern "C" { int yyerror( char * ); } +extern "C" { int YYWarning( char * ); } + +// defines to parse command line +#define STATE_NON 0x0001 +#define STATE_INPUT 0x0002 +#define STATE_OUTPUT 0x0003 +#define STATE_PRJ 0x0004 +#define STATE_ROOT 0x0005 +#define STATE_MERGESRC 0x0006 +#define STATE_ERRORLOG 0x0007 +#define STATE_UTF8 0x000B +#define STATE_LANGUAGES 0x000C +#define STATE_ISOCODE99 0x000D + +// set of global variables +BOOL bEnableExport; +BOOL bMergeMode; +BOOL bErrorLog; +BOOL bUTF8; +bool bQuiet; +ByteString sPrj; +ByteString sPrjRoot; +ByteString sInputFileName; +ByteString sActFileName; +ByteString sOutputFile; +ByteString sMergeSrc; +String sUsedTempFile; +XRMResParser *pParser = NULL; + +extern "C" { +// the whole interface to lexer is in this extern "C" section + +/*****************************************************************************/ +extern char *GetOutputFile( int argc, char* argv[]) +/*****************************************************************************/ +{ + bEnableExport = FALSE; + bMergeMode = FALSE; + bErrorLog = TRUE; + bUTF8 = TRUE; + sPrj = ""; + sPrjRoot = ""; + sInputFileName = ""; + sActFileName = ""; + Export::sLanguages = ""; + bQuiet = false; + USHORT nState = STATE_NON; + BOOL bInput = FALSE; + + // parse command line + for( int i = 1; i < argc; i++ ) { + if ( ByteString( argv[ i ] ).ToUpperAscii() == "-I" ) { + nState = STATE_INPUT; // next token specifies source file + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-O" ) { + nState = STATE_OUTPUT; // next token specifies the dest file + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-P" ) { + nState = STATE_PRJ; // next token specifies the cur. project + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-R" ) { + nState = STATE_ROOT; // next token specifies path to project root + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-M" ) { + nState = STATE_MERGESRC; // next token specifies the merge database + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-QQ" ) { + bQuiet = true; + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-E" ) { + nState = STATE_ERRORLOG; + bErrorLog = FALSE; + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-UTF8" ) { + nState = STATE_UTF8; + bUTF8 = TRUE; + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-NOUTF8" ) { + nState = STATE_UTF8; + bUTF8 = FALSE; + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-L" ) { + nState = STATE_LANGUAGES; + } + else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-ISO99" ) { + nState = STATE_ISOCODE99; + } + else { + switch ( nState ) { + case STATE_NON: { + return NULL; // no valid command line + } + case STATE_INPUT: { + sInputFileName = argv[ i ]; + bInput = TRUE; // source file found + } + break; + case STATE_OUTPUT: { + sOutputFile = argv[ i ]; // the dest. file + } + break; + case STATE_PRJ: { + sPrj = ByteString( argv[ i ]); + } + break; + case STATE_ROOT: { + sPrjRoot = ByteString( argv[ i ]); // path to project root + } + break; + case STATE_MERGESRC: { + sMergeSrc = ByteString( argv[ i ]); + bMergeMode = TRUE; // activate merge mode, cause merge database found + } + break; + case STATE_LANGUAGES: { + Export::sLanguages = ByteString( argv[ i ]); + } + break; + case STATE_ISOCODE99: { + Export::sIsoCode99 = ByteString( argv[ i ]); + } + break; + } + } + } + + if ( bInput ) { + // command line is valid + bEnableExport = TRUE; + char *pReturn = new char[ sOutputFile.Len() + 1 ]; + strcpy( pReturn, sOutputFile.GetBuffer()); // #100211# - checked + return pReturn; + } + + // command line is not valid + return NULL; +} +void removeTempFile(){ + if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){ + DirEntry aTempFile( sUsedTempFile ); + aTempFile.Kill(); + } +} +/*****************************************************************************/ +int InitXrmExport( char *pOutput , char* pFilename) +/*****************************************************************************/ +{ + // instanciate Export + ByteString sOutput( pOutput ); + ByteString sFilename( pFilename ); + Export::InitLanguages( false ); + + if ( bMergeMode ) + pParser = new XRMResMerge( sMergeSrc, sOutputFile, sFilename ); + else if ( sOutputFile.Len()) { + pParser = new XRMResExport( sOutputFile, sPrj, sActFileName ); + } + + return 1; +} + +int isQuiet(){ + if( bQuiet ) return 1; + else return 0; +} +/*****************************************************************************/ +int EndXrmExport() +/*****************************************************************************/ +{ + delete pParser; + return 1; +} +extern const char* getFilename() +{ + return sInputFileName.GetBuffer(); +} +/*****************************************************************************/ +extern FILE *GetXrmFile() +/*****************************************************************************/ +{ + FILE *pFile = 0; + // look for valid filename + if ( sInputFileName.Len()) { + if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){ + DirEntry aTempFile = Export::GetTempFile(); + DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) ); + aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE ); + String sTempFile = aTempFile.GetFull(); + Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) ); + pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" ); + sUsedTempFile = sTempFile; + }else{ + // able to open file? + pFile = fopen( sInputFileName.GetBuffer(), "r" ); + sUsedTempFile = String::CreateFromAscii(""); + } + if ( !pFile ){ + fprintf( stderr, "Error: Could not open file %s\n", + sInputFileName.GetBuffer()); + } + else { + // this is a valid file which can be opened, so + // create path to project root + DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US )); + aEntry.ToAbs(); + ByteString sFullEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); + aEntry += DirEntry( sPrjRoot ); + ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US ); + + // create file name, beginnig with project root + // (e.g.: source\ui\src\menue.src) + sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 ); + + if( !bQuiet ) + fprintf( stdout, "\nProcessing File %s ...\n", sInputFileName.GetBuffer()); + + sActFileName.SearchAndReplaceAll( "/", "\\" ); + + return pFile; + } + } + // this means the file could not be opened + return NULL; +} + +/*****************************************************************************/ +int WorkOnTokenSet( int nTyp, char *pTokenText ) +/*****************************************************************************/ +{ +// printf("Typ = %d , text = '%s'\n",nTyp , pTokenText ); + pParser->Execute( nTyp, pTokenText ); + + return 1; +} + +/*****************************************************************************/ +int SetError() +/*****************************************************************************/ +{ + pParser->SetError(); + return 1; +} +} + +extern "C" { +/*****************************************************************************/ +int GetError() +/*****************************************************************************/ +{ + return pParser->GetError(); +} +} + +// +// class XRMResParser +// + + +/*****************************************************************************/ +XRMResParser::XRMResParser() +/*****************************************************************************/ + : bError( FALSE ), + bText( FALSE ) +{ + aLanguages = Export::GetLanguages(); +} + +/*****************************************************************************/ +XRMResParser::~XRMResParser() +/*****************************************************************************/ +{ +} + +/*****************************************************************************/ +int XRMResParser::Execute( int nToken, char * pToken ) +/*****************************************************************************/ +{ + ByteString rToken( pToken ); + + switch ( nToken ) { + case XRM_README_START: + sLID = ""; + sGID = GetAttribute( rToken, "name" ); + break; + + case XRM_README_END: + sGID = ""; + break; + + case XRM_SECTION_START: + sLID = ""; + sGID += "."; + sGID += GetAttribute( rToken, "id" ); + //sLocalized = "1"; + + //sLocalized = "X:"; + sLocalized = true; + break; + + case XRM_SECTION_END: + sGID = sGID.GetToken( 0, '.' ); + break; + + case XRM_PARAGRAPH_START: + sLID = ""; + sGID += "."; + sGID += GetAttribute( rToken, "id" ); + if ( GetAttribute( rToken, "localized" ) == "false" ) +// sLocalized += "0"; + sLocalized = false; + else +// sLocalized += "1"; + sLocalized = true; + break; + + case XRM_PARAGRAPH_END: { + if ( sLID.Len()) + EndOfText( sCurrentOpenTag, sCurrentCloseTag ); + ByteString sTmp = sGID; + sGID = ""; + for ( USHORT i = 0; i + 1 < sTmp.GetTokenCount( '.' ); i++ ) { + if ( sGID.Len()) + sGID += "."; + sGID += sTmp.GetToken( i, '.' ); + } + //sLocalized = sLocalized.Copy( 0, sLocalized.Len() - 1 ); + } + break; + + case XRM_TEXT_START: +// if ( sLocalized.GetChar( sLocalized.Len() - 1 ) == '1' ) { + if ( sLocalized ) { + + ByteString sNewLID = GetAttribute( rToken, "id" ); + if ( sNewLID != sLID ) { + EndOfText( sCurrentOpenTag, sCurrentCloseTag ); + sLID = sNewLID; + } + bText = TRUE; + sCurrentText = ""; + sCurrentOpenTag = rToken; + Output( rToken ); + } + break; + + case XRM_TEXT_END: { +// if ( sLocalized.GetChar( sLocalized.Len() - 1 ) == '1' ) { + if( sLocalized ){ + sCurrentCloseTag = rToken; + + ByteString sLang = GetAttribute( sCurrentOpenTag, "xml:lang" ); + if( sLang.EqualsIgnoreCaseAscii("de") ){ + ULONG nLen = 0; + while ( sCurrentText.Len() != nLen ) + { + nLen = sCurrentText.Len(); + sCurrentText.SearchAndReplaceAll( "\n\t", "\n" ); + sCurrentText.SearchAndReplaceAll( "\n ", "\n" ); + } + sCurrentText.SearchAndReplaceAll( "\n", " " ); + sCurrentCloseTag = rToken; + } + WorkOnText( sCurrentOpenTag, sCurrentText ); + Output( sCurrentText ); + + //fprintf( stdout, "%s %s\n", sGID.GetBuffer(), sLID.GetBuffer()); + //fprintf( stdout, "%s\n\n", sCurrentText.GetBuffer()); + + bText = FALSE; + } + } + break; + + case XRM_LIST_START: + sLID = ""; + break; + + case XRM_LIST_END: + if ( sLID.Len()) + EndOfText( sCurrentOpenTag, sCurrentCloseTag ); + break; + + default: + if ( bText ) { + sCurrentText += rToken; + } + break; + } + + if ( !bText ) + Output( rToken ); + + return 0; +} + +/*****************************************************************************/ +ByteString XRMResParser::GetAttribute( const ByteString &rToken, const ByteString &rAttribute ) +/*****************************************************************************/ +{ + ByteString sTmp( rToken ); + sTmp.SearchAndReplaceAll( "\t", " " ); + + ByteString sSearch( " " ); + sSearch += rAttribute; + sSearch += "="; + USHORT nPos = sTmp.Search( sSearch ); + + if ( nPos != STRING_NOTFOUND ) { + sTmp = sTmp.Copy( nPos ); + ByteString sId = sTmp.GetToken( 1, '\"' ); + return sId; + } + return ""; +} + + +/*****************************************************************************/ +void XRMResParser::Error( const ByteString &rError ) +/*****************************************************************************/ +{ + yyerror(( char * ) rError.GetBuffer()); +} + +/*****************************************************************************/ +void XRMResParser::ConvertStringToDBFormat( ByteString &rString ) +/*****************************************************************************/ +{ + ByteString sResult; + do { + sResult = rString; + rString.EraseLeadingChars( _LF ); + // rString.EraseLeadingChars( ' ' ); + rString.EraseLeadingChars( '\t' ); + // rString.EraseTrailingChars( ' ' ); + rString.EraseTrailingChars( '\t' ); + } while ( sResult != rString ); + + rString.SearchAndReplaceAll( "\t", "\\t" ); +} + +/*****************************************************************************/ +void XRMResParser::ConvertStringToXMLFormat( ByteString &rString ) +/*****************************************************************************/ +{ + rString.SearchAndReplaceAll( "\\t", "\t" ); +} + + + +// +// class XRMResOutputParser +// + +/*****************************************************************************/ +XRMResOutputParser::XRMResOutputParser ( const ByteString &rOutputFile ) +/*****************************************************************************/ +{ + aLanguages = Export::GetLanguages(); + pOutputStream = + new SvFileStream( + String( rOutputFile, RTL_TEXTENCODING_ASCII_US ), + STREAM_STD_WRITE | STREAM_TRUNC + ); + pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); + if ( !pOutputStream->IsOpen()) { + ByteString sError( "Unable to open output file: " ); + sError += rOutputFile; + Error( sError ); + delete pOutputStream; + pOutputStream = NULL; + } +} + +/*****************************************************************************/ +XRMResOutputParser::~XRMResOutputParser() +/*****************************************************************************/ +{ + if ( pOutputStream ) { + pOutputStream->Close(); + delete pOutputStream; + } +} + +// +// class XMLResExport +// + +/*****************************************************************************/ +XRMResExport::XRMResExport( + const ByteString &rOutputFile, const ByteString &rProject, + const ByteString &rFilePath ) +/*****************************************************************************/ + : XRMResOutputParser( rOutputFile ), + pResData( NULL ), + sPrj( rProject ), + sPath( rFilePath ) +{ + aLanguages = Export::GetLanguages(); +} + +/*****************************************************************************/ +XRMResExport::~XRMResExport() +/*****************************************************************************/ +{ + delete pResData; +} + +void XRMResExport::Output( const ByteString& rOutput ) +{ + // Dummy to suppress warnings caused by poor class design + (void) rOutput; +} + +/*****************************************************************************/ +void XRMResExport::WorkOnText( + const ByteString &rOpenTag, + ByteString &rText +) +/*****************************************************************************/ +{ + ByteString sLang( GetAttribute( rOpenTag, "xml:lang" )); + + if ( !pResData ) { + ByteString sPlatform( "" ); + pResData = new ResData( sPlatform, GetGID() ); + pResData->sId = GetLID(); + } + + pResData->sText[ sLang ] = rText; + ConvertStringToDBFormat( pResData->sText[ sLang ] ); +} + +/*****************************************************************************/ +void XRMResExport::EndOfText( + const ByteString &rOpenTag, + const ByteString &rCloseTag +) +/*****************************************************************************/ +{ + + (void) rOpenTag; // FIXME + (void) rCloseTag; // FIXME + + if ( pResData && pOutputStream ) { + + char cSearch = 0x00; + ByteString sSearch( cSearch ); + + // if ( !pResData->sText[ ByteString("en-US") ].Len() ) + // pResData->sText[ ByteString("en-US") ] = pResData->sText[ ByteString("de") ]; + + Export::FillInFallbacks( pResData ); + + ByteString sTimeStamp( Export::GetTimeStamp()); + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + + ByteString sAct = pResData->sText[ sCur ]; + Export::UnquotHTML( sAct ); + sAct.EraseAllChars( 0x0A ); + + ByteString sOutput( sPrj ); sOutput += "\t"; + sOutput += sPath; + sOutput += "\t0\t"; + sOutput += "readmeitem\t"; + sOutput += pResData->sGId; sOutput += "\t"; + sOutput += pResData->sId; sOutput += "\t\t\t0\t"; + sOutput += sCur; + sOutput += "\t"; + + sOutput += sAct; sOutput += "\t\t\t\t"; + sOutput += sTimeStamp; + + sOutput.SearchAndReplaceAll( sSearch, "_" ); + //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) ) + pOutputStream->WriteLine( sOutput ); + } + } + delete pResData; + pResData = NULL; +} + +// +// class XRMResMerge +// + +/*****************************************************************************/ +XRMResMerge::XRMResMerge( + const ByteString &rMergeSource, const ByteString &rOutputFile, + ByteString &rFilename) +/*****************************************************************************/ + : XRMResOutputParser( rOutputFile ), + pMergeDataFile( NULL ), + sFilename( rFilename ) , + pResData( NULL ) +{ + if ( rMergeSource.Len()) + pMergeDataFile = new MergeDataFile( + rMergeSource, sInputFileName , bErrorLog, RTL_TEXTENCODING_MS_1252);//, bUTF8 ); + if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){ + Export::SetLanguages( pMergeDataFile->GetLanguages() ); + aLanguages = pMergeDataFile->GetLanguages(); + } + else aLanguages = Export::GetLanguages(); +} + +/*****************************************************************************/ +XRMResMerge::~XRMResMerge() +/*****************************************************************************/ +{ + delete pMergeDataFile; + delete pResData; +} + +/*****************************************************************************/ +void XRMResMerge::WorkOnText( + const ByteString &rOpenTag, + ByteString &rText +) +/*****************************************************************************/ +{ + ByteString sLang( GetAttribute( rOpenTag, "xml:lang" )); + + if ( pMergeDataFile ) { + if ( !pResData ) { + ByteString sPlatform( "" ); + pResData = new ResData( sPlatform, GetGID() , sFilename ); + pResData->sId = GetLID(); + pResData->sResTyp = "readmeitem"; + } + + PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); + if ( pEntrys ) { + ByteString sContent; + if ( Export::isAllowed( sLang ) && + ( pEntrys->GetText( + sContent, STRING_TYP_TEXT, sLang )) && + ( sContent != "-" ) && ( sContent.Len())) + + { + rText = sContent; + ConvertStringToXMLFormat( rText ); + Export::QuotHTMLXRM( rText ); + } + } + } +} + +/*****************************************************************************/ +void XRMResMerge::Output( const ByteString& rOutput ) +/*****************************************************************************/ +{ + if ( pOutputStream ) + pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len()); +} + +/*****************************************************************************/ +void XRMResMerge::EndOfText( + const ByteString &rOpenTag, + const ByteString &rCloseTag +) +/*****************************************************************************/ +{ + if ( pMergeDataFile && pResData ) { + PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); + if ( pEntrys ) { + ByteString sCur; + for( unsigned int n = 0; n < aLanguages.size(); n++ ){ + sCur = aLanguages[ n ]; + ByteString sContent; +//<<<<<<< xrmmerge.cxx + if ( !sCur.EqualsIgnoreCaseAscii("en-US") && + // ( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && Export::isMergingGermanAllowed( sPrj ) )) && +//======= +// if ( Export::isAllowed( sCur ) && +//>>>>>>> 1.17 + ( pEntrys->GetText( + sContent, STRING_TYP_TEXT, sCur, TRUE )) && + ( sContent != "-" ) && ( sContent.Len())) + { + ByteString sText( sContent ); + Export::QuotHTMLXRM( sText ); + + ByteString sAdditionalLine( "\t" ); + sAdditionalLine += rOpenTag; + ByteString sSearch = "xml:lang=\""; + ByteString sReplace( sSearch ); + + sSearch += GetAttribute( rOpenTag, "xml:lang" ); + sReplace += sCur; + + sAdditionalLine.SearchAndReplace( sSearch, sReplace ); + + sAdditionalLine += sText; + sAdditionalLine += rCloseTag; + sAdditionalLine += "\n"; + + for ( USHORT i = 0; i + 1 < GetGID().GetTokenCount( '.' ); i++ ) + sAdditionalLine += "\t"; + + Output( sAdditionalLine ); + } + } + } + } + delete pResData; + pResData = NULL; +} + diff --git a/transex3/workbench/gsicheck_errors.sdf b/transex3/workbench/gsicheck_errors.sdf new file mode 100644 index 000000000000..04dde12e13ca --- /dev/null +++ b/transex3/workbench/gsicheck_errors.sdf @@ -0,0 +1,15 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 de ERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 en-US äERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 de äERR OK ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 de OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 en-US OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 6 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 7 0 en-US OK OK ERR 2004-11-09 18:41:29.59 + diff --git a/transex3/workbench/gsicheck_errors_err-.sdf b/transex3/workbench/gsicheck_errors_err-.sdf new file mode 100644 index 000000000000..f6b267b1c55b --- /dev/null +++ b/transex3/workbench/gsicheck_errors_err-.sdf @@ -0,0 +1,11 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 de ERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 en-US äERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 de äERR OK ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 6 0 de ERR ERR ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_err-l.sdf b/transex3/workbench/gsicheck_errors_err-l.sdf new file mode 100644 index 000000000000..6ca7f7065cd2 --- /dev/null +++ b/transex3/workbench/gsicheck_errors_err-l.sdf @@ -0,0 +1,2 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 en-US äERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 de äERR OK ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_err-s.sdf b/transex3/workbench/gsicheck_errors_err-s.sdf new file mode 100644 index 000000000000..523017fcfb35 --- /dev/null +++ b/transex3/workbench/gsicheck_errors_err-s.sdf @@ -0,0 +1,9 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 de ERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 en-US äERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 6 0 de ERR ERR ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_err-t.sdf b/transex3/workbench/gsicheck_errors_err-t.sdf new file mode 100644 index 000000000000..e9594642113c --- /dev/null +++ b/transex3/workbench/gsicheck_errors_err-t.sdf @@ -0,0 +1,9 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 de äERR OK ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 6 0 de ERR ERR ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_ok-.sdf b/transex3/workbench/gsicheck_errors_ok-.sdf new file mode 100644 index 000000000000..4bb4b7bece16 --- /dev/null +++ b/transex3/workbench/gsicheck_errors_ok-.sdf @@ -0,0 +1,5 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 de OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 en-US OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 7 0 en-US OK OK ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_ok-l.sdf b/transex3/workbench/gsicheck_errors_ok-l.sdf new file mode 100644 index 000000000000..9a55e7c95dd3 --- /dev/null +++ b/transex3/workbench/gsicheck_errors_ok-l.sdf @@ -0,0 +1,12 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 de ERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 de OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 en-US OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 en-US ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 5 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 6 0 de ERR ERR ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 7 0 en-US OK OK ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_ok-s.sdf b/transex3/workbench/gsicheck_errors_ok-s.sdf new file mode 100644 index 000000000000..97dd4da6a54b --- /dev/null +++ b/transex3/workbench/gsicheck_errors_ok-s.sdf @@ -0,0 +1,6 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 de äERR OK ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 de OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 en-US OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 7 0 en-US OK OK ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheck_errors_ok-t.sdf b/transex3/workbench/gsicheck_errors_ok-t.sdf new file mode 100644 index 000000000000..a6c097e6bd2f --- /dev/null +++ b/transex3/workbench/gsicheck_errors_ok-t.sdf @@ -0,0 +1,6 @@ +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 de ERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 1 0 en-US äERR ERR OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 2 0 en-US OK/ERR OK ERR/OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 de OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 3 0 en-US OK OK OK 2004-11-09 18:41:29.59 +svx source\dialog\langtab.src 0 itemlist RID_SVXSTR_LANGUAGE_TABLE 4 0 en-US OK/ERR OK/ERR OK/ERR 2004-11-09 18:41:29.59 diff --git a/transex3/workbench/gsicheckcheck.btm b/transex3/workbench/gsicheckcheck.btm new file mode 100644 index 000000000000..de71b17da332 --- /dev/null +++ b/transex3/workbench/gsicheckcheck.btm @@ -0,0 +1,17 @@ +gsicheck +gsicheck.exe gsicheck_errors.sdf -wc -we +#pause +diff --brief gsicheck_errors_ok.sdf gsicheck_errors_ok-.sdf || %vdiff gsicheck_errors_ok.sdf gsicheck_errors_ok-.sdf +diff --brief gsicheck_errors_err.sdf gsicheck_errors_err-.sdf || %vdiff gsicheck_errors_err.sdf gsicheck_errors_err-.sdf +gsicheck.exe gsicheck_errors.sdf -wc -we -s +#pause +diff --brief gsicheck_errors_ok.sdf gsicheck_errors_ok-s.sdf || %vdiff gsicheck_errors_ok.sdf gsicheck_errors_ok-s.sdf +diff --brief gsicheck_errors_err.sdf gsicheck_errors_err-s.sdf || %vdiff gsicheck_errors_err.sdf gsicheck_errors_err-s.sdf +gsicheck.exe gsicheck_errors.sdf -wc -we -t +#pause +diff --brief gsicheck_errors_ok.sdf gsicheck_errors_ok-t.sdf || %vdiff gsicheck_errors_ok.sdf gsicheck_errors_ok-t.sdf +diff --brief gsicheck_errors_err.sdf gsicheck_errors_err-t.sdf || %vdiff gsicheck_errors_err.sdf gsicheck_errors_err-t.sdf +gsicheck.exe gsicheck_errors.sdf -wc -we -l "" +#pause +diff --brief gsicheck_errors_ok.sdf gsicheck_errors_ok-l.sdf || %vdiff gsicheck_errors_ok.sdf gsicheck_errors_ok-l.sdf +diff --brief gsicheck_errors_err.sdf gsicheck_errors_err-l.sdf || %vdiff gsicheck_errors_err.sdf gsicheck_errors_err-l.sdf |