xref: /trunk/main/l10ntools/inc/export.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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