xref: /aoo42x/main/l10ntools/inc/export.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _EXPORT_HXX
29 #define _EXPORT_HXX
30 
31 #ifndef L10NTOOLS_DIRECTORY_HXX
32 #define L10NTOOLS_DIRECTORY_HXX
33 #include <l10ntools/directory.hxx>
34 #endif
35 
36 
37 // #define MERGE_SOURCE_LANGUAGES <- To merge en-US and de resource
38 
39 #include <tools/string.hxx>
40 #include <tools/list.hxx>
41 #include <tools/stream.hxx>
42 #include <tools/fsys.hxx>
43 #include <osl/file.hxx>
44 #include <osl/file.h>
45 
46 #include <hash_map> /* std::hashmap*/
47 #include <iterator> /* std::iterator*/
48 #include <set>      /* std::set*/
49 #include <vector>   /* std::vector*/
50 #include <queue>
51 #include <string>
52 
53 #include <unistd.h>
54 #ifdef WNT
55 #include <direct.h>
56 #endif
57 
58 #define NO_TRANSLATE_ISO		"x-no-translate"
59 
60 #define JAPANESE_ISO "ja"
61 
62 
63 struct eqstr{
64   sal_Bool operator()(const char* s1, const char* s2) const{
65     return strcmp(s1,s2)==0;
66   }
67 };
68 
69 struct equalByteString{
70         bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const {
71             return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL;
72     }
73 };
74 struct lessByteString{
75         bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const {
76             return rKey1.CompareTo( rKey2 )==COMPARE_LESS;
77     }
78 };
79 
80 struct hashByteString{
81     size_t operator()( const ByteString& rName ) const{
82                 std::hash< const char* > myHash;
83                 return myHash( rName.GetBuffer() );
84     }
85 };
86 
87 class PFormEntrys;
88 class MergeData;
89 typedef std::set<ByteString , lessByteString > ByteStringSet;
90 
91 typedef std::hash_map<ByteString , ByteString , hashByteString,equalByteString>
92                                 ByteStringHashMap;
93 
94 typedef std::hash_map<ByteString , bool , hashByteString,equalByteString>
95                                 ByteStringBoolHashMap;
96 
97 typedef std::hash_map<ByteString , PFormEntrys* , hashByteString,equalByteString>
98                                 PFormEntrysHashMap;
99 
100 typedef std::hash_map<ByteString , MergeData* , hashByteString,equalByteString>
101                                 MergeDataHashMap;
102 
103 #define SOURCE_LANGUAGE ByteString("en-US")
104 #define LIST_REFID  "LIST_REFID"
105 
106 typedef ByteStringHashMap ExportListEntry;
107 
108 DECLARE_LIST( ExportListBase, ExportListEntry * )
109 
110 //
111 // class ExportList
112 //
113 
114 class ExportList : public ExportListBase
115 {
116 private:
117 	sal_uLong nSourceLanguageListEntryCount;
118 
119 public:
120 	ExportList() : ExportListBase() { nSourceLanguageListEntryCount = 0; }
121 	sal_uLong GetSourceLanguageListEntryCount() { return nSourceLanguageListEntryCount; }
122 	void NewSourceLanguageListEntry() { nSourceLanguageListEntryCount++; }
123 };
124 
125 #define REFID_NONE 0xFFFF
126 
127 //
128 // struct ResData
129 //
130 
131 /******************************************************************************
132 * Purpose: holds mandatory data to export a single res (used with ResStack)
133 ******************************************************************************/
134 
135 #define ID_LEVEL_NULL		0x0000
136 #define ID_LEVEL_AUTOID		0x0001
137 #define ID_LEVEL_TEXT		0x0002
138 #define ID_LEVEL_FIELDNAME	0x0003
139 #define ID_LEVEL_ACCESSPATH	0x0004
140 #define ID_LEVEL_IDENTIFIER 0x0005
141 #define ID_LEVEL_LISTINDEX	0x0006
142 
143 class ResData
144 {
145 public:
146 	~ResData();
147 	sal_Bool SetId( const ByteString &rId, sal_uInt16 nLevel );
148 
149     sal_uInt16 nWidth;
150 	sal_uInt16 nChildIndex;
151 	sal_uInt16 nIdLevel;
152 	sal_Bool bChild;
153 	sal_Bool bChildWithText;
154 
155 	sal_Bool bText;
156 	sal_Bool bHelpText;
157 	sal_Bool bQuickHelpText;
158 	sal_Bool bTitle;
159 	sal_Bool bList;
160 
161 	sal_Bool bRestMerged;
162 
163     ByteString sResTyp;
164 	ByteString sId;
165 	ByteString sGId;
166 	ByteString sHelpId;
167 	ByteString sFilename;
168 
169     ByteStringHashMap sText;
170     sal_uInt16 nTextRefId;
171 
172 	ByteStringHashMap sHelpText;
173     sal_uInt16 nHelpTextRefId;
174 
175 	ByteStringHashMap sQuickHelpText;
176     sal_uInt16 nQuickHelpTextRefId;
177 
178 	ByteStringHashMap sTitle;
179     sal_uInt16 nTitleRefId;
180 
181 	ByteString sTextTyp;
182 	ByteStringHashMap aFallbackData;
183 	ByteStringHashMap aMergedLanguages;
184 
185 	ExportList	*pStringList;
186 	ExportList	*pUIEntries;
187 	ExportList	*pItemList;
188     ExportList	*pFilterList;
189     ExportList  *pPairedList;
190 
191     ByteString sPForm;
192 
193 	void Dump();
194 	void addFallbackData( ByteString& sId , const ByteString& sText );
195 	bool getFallbackData( ByteString& sId , ByteString& sText);
196 
197 	void addMergedLanguage( ByteString& sLang );
198 	bool isMerged( ByteString& sLang );
199 	ResData( const ByteString &rPF, const ByteString &rGId )
200 			:
201             nWidth( 0 ),
202             nChildIndex( 0 ),
203             nIdLevel( ID_LEVEL_NULL ),
204             bChild( sal_False ),
205             bChildWithText( sal_False ),
206             bText( sal_False ),
207             bHelpText( sal_False ),
208             bQuickHelpText( sal_False ),
209             bTitle( sal_False ),
210             bList( sal_False ),
211             bRestMerged( sal_False ),
212             sGId( rGId ),
213             nTextRefId( REFID_NONE ),
214             nHelpTextRefId( REFID_NONE ),
215             nQuickHelpTextRefId( REFID_NONE ),
216             nTitleRefId( REFID_NONE ),
217             sTextTyp( "Text" ),
218             pStringList( NULL ),
219             pUIEntries( NULL ),
220             pItemList( NULL ),
221             pFilterList( NULL ),
222             pPairedList( NULL ),
223             sPForm( rPF )
224 	{
225 		sGId.EraseAllChars( '\r' );
226 		sPForm.EraseAllChars( '\r' );
227 	};
228 	ResData( const ByteString &rPF, const ByteString &rGId , const ByteString &rFilename )
229 			:
230             nChildIndex( 0 ),
231             nIdLevel( ID_LEVEL_NULL ),
232             bChild( sal_False ),
233             bChildWithText( sal_False ),
234             bText( sal_False ),
235             bHelpText( sal_False ),
236             bQuickHelpText( sal_False ),
237             bTitle( sal_False ),
238             bList( sal_False ),
239             bRestMerged( sal_False ),
240             sGId( rGId ),
241             sFilename( rFilename ),
242             nTextRefId( REFID_NONE ),
243             nHelpTextRefId( REFID_NONE ),
244             nQuickHelpTextRefId( REFID_NONE ),
245             nTitleRefId( REFID_NONE ),
246             sTextTyp( "Text" ),
247             pStringList( NULL ),
248             pUIEntries( NULL ),
249             pItemList( NULL ),
250             pFilterList( NULL ),
251             pPairedList( NULL ),
252             sPForm( rPF )
253 
254 	{
255 		sGId.EraseAllChars( '\r' );
256 		sPForm.EraseAllChars( '\r' );
257 	};
258 
259 
260 };
261 
262 
263 //
264 // class Export
265 //
266 
267 /******************************************************************************
268 * Purpose: syntax check and export of *.src, called from lexer
269 ******************************************************************************/
270 
271 #define LIST_NON 					0x0000
272 #define LIST_STRING 				0x0001
273 #define LIST_FILTER					0x0002
274 #define LIST_ITEM					0x0004
275 #define LIST_PAIRED                 0x0005
276 #define LIST_UIENTRIES				0x0008
277 #define STRING_TYP_TEXT				0x0010
278 #define	STRING_TYP_HELPTEXT			0x0020
279 #define STRING_TYP_QUICKHELPTEXT	0x0040
280 #define STRING_TYP_TITLE			0x0080
281 
282 #define MERGE_MODE_NORMAL			0x0000
283 #define MERGE_MODE_LIST				0x0001
284 
285 DECLARE_LIST( ResStack, ResData * )
286 // forwards
287 class WordTransformer;
288 class ParserQueue;
289 
290 class Export
291 {
292 private:
293 	WordTransformer	*pWordTransformer;
294 
295 	CharSet	aCharSet;					// used charset in src
296 
297 	SvFileStream aOutput;
298 
299 	ResStack aResStack;					// stack for parsing recursive
300 
301 	ByteString sActPForm;				// hold cur. system
302 
303 	sal_Bool bDefine;						// cur. res. in a define?
304 	sal_Bool bNextMustBeDefineEOL;			// define but no \ at lineend
305 	sal_uLong nLevel;						// res. recursiv? how deep?
306 	sal_uInt16 nList;						// cur. res. is String- or FilterList
307     ByteString nListLang;
308     sal_uLong nListIndex;
309 	sal_uLong nListLevel;
310     bool bSkipFile;
311 	ByteString sProject;
312 	ByteString sRoot;
313 	sal_Bool bEnableExport;
314 	sal_Bool bMergeMode;
315 	ByteString sMergeSrc;
316 	ByteString sLastListLine;
317 	sal_Bool bError;						// any errors while export?
318 	sal_Bool bReadOver;
319 	sal_Bool bDontWriteOutput;
320 	ByteString sLastTextTyp;
321     static bool isInitialized;
322 	ByteString sFilename;
323 
324 
325 public:
326 	ParserQueue* pParseQueue; // public ?
327     static ByteString sLanguages; // public ?
328     static ByteString sForcedLanguages; // public ?
329 
330 
331     static bool skipProject( ByteString sPrj ) ;
332 	static void InitLanguages( bool bMergeMode = false );
333     static void InitForcedLanguages( bool bMergeMode = false );
334     static std::vector<ByteString> GetLanguages();
335     static std::vector<ByteString> GetForcedLanguages();
336 
337     static void SetLanguages( std::vector<ByteString> val );
338     static void RemoveUTF8ByteOrderMarker( ByteString &rString );
339     static bool hasUTF8ByteOrderMarker( const ByteString &rString );
340     static void RemoveUTF8ByteOrderMarkerFromFile( const ByteString &rFilename );
341     static bool fileHasUTF8ByteOrderMarker( const ByteString &rString );
342 	static ByteString GetIsoLangByIndex( sal_uInt16 nIndex );
343 	static void QuotHTML( ByteString &rString );
344     static bool CopyFile( const ByteString& source , const ByteString& dest );
345 
346 	static void QuotHTMLXRM( ByteString &rString );
347     static void UnquotHTML( ByteString &rString );
348 
349     static const char* GetEnv( const char *pVar );
350 	static int getCurrentDirectory( rtl::OUString& base_fqurl , rtl::OUString& base );
351 
352     static bool isSourceLanguage( const ByteString &sLanguage );
353 	static bool isAllowed( const ByteString &sLanguage );
354 
355     static bool LanguageAllowed( const ByteString &nLanguage );
356     static void Languages( std::vector<ByteString>::const_iterator& begin , std::vector<ByteString>::const_iterator& end );
357 	static void getRandomName( const ByteString& sPrefix , ByteString& sRandStr , const ByteString& sPostfix  );
358     static void getRandomName( ByteString& sRandStr );
359     static void getCurrentDir( std::string& dir );
360 
361     static void replaceEncoding( ByteString& rString );
362 
363 	static ByteString GetFallbackLanguage( const ByteString nLanguage );
364 	static void FillInFallbacks( ResData *pResData );
365     static void FillInListFallbacks( ExportList *pList, const ByteString &nSource, const ByteString &nFallback );
366     static ByteString GetTimeStamp();
367 	static sal_Bool ConvertLineEnds( ByteString sSource, ByteString sDestination );
368 	static ByteString GetNativeFile( ByteString sSource );
369 	static DirEntry GetTempFile();
370 
371 	static void DumpExportList( ByteString& sListName , ExportList& aList );
372 	static ByteString DumpMap( ByteString& sMapName , ByteStringHashMap& aMap );
373 
374 private:
375     static std::vector<ByteString> aLanguages;
376     static std::vector<ByteString> aForcedLanguages;
377 
378 	sal_Bool ListExists( ResData *pResData, sal_uInt16 nLst );
379 
380 	sal_Bool WriteData( ResData *pResData, sal_Bool bCreateNew = sal_False );// called befor dest. cur ResData
381 	sal_Bool WriteExportList( ResData *pResData, ExportList *pExportList,
382 						const ByteString &rTyp, sal_Bool bCreateNew = sal_False );
383 
384 	ByteString MergePairedList( ByteString& sLine , ByteString& sText );
385 
386 	ByteString FullId();					// creates cur. GID
387 
388 	bool PairedListFallback( ByteString& sText , ResData& aResData );
389 
390 	ByteString GetPairedListID		( const ByteString& sText );
391     ByteString GetPairedListString	( const ByteString& sText );
392 	ByteString StripList	( const ByteString& sText );
393 
394 	void UnmergeUTF8( ByteString& sOrig );
395 	void InsertListEntry( const ByteString &rText, const ByteString &rLine );
396 	void CleanValue( ByteString &rValue );
397 	ByteString GetText( const ByteString &rSource, int nToken );
398 
399 	sal_Bool PrepareTextToMerge( ByteString &rText, sal_uInt16 nTyp,
400 		ByteString &nLangIndex, ResData *pResData );
401 
402 	void MergeRest( ResData *pResData, sal_uInt16 nMode = MERGE_MODE_NORMAL );
403 	void ConvertMergeContent( ByteString &rText );
404 
405   	void WriteToMerged( const ByteString &rText , bool bSDFContent );
406 	void SetChildWithText();
407 
408 	void CutComment( ByteString &rText );
409 
410 public:
411 	Export( const ByteString &rOutput, sal_Bool bWrite,
412 			const ByteString &rPrj, const ByteString &rPrjRoot , const ByteString& rFile );
413 	Export( const ByteString &rOutput, sal_Bool bWrite,
414 			const ByteString &rPrj, const ByteString &rPrjRoot,
415 			const ByteString &rMergeSource , const ByteString& rFile );
416 	~Export();
417 
418 	void Init();
419 	int Execute( int nToken, const char * pToken );	// called from lexer
420 	void SetError() { bError = sal_True; }
421 	sal_Bool GetError() { return bError; }
422 };
423 
424 
425 //
426 // class PFormEntrys
427 //
428 
429 /******************************************************************************
430 * Purpose: holds information of data to merge (one pform)
431 ******************************************************************************/
432 
433 class PFormEntrys : public ByteString
434 {
435 friend class MergeDataFile;
436 private:
437 	ByteString sHelpText; // empty string
438 	ByteStringHashMap sText;
439 	ByteStringBoolHashMap bTextFirst;
440 	ByteStringHashMap sQuickHelpText;
441 	ByteStringBoolHashMap bQuickHelpTextFirst;
442 	ByteStringHashMap sTitle;
443 	ByteStringBoolHashMap bTitleFirst;
444 
445 public:
446 	PFormEntrys( const ByteString &rPForm ) : ByteString( rPForm ) {};
447 	ByteString Dump();
448 	void InsertEntry(
449                     const ByteString &nId ,
450                     const ByteString &rText,
451 					const ByteString &rQuickHelpText,
452 					const ByteString &rTitle
453                     )
454 		{
455 			sText[ nId ] = rText;
456 			bTextFirst[ nId ] = true;
457 			sQuickHelpText[ nId ] = rQuickHelpText;
458 			bQuickHelpTextFirst[ nId ] = true;
459 			sTitle[ nId ] = rTitle;
460 			bTitleFirst[ nId ] = true;
461 		}
462      sal_Bool GetText( ByteString &rReturn, sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel = sal_False );
463      sal_Bool GetTransex3Text( ByteString &rReturn, sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel = sal_False );
464 
465 };
466 
467 //
468 // class MergeData
469 //
470 
471 /******************************************************************************
472 * Purpose: holds information of data to merge (one ressource)
473 ******************************************************************************/
474 
475 class MergeDataFile;
476 
477 class MergeData
478 {
479 friend class MergeDataFile;
480 private:
481 	ByteString sTyp;
482 	ByteString sGID;
483 	ByteString sLID;
484     ByteString sFilename;
485     PFormEntrysHashMap aMap;
486 public:
487 	MergeData( const ByteString &rTyp, const ByteString &rGID, const ByteString &rLID , const ByteString &rFilename )
488 			: sTyp( rTyp ), sGID( rGID ), sLID( rLID ) , sFilename( rFilename ) {};
489 	~MergeData();
490 	PFormEntrys* InsertEntry( const ByteString &rPForm );
491 	PFormEntrys* GetPFormEntrys( ResData *pResData );
492 
493     void Insert( const ByteString& rPFO , PFormEntrys* pfEntrys );
494     PFormEntrys* GetPFObject( const ByteString& rPFO );
495 
496 	ByteString Dump();
497 	sal_Bool operator==( ResData *pData );
498 };
499 
500 //
501 // class MergeDataFile
502 //
503 
504 /******************************************************************************
505 * Purpose: holds information of data to merge
506 ******************************************************************************/
507 
508 class MergeDataFile
509 {
510     private:
511         sal_Bool bErrorLog;
512         ByteString sErrorLog;
513         SvFileStream aErrLog;
514         MergeDataHashMap aMap;
515         std::set<ByteString> aLanguageSet;
516 
517         MergeData *GetMergeData( ResData *pResData , bool bCaseSensitve = false );
518         void InsertEntry( const ByteString &rTYP, const ByteString &rGID, const ByteString &rLID,
519             const ByteString &rPFO,
520             const ByteString &nLang, const ByteString &rTEXT,
521             const ByteString &rQHTEXT, const ByteString &rTITLE,
522             const ByteString &sFilename, bool bCaseSensitive
523             );
524         ByteString Dump();
525         void WriteError( const ByteString &rLine );
526 
527     public:
528         MergeDataFile( const ByteString &rFileName, const ByteString& rFile , sal_Bool bErrLog, CharSet aCharSet, bool bCaseSensitive = false );
529         ~MergeDataFile();
530 
531         std::vector<ByteString> GetLanguages();
532 
533         PFormEntrys *GetPFormEntrys( ResData *pResData );
534         PFormEntrys *GetPFormEntrysCaseSensitive( ResData *pResData );
535 
536         static ByteString CreateKey( const ByteString& rTYP , const ByteString& rGID , const ByteString& rLID , const ByteString& rFilename , bool bCaseSensitive = false );
537 };
538 
539 
540 class QueueEntry
541 {
542 public:
543     QueueEntry( int nTypVal , ByteString sLineVal ): nTyp( nTypVal ) , sLine( sLineVal ){};
544     int nTyp;
545     ByteString sLine;
546 };
547 
548 class ParserQueue
549 {
550 public:
551 
552     ParserQueue( Export& aExportObj );
553     ~ParserQueue();
554 
555     inline void Push( const QueueEntry& aEntry );
556     bool bCurrentIsM;  // public ?
557     bool bNextIsM;   // public ?
558     bool bLastWasM;   // public ?
559     bool bMflag;   // public ?
560 
561     void Close();
562 private:
563     // Future / Next
564     std::queue<QueueEntry>* aQueueNext;
565     // Current
566     std::queue<QueueEntry>* aQueueCur;
567     // Ref
568     std::queue<QueueEntry>* aQref;
569 
570     Export& aExport;
571     bool bStart;
572     bool bStartNext;
573 
574     inline void Pop( std::queue<QueueEntry>& aQueue );
575 
576 };
577 #endif
578 
579