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