xref: /trunk/main/l10ntools/source/export.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_l10ntools.hxx"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <tools/fsys.hxx>
33 #include "export.hxx"
34 #include "tokens.h"
35 #include "utf8conv.hxx"
36 #include <iostream>
37 
38 extern "C" { int yyerror( char * ); }
39 extern "C" { int YYWarning( char * ); }
40 
41 Export *pExport = 0L;
42 
43 // defines to parse command line
44 #define STATE_NON       0x0001
45 #define STATE_INPUT     0x0002
46 #define STATE_OUTPUT    0x0003
47 #define STATE_PRJ       0x0004
48 #define STATE_ROOT      0x0005
49 #define STATE_MERGESRC  0x0006
50 #define STATE_ERRORLOG  0x0007
51 #define STATE_BREAKHELP 0x0008
52 #define STATE_UNMERGE   0x0009
53 #define STATE_UTF8      0x000A
54 #define STATE_LANGUAGES 0X000B
55 
56 // set of global variables
57 DECLARE_LIST( FileList, ByteString * )
58 FileList aInputFileList;
59 sal_Bool bEnableExport;
60 sal_Bool bMergeMode;
61 sal_Bool bErrorLog;
62 sal_Bool bBreakWhenHelpText;
63 sal_Bool bUnmerge;
64 sal_Bool bUTF8;
65 ByteString sPrj;
66 ByteString sPrjRoot;
67 ByteString sActFileName;
68 ByteString sOutputFile;
69 ByteString sMergeSrc;
70 ByteString sTempFile;
71 ByteString sFile;
72 MergeDataFile *pMergeDataFile;
73 FILE *pTempFile;
74 
75 
76 ByteString sStrBuffer;
77 bool bMarcro = false;
78 
79 extern "C" {
80 // the whole interface to lexer is in this extern "C" section
81 
82 
83 /*****************************************************************************/
84 extern char *GetOutputFile( int argc, char* argv[])
85 /*****************************************************************************/
86 {
87     bEnableExport = sal_False;
88     bMergeMode = sal_False;
89     bErrorLog = sal_True;
90     bBreakWhenHelpText = sal_False;
91     bUnmerge = sal_False;
92     bUTF8 = sal_True;
93     sPrj = "";
94     sPrjRoot = "";
95     sActFileName = "";
96     Export::sLanguages = "";
97     Export::sForcedLanguages = "";
98     sTempFile = "";
99     pTempFile = NULL;
100     sal_uInt16 nState = STATE_NON;
101     sal_Bool bInput = sal_False;
102 
103     // parse command line
104     for( int i = 1; i < argc; i++ ) {
105         ByteString sSwitch( argv[ i ] );
106 
107         if (sSwitch == "-i"  || sSwitch == "-I" ) {
108             nState = STATE_INPUT; // next tokens specifies source files
109         }
110         else if (sSwitch == "-o"  || sSwitch == "-O" ) {
111             nState = STATE_OUTPUT; // next token specifies the dest file
112         }
113         else if (sSwitch == "-p"  || sSwitch == "-P" ) {
114             nState = STATE_PRJ; // next token specifies the cur. project
115         }
116 
117         else if (sSwitch == "-r"  || sSwitch == "-R" ) {
118             nState = STATE_ROOT; // next token specifies path to project root
119         }
120         else if (sSwitch == "-m"  || sSwitch == "-M" ) {
121             nState = STATE_MERGESRC; // next token specifies the merge database
122         }
123         else if (sSwitch == "-e"  || sSwitch == "-E" ) {
124             nState = STATE_ERRORLOG;
125             bErrorLog = sal_False;
126         }
127         else if (sSwitch == "-b"  || sSwitch == "-B" ) {
128             nState = STATE_BREAKHELP;
129             bBreakWhenHelpText = sal_True;
130         }
131         else if (sSwitch == "-u"  || sSwitch == "-U" ) {
132             nState = STATE_UNMERGE;
133             bUnmerge = sal_True;
134             bMergeMode = sal_True;
135         }
136         else if ( sSwitch.ToUpperAscii() == "-UTF8" ) {
137             nState = STATE_UTF8;
138             bUTF8 = sal_True;
139         }
140         else if ( sSwitch.ToUpperAscii() == "-NOUTF8" ) {
141             nState = STATE_UTF8;
142             bUTF8 = sal_False;
143         }
144         else if ( sSwitch == "-l"  || sSwitch == "-L" ) {
145             nState = STATE_LANGUAGES;
146         }
147         else {
148             switch ( nState ) {
149                 case STATE_NON: {
150                     return NULL;    // no valid command line
151                 }
152                 case STATE_INPUT: {
153                     aInputFileList.Insert( new ByteString( argv[ i ]), LIST_APPEND );
154                     bInput = sal_True; // min. one source file found
155                 }
156                 break;
157                 case STATE_OUTPUT: {
158                     sOutputFile = ByteString( argv[ i ]); // the dest. file
159                 }
160                 break;
161                 case STATE_PRJ: {
162                     sPrj = ByteString( argv[ i ]);
163                 }
164                 break;
165                 case STATE_ROOT: {
166                     sPrjRoot = ByteString( argv[ i ]); // path to project root
167                 }
168                 break;
169                 case STATE_MERGESRC: {
170                     sMergeSrc = ByteString( argv[ i ]);
171                     bMergeMode = sal_True; // activate merge mode, cause merge database found
172                 }
173                 break;
174                 case STATE_LANGUAGES: {
175                     Export::sLanguages = ByteString( argv[ i ]);
176                 }
177                 break;
178             }
179         }
180     }
181     if( bUnmerge ) sMergeSrc = ByteString();
182     if ( bInput ) {
183         // command line is valid
184         bEnableExport = sal_True;
185         char *pReturn = new char[ sOutputFile.Len() + 1 ];
186         strcpy( pReturn, sOutputFile.GetBuffer());  // #100211# - checked
187         return pReturn;
188     }
189 
190     // command line is not valid
191     return NULL;
192 }
193 /*****************************************************************************/
194 int InitExport( char *pOutput , char* pFilename )
195 /*****************************************************************************/
196 {
197     // instanciate Export
198     ByteString sOutput( pOutput );
199     ByteString sFilename( pFilename );
200 
201     if ( bMergeMode && !bUnmerge ) {
202         // merge mode enabled, so read database
203         pExport = new Export(sOutput, bEnableExport, sPrj, sPrjRoot, sMergeSrc , sFilename );
204     }
205     else
206         // no merge mode, only export
207         pExport = new Export( sOutput, bEnableExport, sPrj, sPrjRoot , sFilename );
208     return 1;
209 }
210 
211 /*****************************************************************************/
212 int EndExport()
213 /*****************************************************************************/
214 {
215     delete pExport;
216     return 1;
217 }
218 
219 extern const char* getFilename()
220 {
221     return (*(aInputFileList.GetObject( 0 ))).GetBuffer();
222 }
223 /*****************************************************************************/
224 extern FILE *GetNextFile()
225 /*****************************************************************************/
226 {
227     // look for next valid filename in input file list
228     if ( sTempFile.Len()) {
229         fclose( pTempFile );
230         String sTemp( sTempFile, RTL_TEXTENCODING_ASCII_US );
231         DirEntry aTemp( sTemp );
232         aTemp.Kill();
233     }
234 
235     while ( aInputFileList.Count()) {
236         ByteString sFileName( *(aInputFileList.GetObject( 0 )));
237 
238         ByteString sOrigFile( sFileName );
239 
240         sFileName = Export::GetNativeFile( sFileName );
241         delete aInputFileList.GetObject(( sal_uLong ) 0 );
242         aInputFileList.Remove(( sal_uLong ) 0 );
243 
244         if ( sFileName == "" ) {
245             fprintf( stderr, "ERROR: Could not precompile File %s\n",
246                 sOrigFile.GetBuffer());
247             return GetNextFile();
248         }
249 
250         sTempFile = sFileName;
251         Export::RemoveUTF8ByteOrderMarkerFromFile( sFileName );
252 
253         // able to open file?
254         FILE *pFile = fopen( sFileName.GetBuffer(), "r" );
255         if ( !pFile )
256             fprintf( stderr, "Error: Could not open File %s\n",
257                 sFileName.GetBuffer());
258         else {
259             pTempFile = pFile;
260 
261             // this is a valid file which can be opened, so
262             // create path to project root
263             DirEntry aEntry( String( sOrigFile, RTL_TEXTENCODING_ASCII_US ));
264             aEntry.ToAbs();
265             ByteString sFullEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
266             aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US ));
267             aEntry += DirEntry( sPrjRoot );
268             ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
269 
270             // create file name, beginnig with project root
271             // (e.g.: source\ui\src\menue.src)
272             sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 );
273 
274 
275             sActFileName.SearchAndReplaceAll( "/", "\\" );
276             sFile = sActFileName;
277 
278             if ( pExport ) {
279                 // create instance of class export
280                 pExport->Init();
281             }
282             // return the valid file handle
283             return pFile;
284         }
285     }
286     // this means the file could not be opened
287     return NULL;
288 }
289 
290 int Parse( int nTyp, const char *pTokenText ){
291     pExport->Execute( nTyp , pTokenText );
292     return 1;
293 }
294 void Close(){
295     pExport->pParseQueue->Close();
296 }
297 /*****************************************************************************/
298 int WorkOnTokenSet( int nTyp, char *pTokenText )
299 /*****************************************************************************/
300 {
301 
302     pExport->pParseQueue->Push( QueueEntry( nTyp , ByteString( pTokenText ) ) );
303     return 1;
304 }
305 
306 } // extern
307 
308 extern "C" {
309 /*****************************************************************************/
310 int SetError()
311 /*****************************************************************************/
312 {
313     // set error at global instance of class Export
314     pExport->SetError();
315     return 1;
316 }
317 }
318 
319 extern "C" {
320 /*****************************************************************************/
321 int GetError()
322 /*****************************************************************************/
323 {
324     // get error at global instance of class Export
325     if ( pExport->GetError())
326         return 1;
327     return sal_False;
328 }
329 }
330 
331 //
332 // class ResData
333 //
334 
335 void ResData::Dump(){
336     printf("**************\nResData\n");
337     printf("sPForm = %s , sResTyp = %s , sId = %s , sGId = %s , sHelpId = %s\n",sPForm.GetBuffer()
338         ,sResTyp.GetBuffer(),sId.GetBuffer(),sGId.GetBuffer(),sHelpId.GetBuffer());
339 
340     ByteString a("*pStringList");
341     ByteString b("*pUIEntries");
342     ByteString c("*pFilterList");
343     ByteString d("*pItemList");
344     ByteString e("*pPairedList");
345     ByteString f("sText");
346 
347     Export::DumpMap( f , sText );
348 
349     if( pStringList )   Export::DumpExportList( a , *pStringList );
350     if( pUIEntries )    Export::DumpExportList( b , *pUIEntries );
351     if( pFilterList )   Export::DumpExportList( c , *pFilterList );
352     if( pItemList )     Export::DumpExportList( d , *pItemList );
353     if( pPairedList )   Export::DumpExportList( e , *pPairedList );
354     printf("\n");
355 }
356 
357 void ResData::addFallbackData( ByteString& sId_in , const ByteString& sText_in ){
358     //printf(" ResData::addFallbackData ( sId = %s , sText = %s )\n", sId_in.GetBuffer() , sText_in.GetBuffer() );
359     aFallbackData[ sId_in ] = sText_in;
360 }
361 bool ResData::getFallbackData( ByteString& sId_in , ByteString& sText_inout ){
362     sText_inout = aFallbackData[ sId_in ];
363     //printf("ResData::getFallbackData( sId = %s , return sText = %s \n" , sId_in.GetBuffer(), sText_inout.GetBuffer());
364     return sText_inout.Len() > 0;
365 }
366 
367 void ResData::addMergedLanguage( ByteString& sLang ){
368     aMergedLanguages[ sLang ]=ByteString("1");
369 }
370 bool ResData::isMerged( ByteString& sLang ){
371     return aMergedLanguages[ sLang ].Equals("1");
372 }
373 
374 /*****************************************************************************/
375 sal_Bool ResData::SetId( const ByteString &rId, sal_uInt16 nLevel )
376 /*****************************************************************************/
377 {
378     if ( nLevel > nIdLevel )
379     {
380         nIdLevel = nLevel;
381         sId = rId;
382 
383         if ( bChild && bChildWithText ) {
384             ByteString sError( "ResId after child definition" );
385             yyerror( sError.GetBufferAccess());
386             sError.ReleaseBufferAccess();
387             SetError();
388         }
389 
390         if ( sId.Len() > 255 ) {
391             ByteString sWarning( "LocalId > 255 chars, truncating..." );
392             YYWarning( sWarning.GetBufferAccess());
393             sWarning.ReleaseBufferAccess();
394             sId.Erase( 255 );
395             sId.EraseTrailingChars( ' ' );
396             sId.EraseTrailingChars( '\t' );
397         }
398 
399         return sal_True;
400     }
401 
402     return sal_False;
403 }
404 
405 //
406 // class Export
407 //
408 
409 /*****************************************************************************/
410 Export::Export( const ByteString &rOutput, sal_Bool bWrite,
411                 const ByteString &rPrj, const ByteString &rPrjRoot , const ByteString& rFile )
412 /*****************************************************************************/
413                 :
414                 pWordTransformer( NULL ),
415                 aCharSet( RTL_TEXTENCODING_MS_1252 ),
416                 bDefine( sal_False ),
417                 bNextMustBeDefineEOL( sal_False ),
418                 nLevel( 0 ),
419                 nList( LIST_NON ),
420                 nListIndex( 0 ),
421                 nListLevel( 0 ),
422                 bSkipFile( false ),
423                 sProject( sPrj ),
424                 sRoot( sPrjRoot ),
425                 bEnableExport( bWrite ),
426                 bMergeMode( bUnmerge ),
427                 bError( sal_False ),
428                 bReadOver( sal_False ),
429                 bDontWriteOutput( sal_False ),
430                 sFilename( rFile )
431 {
432     pParseQueue = new ParserQueue( *this );
433     (void) rPrj;
434     (void) rPrjRoot;
435     (void) rFile;
436 
437     if( !isInitialized ) InitLanguages();
438     // used when export is enabled
439 
440     // open output stream
441     if ( bEnableExport ) {
442         aOutput.Open( String( rOutput, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC );
443         if( !aOutput.IsOpen() ) {
444             printf("ERROR : Can't open file %s\n",rOutput.GetBuffer());
445             exit ( -1 );
446         }
447         aOutput.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
448 
449         aOutput.SetLineDelimiter( LINEEND_CRLF );
450     }
451 }
452 
453 /*****************************************************************************/
454 Export::Export( const ByteString &rOutput, sal_Bool bWrite,
455                 const ByteString &rPrj, const ByteString &rPrjRoot,
456                 const ByteString &rMergeSource , const ByteString& rFile )
457 /*****************************************************************************/
458                 :
459                 pWordTransformer( NULL ),
460                 aCharSet( RTL_TEXTENCODING_MS_1252 ),
461                 bDefine( sal_False ),
462                 bNextMustBeDefineEOL( sal_False ),
463                 nLevel( 0 ),
464                 nList( LIST_NON ),
465                 nListIndex( 0 ),
466                 nListLevel( 0 ),
467                 bSkipFile( false ),
468                 sProject( sPrj ),
469                 sRoot( sPrjRoot ),
470                 bEnableExport( bWrite ),
471                 bMergeMode( sal_True ),
472                 sMergeSrc( rMergeSource ),
473                 bError( sal_False ),
474                 bReadOver( sal_False ),
475                 bDontWriteOutput( sal_False ),
476                 sFilename( rFile )
477 {
478     (void) rPrj;
479     (void) rPrjRoot;
480     (void) rFile;
481     pParseQueue = new ParserQueue( *this );
482     if( !isInitialized ) InitLanguages( bMergeMode );
483     // used when merge is enabled
484 
485     // open output stream
486     if ( bEnableExport ) {
487         aOutput.Open( String( rOutput, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC );
488         aOutput.SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
489         aOutput.SetLineDelimiter( LINEEND_CRLF );
490     }
491 
492 }
493 
494 /*****************************************************************************/
495 void Export::Init()
496 /*****************************************************************************/
497 {
498     // resets the internal status, used before parseing another file
499     sActPForm = "";
500     bDefine = sal_False;
501     bNextMustBeDefineEOL = sal_False;
502     nLevel = 0;
503     nList = LIST_NON;
504     nListLang = ByteString( String::CreateFromAscii(""),RTL_TEXTENCODING_ASCII_US );
505     nListIndex = 0;
506     while ( aResStack.Count()) {
507         delete aResStack.GetObject(( sal_uLong ) 0 );
508         aResStack.Remove(( sal_uLong ) 0 );
509     }
510 }
511 
512 /*****************************************************************************/
513 Export::~Export()
514 /*****************************************************************************/
515 {
516     if( pParseQueue )
517         delete pParseQueue;
518     // close output stream
519     if ( bEnableExport )
520         aOutput.Close();
521     while ( aResStack.Count()) {
522         delete aResStack.GetObject(( sal_uLong ) 0 );
523         aResStack.Remove(( sal_uLong ) 0 );
524     }
525 
526     if ( bMergeMode && !bUnmerge ) {
527         if ( !pMergeDataFile )
528             pMergeDataFile = new MergeDataFile( sMergeSrc,sFile , bErrorLog, aCharSet);//, bUTF8 );
529 
530         //pMergeDataFile->WriteErrorLog( sActFileName );
531         delete pMergeDataFile;
532     }
533 }
534 
535 /*****************************************************************************/
536 int Export::Execute( int nToken, const char * pToken )
537 /*****************************************************************************/
538 {
539 
540     ByteString sToken( pToken );
541     ByteString sOrig( sToken );
542 /*  printf("+---------------\n");
543     printf("sToken = %s\n",sToken.GetBuffer());
544     printf("nToken = %d\n",nToken);
545     printf("+---------------\n"); */
546     sal_Bool bWriteToMerged = bMergeMode;
547 
548     if ( nToken == CONDITION ) {
549         ByteString sTestToken( pToken );
550         sTestToken.EraseAllChars( '\t' );
551         sTestToken.EraseAllChars( ' ' );
552         if (( !bReadOver ) && ( sTestToken.Search( "#ifndef__RSC_PARSER" ) == 0 ))
553             bReadOver = sal_True;
554         else if (( bReadOver ) && ( sTestToken.Search( "#endif" ) == 0 ))
555             bReadOver = sal_False;
556     }
557     if ((( nToken < FILTER_LEVEL ) || ( bReadOver )) &&
558         (!(( bNextMustBeDefineEOL ) && ( sOrig == "\n" )))) {
559         // this tokens are not mandatory for parsing, so ignore them ...
560         if ( bMergeMode )
561             WriteToMerged( sOrig , false ); // ... ore whrite them directly to dest.
562         return 0;
563     }
564 
565     ResData *pResData = NULL;
566     if ( nLevel ) {
567         // res. exists at cur. level
568         pResData = aResStack.GetObject( nLevel-1 );
569     }
570     else if (( nToken != RESSOURCE ) &&
571             ( nToken != RESSOURCEEXPR ) &&
572             ( nToken != SMALRESSOURCE ) &&
573             ( nToken != LEVELUP ) &&
574             ( nToken != NORMDEFINE ) &&
575             ( nToken != RSCDEFINE ) &&
576             ( nToken != CONDITION ) &&
577             ( nToken != PRAGMA ))
578     {
579         // no res. exists at cur. level so return
580         if ( bMergeMode )
581             WriteToMerged( sOrig , false );
582         return 0;
583     }
584     // #define NO_LOCALIZE_EXPORT
585     if( bSkipFile ){
586         if ( bMergeMode ) {
587             WriteToMerged( sOrig , false );
588         }
589         return 1;
590     }
591 
592 
593     if ( bDefine ) {
594         if (( nToken != EMPTYLINE ) && ( nToken != LEVELDOWN ) && ( nToken != LEVELUP )) {
595             // cur. res. defined in macro
596             if ( bNextMustBeDefineEOL ) {
597                 if ( nToken != RSCDEFINELEND ) {
598                     // end of macro found, so destroy res.
599                     bDefine = sal_False;
600                     if ( bMergeMode ) {
601                         /*if ( bDontWriteOutput && bUnmerge ) {
602                             bDontWriteOutput = sal_False;
603                             bNextMustBeDefineEOL = sal_False;
604                             bDefine = sal_True;
605                         }*/
606                         MergeRest( pResData );
607                     }
608                     bNextMustBeDefineEOL = sal_False;
609                     Execute( LEVELDOWN, "" );
610                 }
611                 else {
612                     // next line also in macro definition
613                     bNextMustBeDefineEOL = sal_False;
614                     if ( bMergeMode )
615                         WriteToMerged( sOrig , false );
616                     return 1;
617                 }
618             }
619             else if (( nToken != LISTASSIGNMENT ) && ( nToken != UIENTRIES )){
620                 // cur. line has macro line end
621                 ByteString sTmpLine( sToken );
622                 sTmpLine.EraseAllChars( '\t' ); sTmpLine.EraseAllChars( ' ' );
623                 #if 0
624                 // impossible, unsigned is never negative
625                 if( sTmpLine.Len() < 0 ){
626                     if ( sTmpLine.GetChar(( sal_uInt16 )( sTmpLine.Len() - 1 )) != '\\' )
627                         bNextMustBeDefineEOL = sal_True;
628                 }
629                 #endif
630             }
631         }
632     }
633 
634     sal_Bool bExecuteDown = sal_False;
635     if ( nToken != LEVELDOWN ) {
636         sal_uInt16 nOpen = 0;
637         sal_uInt16 nClose = 0;
638         sal_Bool bReadOver1 = sal_False;
639         sal_uInt16 i = 0;
640         for ( i = 0; i < sToken.Len(); i++ ) {
641             if ( sToken.GetChar( i ) == '\"' )
642                 bReadOver1 = !bReadOver1;
643             if ( !bReadOver1 && ( sToken.GetChar( i ) == '{' ))
644                 nOpen++;
645         }
646 
647         bReadOver1 = sal_False;
648         for ( i = 0; i < sToken.Len(); i++ ) {
649             if ( sToken.GetChar( i ) == '\"' )
650                 bReadOver1 = !bReadOver1;
651             if ( !bReadOver1 && ( sToken.GetChar( i ) == '}' ))
652                 nClose++;
653         }
654 
655         if ( nOpen < nClose )
656             bExecuteDown = sal_True;
657     }
658     switch ( nToken ) {
659 
660         case NORMDEFINE:
661                         //printf("sToken = '%s'",sToken.GetBuffer());
662                         while( sToken.SearchAndReplace( "\r", " " ) != STRING_NOTFOUND ) {};
663                         while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {};
664                         while( sToken.SearchAndReplace( "  ", " " ) != STRING_NOTFOUND ) {};
665                         if( sToken.EqualsIgnoreCaseAscii( "#define NO_LOCALIZE_EXPORT" ) ){
666                             bSkipFile = true;
667                             return 0;
668                         }
669                         if ( bMergeMode )
670                           WriteToMerged( sOrig , false );
671 
672                         return 0;
673 
674 
675         case RSCDEFINE:
676             bDefine = sal_True; // res. defined in macro
677 
678         case RESSOURCE:
679         case RESSOURCEEXPR: {
680             bDontWriteOutput = sal_False;
681             if ( nToken != RSCDEFINE )
682                 bNextMustBeDefineEOL = sal_False;
683             // this is the beginning of a new res.
684             nLevel++;
685             if ( nLevel > 1 ) {
686                 aResStack.GetObject( nLevel - 2 )->bChild = sal_True;
687             }
688 
689             // create new instance for this res. and fill mandatory fields
690 
691             pResData = new ResData( sActPForm, FullId() , sFilename );
692             aResStack.Insert( pResData, LIST_APPEND );
693             ByteString sBackup( sToken );
694             sToken.EraseAllChars( '\n' );
695             sToken.EraseAllChars( '\r' );
696             sToken.EraseAllChars( '{' );
697             while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {};
698             sToken.EraseTrailingChars( ' ' );
699             ByteString sT =  sToken.GetToken( 0, ' ' );
700             pResData->sResTyp = sT.ToLowerAscii();
701             ByteString sId( sToken.Copy( pResData->sResTyp.Len() + 1 ));
702             ByteString sCondition;
703             if ( sId.Search( "#" ) != STRING_NOTFOUND ) {
704                 // between ResTyp, Id and paranthes is a precomp. condition
705                 sCondition = "#";
706                 sCondition += sId.GetToken( 1, '#' );
707                 sId = sId.GetToken( 0, '#' );
708             }
709             sId = sId.GetToken( 0, '/' );
710             CleanValue( sId );
711             sId = sId.EraseAllChars( '\t' );
712             pResData->SetId( sId, ID_LEVEL_IDENTIFIER );
713             if ( sCondition.Len()) {
714                 ByteString sEmpty( "" );
715                 Execute( CONDITION, sEmpty.GetBufferAccess());  // execute the
716                                                                 // precomp.
717                                                                 // condition
718                 sEmpty.ReleaseBufferAccess();
719             }
720         }
721         break;
722         case SMALRESSOURCE: {
723             bDontWriteOutput = sal_False;
724             // this is the beginning of a new res.
725             bNextMustBeDefineEOL = sal_False;
726             nLevel++;
727             if ( nLevel > 1 ) {
728                 aResStack.GetObject( nLevel - 2 )->bChild = sal_True;
729             }
730 
731             // create new instance for this res. and fill mandatory fields
732 
733             pResData = new ResData( sActPForm, FullId() , sFilename );
734             aResStack.Insert( pResData, LIST_APPEND );
735             sToken.EraseAllChars( '\n' );
736             sToken.EraseAllChars( '\r' );
737             sToken.EraseAllChars( '{' );
738             sToken.EraseAllChars( '\t' );
739             sToken.EraseAllChars( ' ' );
740             sToken.EraseAllChars( '\\' );
741             pResData->sResTyp = sToken.ToLowerAscii();
742         }
743         break;
744         case LEVELUP: {
745             // push
746             if ( nList )
747                 nListLevel++;
748             if ( nList )
749                 break;
750 
751             bDontWriteOutput = sal_False;
752             ByteString sLowerTyp;
753             if ( pResData )
754                 sLowerTyp = "unknown";
755             nLevel++;
756             if ( nLevel > 1 ) {
757                 aResStack.GetObject( nLevel - 2 )->bChild = sal_True;
758             }
759 
760             ResData *pNewData = new ResData( sActPForm, FullId() , sFilename );
761             pNewData->sResTyp = sLowerTyp;
762             aResStack.Insert( pNewData, LIST_APPEND );
763         }
764         break;
765         case LEVELDOWN: {
766             // pop
767             if ( !nList  ) {
768                 bDontWriteOutput = sal_False;
769                 if ( nLevel ) {
770                     if ( bDefine && (nLevel == 1 )) {
771                         bDefine = sal_False;
772                         bNextMustBeDefineEOL = sal_False;
773                     }
774                     WriteData( pResData );
775                     delete aResStack.GetObject( nLevel - 1 );
776                     aResStack.Remove( nLevel - 1 );
777                     nLevel--;
778                 }
779             }
780             else {
781                 if ( bDefine )
782                     bNextMustBeDefineEOL = sal_True;
783                 if ( !nListLevel ) {
784                     if ( bMergeMode )
785                         MergeRest( pResData, MERGE_MODE_LIST );
786                     nList = LIST_NON;
787                 }
788                 else
789                     nListLevel--;
790             }
791         }
792         break;
793         case ASSIGNMENT: {
794             bDontWriteOutput = sal_False;
795             // interpret different types of assignement
796             ByteString sKey = sToken.GetToken( 0, '=' );
797             sKey.EraseAllChars( ' ' );
798             sKey.EraseAllChars( '\t' );
799             ByteString sValue = sToken.GetToken( 1, '=' );
800             CleanValue( sValue );
801             if ( sKey.ToUpperAscii() == "IDENTIFIER" ) {
802                 ByteString sId( sValue.EraseAllChars( '\t' ));
803                 pResData->SetId( sId.EraseAllChars( ' ' ), ID_LEVEL_IDENTIFIER );
804             }
805             else if ( sKey == "HELPID" ) {
806                 pResData->sHelpId = sValue;
807             }
808             else if ( sKey == "STRINGLIST" ) {
809                 //if ( bUnmerge ){
810                 //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
811                 //}
812 
813                 pResData->bList = sal_True;
814                 nList = LIST_STRING;
815                 //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
816                 nListLang = SOURCE_LANGUAGE;
817                 nListIndex = 0;
818                 nListLevel = 0;
819             }
820             else if ( sKey == "FILTERLIST" ) {
821                 //if ( bUnmerge ){
822                 //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
823                 //}
824                 pResData->bList = sal_True;
825                 nList = LIST_FILTER;
826                 //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
827                 nListLang = SOURCE_LANGUAGE;
828                 nListIndex = 0;
829                 nListLevel = 0;
830             }
831             else if ( sKey == "UIENTRIES" ) {
832                 //if ( bUnmerge ){
833                 //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));}
834                 pResData->bList = sal_True;
835                 nList = LIST_UIENTRIES;
836                 //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
837                 nListLang = SOURCE_LANGUAGE;
838                 nListIndex = 0;
839                 nListLevel = 0;
840             }
841             if (( sToken.Search( "{" ) != STRING_NOTFOUND ) &&
842                 ( sToken.GetTokenCount( '{' ) > sToken.GetTokenCount( '}' )))
843             {
844                 //WorkOnTokenSet( LEVELUP, pTkn );
845                 Parse( LEVELUP, "" );
846             }
847             //if ( bUnmerge && ( nListLang.EqualsIgnoreCaseAscii("de") || nListLang.EqualsIgnoreCaseAscii("en-US") ) && ListExists( pResData, nList ))
848             //  bDontWriteOutput = sal_True;
849         }
850         break;
851         case UIENTRIES:
852         case LISTASSIGNMENT: {
853             bDontWriteOutput = sal_False;
854             ByteString sTmpToken( sToken);
855             sTmpToken.EraseAllChars(' ');
856             sal_uInt16 nPos = 0;
857             //nPos = sTmpToken.ToLowerAscii().Search("[de]=");
858             nPos = sTmpToken.ToLowerAscii().Search("[en-us]=");
859             if( nPos != STRING_NOTFOUND ) {
860                 //if ( bUnmerge ){
861                 //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
862                 //}
863                 ByteString sKey = sTmpToken.Copy( 0 , nPos );
864                 sKey.EraseAllChars( ' ' );
865                 sKey.EraseAllChars( '\t' );
866                 ByteString sValue = sToken.GetToken( 1, '=' );
867                 CleanValue( sValue );
868                 if ( sKey.ToUpperAscii() ==  "STRINGLIST" ) {
869                     pResData->bList = sal_True;
870                     nList = LIST_STRING;
871                     //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
872                     nListLang = SOURCE_LANGUAGE;
873                     nListIndex = 0;
874                     nListLevel = 0;
875                 }
876                 else if ( sKey == "FILTERLIST" ) {
877                     pResData->bList = sal_True;
878                     nList = LIST_FILTER;
879                     //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
880                     nListLang = SOURCE_LANGUAGE;
881                     nListIndex = 0;
882                     nListLevel = 0;
883                 }
884                 // PairedList
885                 else if ( sKey ==  "PAIREDLIST" ) {
886                     pResData->bList = sal_True;
887                     nList = LIST_PAIRED;
888                     //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
889                     nListLang = SOURCE_LANGUAGE;
890                     nListIndex = 0;
891                     nListLevel = 0;
892                 }
893 
894                 else if ( sKey ==  "ITEMLIST" ) {
895                     pResData->bList = sal_True;
896                     nList = LIST_ITEM;
897                     //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
898                     nListLang = SOURCE_LANGUAGE;
899                     nListIndex = 0;
900                     nListLevel = 0;
901                 }
902                 else if ( sKey ==  "UIENTRIES" ) {
903                     pResData->bList = sal_True;
904                     nList = LIST_UIENTRIES;
905                     //ByteString sLang("en-US" , RTL_TEXTENCODING_ASCII_US );
906                     nListLang = SOURCE_LANGUAGE;
907                     nListIndex = 0;
908                     nListLevel = 0;
909                 }
910                 /*if ( bUnmerge && ( nListLang.EqualsIgnoreCaseAscii( "de" )
911                     || nListLang.EqualsIgnoreCaseAscii("en-US" ) )
912                     && ListExists( pResData, nList ))
913                     bDontWriteOutput = sal_True;*/
914             }
915             else {
916                 // new res. is a String- or FilterList
917                 ByteString sKey = sToken.GetToken( 0, '[' );
918                 sKey.EraseAllChars( ' ' );
919                 sKey.EraseAllChars( '\t' );
920                 if ( sKey.ToUpperAscii() == "STRINGLIST" )
921                     nList = LIST_STRING;
922                 else if ( sKey == "FILTERLIST" )
923                     nList = LIST_FILTER;
924                 else if ( sKey == "PAIREDLIST" )
925                     nList = LIST_PAIRED;                // abcd
926                 else if ( sKey == "ITEMLIST" )
927                     nList = LIST_ITEM;
928                 else if ( sKey == "UIENTRIES" )
929                     nList = LIST_UIENTRIES;
930                 if ( nList ) {
931                     ByteString sLang=sToken.GetToken( 1, '[' ).GetToken( 0, ']' );
932                     CleanValue( sLang );
933                     nListLang = sLang;
934                     /*if (( bUnmerge ) && ( !nListLang.EqualsIgnoreCaseAscii("de")) && ( !nListLang.EqualsIgnoreCaseAscii("en-US")))
935                         bDontWriteOutput = sal_True;*/
936                     nListIndex = 0;
937                     nListLevel = 0;
938                     /*if ( bUnmerge && nListLang.EqualsIgnoreCaseAscii("de")  && ListExists( pResData, nList ) )
939                         bDontWriteOutput = sal_True;*/
940                 }
941             }
942         }
943         break;
944         case TEXT:
945         case _LISTTEXT:
946         case LISTTEXT: {
947             // this is an entry for a String- or FilterList
948             if ( nList ) {
949                 SetChildWithText();
950                 ByteString sEntry( sToken.GetToken( 1, '\"' ));
951                 if ( sToken.GetTokenCount( '\"' ) > 3 )
952                     sEntry += "\"";
953                 if ( sEntry == "\\\"" )
954                     sEntry = "\"";
955                 //sEntry = sEntry.Convert( aCharSet, RTL_TEXTENCODING_MS_1252 );
956                 //sEntry = sEntry.Convert( RTL_TEXTENCODING_MS_1252, RTL_TEXTENCODING_UTF8 );
957                 InsertListEntry( sEntry, sOrig );
958                 if ( bMergeMode && ( sEntry != "\"" )) {
959                     PrepareTextToMerge( sOrig, nList, nListLang, pResData );
960                 }
961             }
962         }
963         break;
964         case LONGTEXTLINE:
965         case TEXTLINE:
966             bDontWriteOutput = sal_False;
967             if ( nLevel ) {
968                 CutComment( sToken );
969 
970                 // this is a text line!!!
971                 ByteString sKey = sToken.GetToken( 0, '=' ).GetToken( 0, '[' );
972                 sKey.EraseAllChars( ' ' );
973                 sKey.EraseAllChars( '\t' );
974                 ByteString sText( GetText( sToken, nToken ));
975                 if ( !bMergeMode )
976                     sText = sText.Convert( aCharSet, RTL_TEXTENCODING_MS_1252 );
977                 ByteString sLang;
978                 if ( sToken.GetToken( 0, '=' ).Search( "[" ) != STRING_NOTFOUND ) {
979                     sLang = sToken.GetToken( 0, '=' ).GetToken( 1, '[' ).GetToken( 0, ']' );
980                     CleanValue( sLang );
981                 }
982                 ByteString nLangIndex = sLang;
983                 ByteString sOrigKey = sKey;
984                 if ( sText.Len() && sLang.Len() ) {
985                     if (( sKey.ToUpperAscii() == "TEXT" ) ||
986                         ( sKey == "MESSAGE" ) ||
987                         ( sKey == "CUSTOMUNITTEXT" ) ||
988                         ( sKey == "SLOTNAME" ) ||
989                         ( sKey == "UINAME" ))
990                     {
991                         //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND )
992                         //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
993 
994                         SetChildWithText();
995                         //if ( nLangIndex.EqualsIgnoreCaseAscii("en-US") )
996                         if ( Export::isSourceLanguage( nLangIndex ) )
997                             pResData->SetId( sText, ID_LEVEL_TEXT );
998 
999                         pResData->bText = sal_True;
1000                         pResData->sTextTyp = sOrigKey;
1001                         if ( bMergeMode ) {
1002                             PrepareTextToMerge( sOrig, STRING_TYP_TEXT, nLangIndex, pResData );
1003                             //if ( bUnmerge )
1004                             //  pResData->sText[ nLangIndex ] = sText;
1005                         }
1006                         else {
1007                             if ( pResData->sText[ nLangIndex ].Len()) {
1008                                 ByteString sError( "Language " );
1009                                 sError += nLangIndex;
1010                                 sError += " defined twice";
1011                             }
1012                             pResData->sText[ nLangIndex ] = sText;
1013                         }
1014                     }
1015                     else if ( sKey == "HELPTEXT" ) {
1016                         //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ){
1017                         //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
1018                         //  }
1019                         SetChildWithText();
1020                         pResData->bHelpText = sal_True;
1021                         if ( bBreakWhenHelpText ) {
1022                             ByteString sError( "\"HelpText\" found in source\n" );
1023                             YYWarning( sError.GetBufferAccess());
1024                             sError.ReleaseBufferAccess();
1025                             SetError();
1026                         }
1027                         if ( bMergeMode )
1028                             PrepareTextToMerge( sOrig, STRING_TYP_HELPTEXT, nLangIndex, pResData );
1029                             //if ( bUnmerge )
1030                             //  pResData->sHelpText[ nLangIndex ] = sText;
1031                         else {
1032                             if ( pResData->sHelpText[ nLangIndex ].Len()) {
1033                                 ByteString sError( "Language " );
1034                                 sError += nLangIndex;
1035                                 sError += " defined twice";
1036                             }
1037                             pResData->sHelpText[ nLangIndex ] = sText;
1038                         }
1039                     }
1040                     else if ( sKey == "QUICKHELPTEXT" ) {
1041                         //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ){
1042                         //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
1043                         //  }
1044                         SetChildWithText();
1045                         pResData->bQuickHelpText = sal_True;
1046                         if ( bMergeMode )
1047                             PrepareTextToMerge( sOrig, STRING_TYP_QUICKHELPTEXT, nLangIndex, pResData );
1048                             //if ( bUnmerge )
1049                             //  pResData->sQuickHelpText[ nLangIndex ] = sText;
1050                         else {
1051                             if ( pResData->sQuickHelpText[ nLangIndex ].Len()) {
1052                                 ByteString sError( "Language " );
1053                                 sError += nLangIndex;
1054                                 sError += " defined twice";
1055                             }
1056                             pResData->sQuickHelpText[ nLangIndex ] = sText;
1057                         }
1058                     }
1059                     else if ( sKey == "TITLE" ) {
1060                         //if ( bUnmerge && sToken.GetToken( 0, '=' ).Search( "[" ) == STRING_NOTFOUND ){
1061                         //  ( sOrig.SearchAndReplace( "=", "[ de ] =" ));
1062                         //  }
1063                         SetChildWithText();
1064                         pResData->bTitle = sal_True;
1065                         if ( bMergeMode )
1066                             PrepareTextToMerge( sOrig, STRING_TYP_TITLE, nLangIndex, pResData );
1067                             //if ( bUnmerge )
1068                             //  pResData->sTitle[ nLangIndex ] = sText;
1069                         else {
1070                             if ( pResData->sTitle[ nLangIndex ].Len()) {
1071                                 ByteString sError( "Language " );
1072                                 sError += nLangIndex;
1073                                 sError += " defined twice";
1074                             }
1075                             pResData->sTitle[ nLangIndex ] = sText;
1076                         }
1077                     }
1078                     else if ( sKey == "ACCESSPATH" ) {
1079                         pResData->SetId( sText, ID_LEVEL_ACCESSPATH );
1080                     }
1081                     else if ( sKey == "FIELDNAME" ) {
1082                         pResData->SetId( sText, ID_LEVEL_FIELDNAME );
1083                     }
1084                 }
1085             }
1086         break;
1087         case NEWTEXTINRES: {
1088             bDontWriteOutput = sal_True;
1089             // this means something like // ### Achtung : Neuer Text ...
1090             /*ByteString sLang( "GERMAN" );
1091             ByteString sText = sToken.GetToken( 2, ':' ).GetToken( 0, '*' );
1092             CleanValue( sText );
1093             if ( sText.Len())
1094                 pResData->sText[ sLang ] = sText;*/
1095         }
1096         break;
1097         case APPFONTMAPPING: {
1098             bDontWriteOutput = sal_False;
1099             // this is a AppfontMapping, so look if its a definition
1100             // of field size
1101             ByteString sKey = sToken.GetToken( 0, '=' );
1102             sKey.EraseAllChars( ' ' );
1103             sKey.EraseAllChars( '\t' );
1104             ByteString sMapping = sToken.GetToken( 1, '=' );
1105             sMapping = sMapping.GetToken( 1, '(' );
1106             sMapping = sMapping.GetToken( 0, ')' );
1107             sMapping.EraseAllChars( ' ' );
1108             sMapping.EraseAllChars( '\t' );
1109             if ( sKey.ToUpperAscii() == "SIZE" ) {
1110                 pResData->nWidth = ( sal_uInt16 ) sMapping.GetToken( 0, ',' ).ToInt64();
1111             }
1112             else if ( sKey == "POSSIZE" ) {
1113                 pResData->nWidth = ( sal_uInt16 ) sMapping.GetToken( 2, ',' ).ToInt64();
1114             }
1115         }
1116         break;
1117         case RSCDEFINELEND:
1118             bDontWriteOutput = sal_False;
1119         break;
1120         case CONDITION: {
1121             bDontWriteOutput = sal_False;
1122             while( sToken.SearchAndReplace( "\r", " " ) != STRING_NOTFOUND ) {};
1123             while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {};
1124             while( sToken.SearchAndReplace( "  ", " " ) != STRING_NOTFOUND ) {};
1125             ByteString sCondition = sToken.GetToken( 0, ' ' );
1126             if ( sCondition == "#ifndef" ) {
1127                 sActPForm = "!defined ";
1128                 sActPForm += sToken.GetToken( 1, ' ' );
1129             }
1130             else if ( sCondition == "#ifdef" ) {
1131                 sActPForm = "defined ";
1132                 sActPForm += sToken.GetToken( 1, ' ' );
1133             }
1134             else if ( sCondition == "#if" ) {
1135                 sActPForm = sToken.Copy( 4 );
1136                 while ( sActPForm.SearchAndReplace( "||", "\\or" ) != STRING_NOTFOUND ) {};
1137             }
1138             else if ( sCondition == "#elif" ) {
1139                 sActPForm = sToken.Copy( 6 );
1140                 while ( sActPForm.SearchAndReplace( "||", "\\or" ) != STRING_NOTFOUND ) {};
1141             }
1142             else if ( sCondition == "#else" ) {
1143                 sActPForm = sCondition;
1144             }
1145             else if ( sCondition == "#endif" ) {
1146                 sActPForm = "";
1147             }
1148             else break;
1149             if ( nLevel ) {
1150                 WriteData( pResData, sal_True );
1151                 pResData->sPForm = sActPForm;
1152             }
1153         }
1154         break;
1155         case EMPTYLINE : {
1156             bDontWriteOutput = sal_False;
1157             if ( bDefine ) {
1158                 bNextMustBeDefineEOL = sal_False;
1159                 bDefine = sal_False;
1160                 while ( nLevel )
1161                     Parse( LEVELDOWN, "" );
1162                     //WorkOnTokenSet( LEVELDOWN, pTkn );
1163             }
1164         }
1165         break;
1166         case PRAGMA : {
1167             bDontWriteOutput = sal_False;
1168             while( sToken.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {};
1169             while( sToken.SearchAndReplace( "  ", " " ) != STRING_NOTFOUND ) {};
1170             sToken.EraseLeadingChars( ' ' );
1171             sToken.EraseTrailingChars( ' ' );
1172 
1173             ByteString sCharset = sToken.GetToken( 1, ' ' );
1174             ByteString sSet = sToken.GetToken( 2, ' ' );
1175             if (( sCharset.ToUpperAscii() == "CHARSET_IBMPC" ) ||
1176                 ( sCharset == "RTL_TEXTENCODING_IBM_850" ) ||
1177                 (( sCharset == "CHARSET" ) && ( sSet.ToUpperAscii() == "IBMPC" )))
1178             {
1179                 aCharSet = RTL_TEXTENCODING_IBM_850;
1180             }
1181             else if (( sCharset == "CHARSET_ANSI" ) ||
1182                 ( sCharset == "RTL_TEXTENCODING_MS_1252" ) ||
1183                 (( sCharset == "CHARSET" ) && ( sSet.ToUpperAscii() == "ANSI" )))
1184             {
1185                 aCharSet = RTL_TEXTENCODING_MS_1252;
1186             }
1187         }
1188         break;
1189         case TEXTREFID : {
1190             bDontWriteOutput = sal_True;
1191             /*ByteString sK = sToken.GetToken( 0, '=' );
1192             ByteString sKey = sK.EraseAllChars( '\t' ).EraseAllChars( ' ' );
1193             ByteString sT = sToken.GetToken( 1, '=' ).GetToken( 0, ';' );
1194             sal_uInt16 nRefId = ( sal_uInt16 ) sT.EraseAllChars( '\t' ).EraseAllChars( ' ' ).ToInt32();
1195             if (( sKey.ToUpperAscii() == "TEXT" ) ||
1196                 ( sKey == "MESSAGE" ) ||
1197                 ( sKey == "CUSTOMUNITTEXT" ) ||
1198                 ( sKey == "SLOTNAME" ) ||
1199                 ( sKey == "UINAME" ))
1200                     pResData->nTextRefId = nRefId;
1201             else if ( sKey == "HELPTEXT" )
1202                 pResData->nHelpTextRefId = nRefId;
1203             else if ( sKey == "QUICKHELPTEXT" )
1204                 pResData->nQuickHelpTextRefId = nRefId;
1205             else if ( sKey == "TITLE" )
1206                 pResData->nTitleRefId = nRefId;*/
1207         }
1208         }
1209     if ( bWriteToMerged ) {
1210         // the current token must be written to dest. without merging
1211 
1212         if( bDefine && sOrig.Len() > 2 ){
1213             for( sal_uInt16 n = 0 ; n < sOrig.Len() ; n++ ){
1214                 if( sOrig.GetChar( n ) == '\n' && sOrig.GetChar( n-1 ) != '\\'){
1215                     sOrig.Insert('\\' , n++ );
1216                 }
1217             }
1218         }
1219         WriteToMerged( sOrig , false);
1220     }
1221 
1222     if ( bExecuteDown ) {
1223         Parse( LEVELDOWN, "" );
1224         //WorkOnTokenSet( LEVELDOWN, pTkn );
1225     }
1226 
1227     return 1;
1228 }
1229 
1230 /*****************************************************************************/
1231 void Export::CutComment( ByteString &rText )
1232 /*****************************************************************************/
1233 {
1234     if ( rText.Search( "//" ) != STRING_NOTFOUND ) {
1235         ByteString sWork( rText );
1236         sWork.SearchAndReplaceAll( "\\\"", "XX" );
1237         sal_uInt16 i = 0;
1238         sal_Bool bInner = sal_False;
1239 
1240         while ( i < sWork.Len() - 1 ) {
1241             if ( sWork.GetChar( i ) == '\"' )
1242                 bInner = !bInner;
1243             else if
1244                 (( sWork.GetChar( i ) == '/' ) &&
1245                 ( !bInner ) &&
1246                 ( sWork.GetChar( i + 1 ) == '/' ))
1247             {
1248                 rText.Erase( i );
1249                 return;
1250             }
1251             i++;
1252         }
1253     }
1254 }
1255 
1256 void Export::UnmergeUTF8( ByteString& sOrig ){
1257     sal_uInt16 nPos1 = sOrig.Search('\"');
1258     sal_uInt16 nPos2 = sOrig.SearchBackward('\"');
1259     if( nPos1 > 0 && nPos2 > 0 && nPos1 < nPos2){
1260         ByteString sPart = sOrig.Copy(nPos1+1 , nPos2-1);
1261         ByteString sPartUTF8 = sPart;
1262         sPartUTF8.Convert( RTL_TEXTENCODING_MS_1252 , RTL_TEXTENCODING_UTF8 );
1263         sOrig.SearchAndReplace( sPart , sPartUTF8 );
1264     }
1265 }
1266 
1267 /*****************************************************************************/
1268 sal_Bool Export::ListExists( ResData *pResData, sal_uInt16 nLst )
1269 /*****************************************************************************/
1270 {
1271     switch ( nLst ) {
1272         case LIST_STRING: return pResData->pStringList != NULL;
1273         case LIST_FILTER: return pResData->pFilterList != NULL;
1274         case LIST_ITEM: return pResData->pItemList != NULL;
1275         case LIST_PAIRED: return pResData->pPairedList != NULL;
1276         case LIST_UIENTRIES: return pResData->pUIEntries != NULL;
1277     }
1278     return sal_False;
1279 }
1280 
1281 /*****************************************************************************/
1282 sal_Bool Export::WriteData( ResData *pResData, sal_Bool bCreateNew )
1283 /*****************************************************************************/
1284 {
1285     if ( bMergeMode ) {
1286         MergeRest( pResData );
1287         return sal_True;
1288     }
1289 
1290     if ( bUnmerge )
1291         return sal_True;
1292 
1293 /*    ByteStringHashMap::iterator pos3 = pResData->sText.begin();
1294     ByteStringHashMap::iterator end3 = pResData->sText.end();
1295     for(;pos3!=end3;++pos3){
1296 
1297         printf("[%s]=%s\n", pos3->first.GetBuffer(), pos3->second.GetBuffer() );
1298     }*/
1299     // mandatory to export: en-US
1300 
1301      if (( //pResData->sText[ ByteString("de") ].Len() &&
1302         ( pResData->sText[ SOURCE_LANGUAGE ].Len()))
1303         ||
1304         ( //pResData->sHelpText[ ByteString("de") ].Len() &&
1305         (  pResData->sHelpText[ SOURCE_LANGUAGE ].Len()))
1306         ||
1307         ( //pResData->sQuickHelpText[ ByteString("de") ].Len() &&
1308         (  pResData->sQuickHelpText[ SOURCE_LANGUAGE ].Len()))
1309          ||
1310         ( //pResData->sTitle[ ByteString("de") ].Len() &&
1311         (  pResData->sTitle[ SOURCE_LANGUAGE ].Len())))
1312 
1313     {
1314         FillInFallbacks( pResData );
1315 
1316         ByteString sGID = pResData->sGId;
1317         ByteString sLID;
1318         if ( !sGID.Len())
1319             sGID = pResData->sId;
1320         else
1321             sLID = pResData->sId;
1322 
1323         ByteString sXText;
1324         ByteString sXHText;
1325         ByteString sXQHText;
1326         ByteString sXTitle;
1327 
1328         ByteString sTimeStamp( Export::GetTimeStamp());
1329         ByteString sCur;
1330 
1331         for( unsigned int n = 0; n < aLanguages.size(); n++ ){
1332             sCur = aLanguages[ n ];
1333                 if ( !sCur.EqualsIgnoreCaseAscii("x-comment") ){
1334                     if ( pResData->sText[ sCur ].Len())
1335                         sXText = pResData->sText[ sCur ];
1336                     else {
1337                         sXText = pResData->sText[ SOURCE_LANGUAGE ];
1338                         /*if ( !sXText.Len())
1339                             sXText = pResData->sText[ ByteString("en") ];
1340                         if ( !sXText.Len())
1341                             sXText = pResData->sText[ ByteString("de") ];*/
1342                     }
1343 
1344                     if ( pResData->sHelpText[ sCur ].Len())
1345                         sXHText = pResData->sHelpText[ sCur ];
1346                     else {
1347                         sXHText = pResData->sHelpText[ SOURCE_LANGUAGE ];
1348                         /*if ( !sXHText.Len())
1349                             sXHText = pResData->sHelpText[ ByteString("en") ];
1350                         if ( !sXText.Len())
1351                             sXHText = pResData->sHelpText[ ByteString("de") ];*/
1352                     }
1353 
1354                     if ( pResData->sQuickHelpText[ sCur ].Len())
1355                         sXQHText = pResData->sQuickHelpText[ sCur ];
1356                     else {
1357                         sXQHText = pResData->sQuickHelpText[ SOURCE_LANGUAGE ];
1358                         /*if ( !sXQHText.Len())
1359                             sXQHText = pResData->sQuickHelpText[ ByteString("en") ];
1360                         if ( !sXQHText.Len())
1361                             sXQHText = pResData->sQuickHelpText[ ByteString("de") ];*/
1362                     }
1363 
1364                     if ( pResData->sTitle[ sCur ].Len())
1365                         sXTitle = pResData->sTitle[ sCur ];
1366                     else {
1367                         sXTitle = pResData->sTitle[ SOURCE_LANGUAGE ];
1368                         /*if ( !sXTitle.Len())
1369                             sXTitle = pResData->sTitle[ ByteString("en") ];
1370                         if ( !sXTitle.Len())
1371                             sXTitle = pResData->sTitle[ ByteString("de") ];*/
1372                     }
1373 
1374                     if ( !sXText.Len())
1375                         sXText = "-";
1376 
1377                     if ( !sXHText.Len()) {
1378                         /*if ( pResData->sHelpText[ ByteString("de") ].Len())
1379                             sXHText = pResData->sHelpText[ ByteString("de") ];*/
1380                         if ( pResData->sHelpText[ SOURCE_LANGUAGE ].Len())
1381                             sXHText = pResData->sHelpText[ SOURCE_LANGUAGE ];
1382                         /*else if ( pResData->sHelpText[ ByteString("en") ].Len())
1383                             sXHText = pResData->sHelpText[ ByteString("en") ];*/
1384                     }
1385                 }
1386                 else
1387                     sXText = pResData->sText[ sCur ];
1388 
1389                 if ( bEnableExport ) {
1390                     ByteString sOutput( sProject ); sOutput += "\t";
1391                     if ( sRoot.Len())
1392                         sOutput += sActFileName;
1393                     sOutput += "\t0\t";
1394                     sOutput += pResData->sResTyp; sOutput += "\t";
1395                     sOutput += sGID; sOutput += "\t";
1396                     sOutput += sLID; sOutput += "\t";
1397                     sOutput += pResData->sHelpId; sOutput   += "\t";
1398                     sOutput += pResData->sPForm; sOutput    += "\t";
1399                     sOutput += ByteString::CreateFromInt64( pResData->nWidth ); sOutput += "\t";
1400                     sOutput += sCur; sOutput += "\t";
1401 
1402 
1403                     sOutput += sXText; sOutput  += "\t";
1404                     sOutput += sXHText; sOutput += "\t";
1405                     sOutput += sXQHText; sOutput+= "\t";
1406                     sOutput += sXTitle; sOutput += "\t";
1407                     sOutput += sTimeStamp;
1408 
1409                  // if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sProject ) ) )
1410                     aOutput.WriteLine( sOutput );
1411                 }
1412 
1413                 if ( bCreateNew ) {
1414                     pResData->sText[ sCur ]         = "";
1415                     pResData->sHelpText[ sCur ]     = "";
1416                     pResData->sQuickHelpText[ sCur ]= "";
1417                     pResData->sTitle[ sCur ]        = "";
1418                 }
1419             }
1420     }
1421     FillInFallbacks( pResData );
1422     if ( pResData->pStringList ) {
1423         ByteString sList( "stringlist" );
1424         WriteExportList( pResData, pResData->pStringList, sList, bCreateNew );
1425         if ( bCreateNew )
1426             pResData->pStringList = 0;
1427     }
1428     if ( pResData->pFilterList ) {
1429         ByteString sList( "filterlist" );
1430         WriteExportList( pResData, pResData->pFilterList, sList, bCreateNew );
1431         if ( bCreateNew )
1432             pResData->pFilterList = 0;
1433     }
1434     if ( pResData->pItemList ) {
1435         ByteString sList( "itemlist" );
1436         WriteExportList( pResData, pResData->pItemList, sList, bCreateNew );
1437         if ( bCreateNew )
1438             pResData->pItemList = 0;
1439     }
1440     if ( pResData->pPairedList ) {
1441         ByteString sList( "pairedlist" );
1442         WriteExportList( pResData, pResData->pPairedList, sList, bCreateNew );
1443         if ( bCreateNew )
1444             pResData->pItemList = 0;
1445     }
1446     if ( pResData->pUIEntries ) {
1447         ByteString sList( "uientries" );
1448         WriteExportList( pResData, pResData->pUIEntries, sList, bCreateNew );
1449         if ( bCreateNew )
1450             pResData->pUIEntries = 0;
1451     }
1452     return sal_True;
1453 }
1454 ByteString Export::GetPairedListID( const ByteString& sText ){
1455 // < "STRING" ; IDENTIFIER ; > ;
1456     ByteString sIdent = sText.GetToken( 1, ';' );
1457     sIdent.ToUpperAscii();
1458     while( sIdent.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {};
1459     sIdent.EraseTrailingChars( ' ' );
1460     sIdent.EraseLeadingChars( ' ' );
1461     return sIdent;
1462 }
1463 ByteString Export::GetPairedListString( const ByteString& sText ){
1464 // < "STRING" ; IDENTIFIER ; > ;
1465     ByteString sString = sText.GetToken( 0, ';' );
1466     while( sString.SearchAndReplace( "\t", " " ) != STRING_NOTFOUND ) {};
1467     sString.EraseTrailingChars( ' ' );
1468     ByteString s1 = sString.Copy( sString.Search( '\"' )+1 );
1469     sString = s1.Copy( 0 , s1.SearchBackward( '\"' ) );
1470     sString.EraseTrailingChars( ' ' );
1471     sString.EraseLeadingChars( ' ' );
1472     return sString;
1473 }
1474 ByteString Export::StripList( const ByteString& sText ){
1475     ByteString s1 = sText.Copy( sText.Search( '\"' ) + 1 );
1476     return s1.Copy( 0 , s1.SearchBackward( '\"' ) );
1477 }
1478 
1479 /*****************************************************************************/
1480 sal_Bool Export::WriteExportList( ResData *pResData, ExportList *pExportList,
1481                         const ByteString &rTyp, sal_Bool bCreateNew )
1482 /*****************************************************************************/
1483 {
1484     ByteString sGID = pResData->sGId;
1485     if ( !sGID.Len())
1486         sGID = pResData->sId;
1487     else {
1488         sGID += ".";
1489         sGID += pResData->sId;
1490         sGID.EraseTrailingChars( '.' );
1491     }
1492 
1493     ByteString sTimeStamp( Export::GetTimeStamp());
1494     ByteString sCur;
1495     for ( sal_uLong i = 0; pExportList != NULL && i < pExportList->Count(); i++ ) {
1496         ExportListEntry *pEntry = pExportList->GetObject( i );
1497                 // mandatory for export: german and eng. and/or enus
1498         //ByteString a("Export::WriteExportList::pEntry");
1499         //Export::DumpMap( a,  *pEntry );
1500 
1501         ByteString sLID( ByteString::CreateFromInt64( i + 1 ));
1502         for( unsigned int n = 0; n < aLanguages.size(); n++ ){
1503             sCur = aLanguages[ n ];
1504             if ( //1 )
1505                   //(*pEntry)[ ByteString("de") ].Len() &&
1506                     (*pEntry)[ SOURCE_LANGUAGE ].Len() )
1507                     //||
1508                     //  (*pEntry)[ ByteString("en") ].Len()))
1509                 {
1510                     if ( bEnableExport )
1511                     {
1512                         ByteString sText((*pEntry)[ SOURCE_LANGUAGE ] );
1513 
1514                         // Strip PairList Line String
1515                         if( rTyp.EqualsIgnoreCaseAscii("pairedlist") ){
1516                             sLID = GetPairedListID( sText );
1517                             if ((*pEntry)[ sCur ].Len())
1518                                 sText = (*pEntry)[ sCur ];
1519                             sText = GetPairedListString( sText );
1520                         }
1521                         else{
1522                             //if ((*pEntry)[ sCur ].Len()){
1523                             //  if( sCur.EqualsIgnoreCaseAscii("de") ){
1524                             //      sText = StripList( (*pEntry)[ sCur ] );
1525                             //  }
1526                             //  else
1527                                     sText = StripList( (*pEntry)[ sCur ] );
1528                                     if( sText == "\\\"" )
1529                                         sText = "\"";
1530                             //}
1531                         }
1532 
1533                         ByteString sOutput( sProject ); sOutput += "\t";
1534                         if ( sRoot.Len())
1535                             sOutput += sActFileName;
1536                         sOutput += "\t0\t";
1537                         sOutput += rTyp; sOutput += "\t";
1538                         sOutput += sGID; sOutput += "\t";
1539                         sOutput += sLID; sOutput += "\t\t";
1540                         sOutput += pResData->sPForm; sOutput += "\t0\t";
1541                         sOutput += sCur; sOutput += "\t";
1542 
1543                         sOutput += sText; sOutput += "\t\t\t\t";
1544                         sOutput += sTimeStamp;
1545 
1546                         //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sProject ) ) )
1547                         aOutput.WriteLine( sOutput );
1548 
1549                     }
1550                 }
1551         }
1552         if ( bCreateNew )
1553             delete [] pEntry;
1554     }
1555     if ( bCreateNew )
1556         delete pExportList;
1557 
1558     return sal_True;
1559 }
1560 
1561 /*****************************************************************************/
1562 ByteString Export::FullId()
1563 /*****************************************************************************/
1564 {
1565     ByteString sFull;
1566     if ( nLevel > 1 ) {
1567         sFull = aResStack.GetObject( 0 )->sId;
1568         for ( sal_uInt16 i = 1; i < nLevel - 1; i++ ) {
1569             ByteString sToAdd = aResStack.GetObject( i )->sId;
1570             if ( sToAdd.Len()) {
1571                 sFull += ".";
1572                 sFull += sToAdd;
1573             }
1574         }
1575     }
1576     if ( sFull.Len() > 255 ) {
1577         ByteString sError( "GroupId > 255 chars" );
1578         printf("GroupID = %s\n",sFull.GetBuffer());
1579         yyerror( sError.GetBufferAccess());
1580         sError.ReleaseBufferAccess();
1581     }
1582 
1583     return sFull;
1584 }
1585 
1586 /*****************************************************************************/
1587 void Export::InsertListEntry( const ByteString &rText, const ByteString &rLine )
1588 /*****************************************************************************/
1589 {
1590     ResData *pResData = aResStack.GetObject( nLevel-1 );
1591 
1592     ExportList *pList = NULL;
1593     if ( nList == LIST_STRING ) {
1594         pList = pResData->pStringList;
1595         if ( !pList ) {
1596             pResData->pStringList = new ExportList();
1597             pList = pResData->pStringList;
1598             nListIndex = 0;
1599         }
1600     }
1601     else if ( nList == LIST_FILTER ) {
1602         pList = pResData->pFilterList;
1603         if ( !pList ) {
1604             pResData->pFilterList = new ExportList();
1605             pList = pResData->pFilterList;
1606             nListIndex = 0;
1607         }
1608     }
1609     else if ( nList == LIST_ITEM ) {
1610         pList = pResData->pItemList;
1611         if ( !pList ) {
1612             pResData->pItemList = new ExportList();
1613             pList = pResData->pItemList;
1614             nListIndex = 0;
1615         }
1616     }
1617     else if ( nList == LIST_PAIRED ) {
1618         pList = pResData->pPairedList;
1619         if ( !pList ) {
1620             pResData->pPairedList = new ExportList();
1621             pList = pResData->pPairedList;
1622             nListIndex = 0;
1623         }
1624     }
1625     else if ( nList == LIST_UIENTRIES ) {
1626         pList = pResData->pUIEntries;
1627         if ( !pList ) {
1628             pResData->pUIEntries = new ExportList();
1629             pList = pResData->pUIEntries;
1630             nListIndex = 0;
1631         }
1632     }
1633     else
1634         return;
1635 
1636     if ( nListIndex + 1 > pList->Count()) {
1637         ExportListEntry *pNew = new ExportListEntry();
1638         (*pNew)[ LIST_REFID ] = ByteString::CreateFromInt32( REFID_NONE );
1639         pList->Insert( pNew, LIST_APPEND );
1640     }
1641     ExportListEntry *pCurEntry = pList->GetObject( nListIndex );
1642 
1643     // For paired list use the line to set proper lid
1644     if( nList == LIST_PAIRED ){
1645         (*pCurEntry)[ nListLang ] = rLine;
1646     }else
1647         (*pCurEntry)[ nListLang ] = rText;
1648 
1649     // Remember en-US fallback string, so each list has the same amount of elements
1650     //if ( nListLang.EqualsIgnoreCaseAscii("en-US")  ) {
1651     if ( Export::isSourceLanguage( nListLang ) ) {
1652         if( nList == LIST_PAIRED ){
1653             const ByteString sPlist("pairedlist");
1654             ByteString sKey = MergeDataFile::CreateKey( sPlist , pResData->sId , GetPairedListID( rLine ) , sFilename );
1655             pResData->addFallbackData( sKey , rText );
1656         }
1657         // new fallback
1658         else{
1659             const ByteString sPlist("list");
1660             ByteString a( pResData->sGId );
1661             a.Append( "." );
1662             a.Append( pResData->sId );
1663             sal_Int64 x = nListIndex+1;
1664             ByteString b( ByteString::CreateFromInt64( x ) );
1665             ByteString sKey = MergeDataFile::CreateKey( sPlist , a , b  , sFilename );
1666             pResData->addFallbackData( sKey , rText );
1667         }
1668         // new fallback
1669     }
1670 
1671     //if ( nListLang.EqualsIgnoreCaseAscii("en-US")  ) {
1672     if ( Export::isSourceLanguage( nListLang ) ) {
1673         if( nList == LIST_PAIRED ){
1674             (*pCurEntry)[ SOURCE_LANGUAGE ] = rLine;
1675         }
1676         else
1677             (*pCurEntry)[ SOURCE_LANGUAGE ] = rLine;
1678 
1679         pList->NewSourceLanguageListEntry();
1680     }
1681 
1682     //printf("Export::InsertListEntry ResData.id = %s ResData.ListData = %s\n",pResData->sId.GetBuffer() ,(*pCurEntry)[ nListLang ].GetBuffer());
1683     nListIndex++;
1684 }
1685 
1686 /*****************************************************************************/
1687 void Export::CleanValue( ByteString &rValue )
1688 /*****************************************************************************/
1689 {
1690     while ( rValue.Len()) {
1691         if (( rValue.GetChar( 0 ) == ' ' ) || ( rValue.GetChar( 0 ) == '\t' ))
1692             rValue = rValue.Copy( 1 );
1693         else
1694             break;
1695     }
1696 
1697     if ( rValue.Len()) {
1698         for ( sal_uInt16 i = rValue.Len() - 1; i > 0; i-- ) {
1699             if (( rValue.GetChar( i ) == ' ' ) || ( rValue.GetChar( i ) == '\t' ) ||
1700                 ( rValue.GetChar( i ) == '\n' ) || ( rValue.GetChar( i ) == ';' ) ||
1701                 ( rValue.GetChar( i ) == '{' ) || ( rValue.GetChar( i ) == '\\' ) ||
1702                 ( rValue.GetChar( i ) == '\r' ))
1703                 rValue.Erase( i );
1704             else
1705                 break;
1706         }
1707     }
1708 }
1709 
1710 
1711 /*****************************************************************************/
1712 ByteString Export::GetText( const ByteString &rSource, int nToken )
1713 /*****************************************************************************/
1714 #define TXT_STATE_NON   0x000
1715 #define TXT_STATE_TEXT  0x001
1716 #define TXT_STATE_MACRO 0x002
1717 {
1718     ByteString sReturn;
1719     switch ( nToken ) {
1720         case TEXTLINE:
1721         case LONGTEXTLINE: {
1722             ByteString sTmp( rSource.Copy( rSource.Search( "=" )));
1723             CleanValue( sTmp );
1724             sTmp.EraseAllChars( '\n' );
1725             sTmp.EraseAllChars( '\r' );
1726 
1727             while ( sTmp.SearchAndReplace( "\\\\\"", "-=<[BSlashBSlashHKom]>=-\"" )
1728                 != STRING_NOTFOUND ) {};
1729             while ( sTmp.SearchAndReplace( "\\\"", "-=<[Hochkomma]>=-" )
1730                 != STRING_NOTFOUND ) {};
1731             while ( sTmp.SearchAndReplace( "\\", "-=<[0x7F]>=-" )
1732                 != STRING_NOTFOUND ) {};
1733             while ( sTmp.SearchAndReplace( "\\0x7F", "-=<[0x7F]>=-" )
1734                 != STRING_NOTFOUND ) {};
1735 
1736             sal_uInt16 nStart = 0;
1737             sal_uInt16 nState = TXT_STATE_MACRO;
1738 
1739             nState = TXT_STATE_TEXT;
1740             nStart = 1;
1741 
1742 
1743             for ( sal_uInt16 i = nStart; i < sTmp.GetTokenCount( '\"' ); i++ ) {
1744                 ByteString sToken = sTmp.GetToken( i, '\"' );
1745                 if ( sToken.Len()) {
1746                     if ( nState == TXT_STATE_TEXT ) {
1747                         sReturn += sToken;
1748                         nState = TXT_STATE_MACRO;
1749                     }
1750                     else {
1751                         while( sToken.SearchAndReplace( "\t", " " ) !=
1752                             STRING_NOTFOUND ) {};
1753                         while( sToken.SearchAndReplace( "  ", " " ) !=
1754                             STRING_NOTFOUND ) {};
1755                         sToken.EraseLeadingChars( ' ' );
1756                         sToken.EraseTrailingChars( ' ' );
1757                         if ( sToken.Len()) {
1758                             sReturn += "\\\" ";
1759                             sReturn += sToken;
1760                             sReturn += " \\\"";
1761                         }
1762                         nState = TXT_STATE_TEXT;
1763                     }
1764                 }
1765             }
1766 
1767             while ( sReturn.SearchAndReplace( "-=<[0x7F]>=-", "" )
1768                 != STRING_NOTFOUND ) {};
1769             while ( sReturn.SearchAndReplace( "-=<[Hochkomma]>=-", "\"" )
1770                 != STRING_NOTFOUND ) {};
1771             while ( sReturn.SearchAndReplace( "-=<[BSlashBSlashHKom]>=-", "\\\\" )
1772                 != STRING_NOTFOUND ) {};
1773 
1774 
1775             while ( sReturn.SearchAndReplace( "\\\\", "-=<[BSlashBSlash]>=-" )
1776                 != STRING_NOTFOUND ) {};
1777             while ( sReturn.SearchAndReplace( "-=<[BSlashBSlash]>=-", "\\" )
1778                 != STRING_NOTFOUND ) {};
1779 
1780         }
1781         break;
1782     }
1783     return sReturn;
1784 }
1785 
1786 /*****************************************************************************/
1787 void Export::WriteToMerged( const ByteString &rText , bool bSDFContent )
1788 /*****************************************************************************/
1789 {
1790     static ByteString SLASH  ('\\');
1791     static ByteString RETURN ('\n');
1792     //printf("%s\n",rText.GetBuffer() );
1793 
1794     #if 0
1795     // statement has no effect
1796     if( pParseQueue->bMflag && !bSDFContent ) pParseQueue->bMflag;
1797     #endif
1798 
1799     if ( !bDontWriteOutput || !bUnmerge ) {
1800         ByteString sText( rText );
1801         while ( sText.SearchAndReplace( " \n", "\n" ) != STRING_NOTFOUND ) {};
1802         if( pParseQueue->bNextIsM && bSDFContent && sText.Len() > 2 ){
1803             for( sal_uInt16 n = 0 ; n < sText.Len() ; n++ ){
1804                 if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){
1805                     sText.Insert('\\' , n++ );
1806 
1807                 }
1808             }
1809         }
1810         else if( pParseQueue->bLastWasM && sText.Len() > 2 ){
1811             for( sal_uInt16 n = 0 ; n < sText.Len() ; n++ ){
1812                 if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){
1813                     sText.Insert('\\' , n++ );
1814                 }
1815                 if( sText.GetChar( n ) == '\n' )pParseQueue->bMflag=true;
1816             }
1817         }
1818         else if( pParseQueue->bCurrentIsM && bSDFContent && sText.Len() > 2 ){
1819             for( sal_uInt16 n = 0 ; n < sText.Len() ; n++ ){
1820                 if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){
1821                     sText.Insert('\\' , n++ );
1822                     pParseQueue->bMflag=true;
1823                 }
1824             }
1825         }
1826         else if( pParseQueue->bMflag ){
1827             for( sal_uInt16 n = 1 ; n < sText.Len() ; n++ ){
1828                 if( sText.GetChar( n ) == '\n' && sText.GetChar( n-1 ) != '\\'){
1829                     sText.Insert('\\' , n++ );
1830                 }
1831             }
1832         }
1833         for ( sal_uInt16 i = 0; i < sText.Len(); i++ ) {
1834             if ( sText.GetChar( i ) != '\n' ){
1835                 aOutput.Write( ByteString( sText.GetChar( i )).GetBuffer(), 1 );
1836 
1837             }
1838             else{
1839                 aOutput.WriteLine( ByteString());
1840             }
1841 
1842         }
1843     }
1844 }
1845 
1846 /*****************************************************************************/
1847 void Export::ConvertMergeContent( ByteString &rText )
1848 /*****************************************************************************/
1849 {
1850     sal_Bool bNoOpen = ( rText.Search( "\\\"" ) != 0 );
1851     ByteString sClose( rText.Copy( rText.Len() - 2 ));
1852     sal_Bool bNoClose = ( sClose != "\\\"" );
1853     ByteString sNew;
1854     for ( sal_uInt16 i = 0; i < rText.Len(); i++ ) {
1855         ByteString sChar( rText.GetChar( i ));
1856         if ( sChar == "\\" ) {
1857             if (( i + 1 ) < rText.Len()) {
1858                 ByteString sNext( rText.GetChar( i + 1 ));
1859                 if ( sNext == "\"" ) {
1860                     sChar = "\"";
1861                     i++;
1862                 }
1863                 else if ( sNext == "n" ) {
1864                     sChar = "\\n";
1865                     i++;
1866                 }
1867                 else if ( sNext == "t" ) {
1868                     sChar = "\\t";
1869                     i++;
1870                 }
1871                 else if ( sNext == "\'" ) {
1872                     sChar = "\\\'";
1873                     i++;
1874                 }
1875                 else
1876                     sChar = "\\\\";
1877             }
1878             else {
1879                 sChar = "\\\\";
1880             }
1881         }
1882         else if ( sChar == "\"" ) {
1883             sChar = "\\\"";
1884         }
1885         else if ( sChar == "" ) {
1886             sChar = "\\0x7F";
1887         }
1888         sNew += sChar;
1889     }
1890 
1891     rText = sNew;
1892 
1893     if ( bNoOpen ) {
1894         ByteString sTmp( rText );
1895         rText = "\"";
1896         rText += sTmp;
1897     }
1898     if ( bNoClose )
1899         rText += "\"";
1900 }
1901 
1902 /*****************************************************************************/
1903 sal_Bool Export::PrepareTextToMerge( ByteString &rText, sal_uInt16 nTyp,
1904                                 ByteString &nLangIndex, ResData *pResData )
1905 /*****************************************************************************/
1906 {
1907     // position to merge in:
1908     sal_uInt16 nStart = 0;
1909     sal_uInt16 nEnd = 0;
1910     ByteString sOldId = pResData->sId;
1911     ByteString sOldGId = pResData->sGId;
1912     ByteString sOldTyp = pResData->sResTyp;
1913 
1914     ByteString sOrigText( rText );
1915 
1916     switch ( nTyp ) {
1917         case LIST_STRING :
1918         case LIST_UIENTRIES :
1919         case LIST_FILTER :
1920         case LIST_PAIRED:
1921         case LIST_ITEM :
1922         {
1923             if ( bUnmerge )
1924                 return sal_True;
1925 
1926             ExportList *pList = NULL;
1927             switch ( nTyp ) {
1928                 case LIST_STRING : {
1929                     pResData->sResTyp = "stringlist";
1930                     pList = pResData->pStringList;
1931                 }
1932                 break;
1933                 case LIST_UIENTRIES : {
1934                     pResData->sResTyp = "uientries";
1935                     pList = pResData->pUIEntries;
1936                 }
1937                 break;
1938                 case LIST_FILTER : {
1939                     pResData->sResTyp = "filterlist";
1940                     pList = pResData->pFilterList;
1941                 }
1942                 break;
1943                 case LIST_ITEM : {
1944                     pResData->sResTyp = "itemlist";
1945                     pList = pResData->pItemList;
1946                 }
1947                 break;
1948                 case LIST_PAIRED : {
1949                     pResData->sResTyp = "pairedlist";
1950                     pList = pResData->pPairedList;
1951                 }
1952                 break;
1953 
1954             }
1955             if ( pList ) {
1956                 ExportListEntry *pCurEntry = pList->GetObject( nListIndex - 1 );
1957                 if ( pCurEntry ) {
1958                     //printf("%s\n",Export::DumpMap( "pCurEntry", *pCurEntry ).GetBuffer() );
1959                     //ByteString a("pCurEntry");
1960                     //Export::DumpMap( a , *pCurEntry );
1961                     rText = (*pCurEntry)[ SOURCE_LANGUAGE ];
1962                     if( nTyp == LIST_PAIRED ){
1963                         pResData->addMergedLanguage( nLangIndex );
1964                     }
1965                 }
1966             }
1967 
1968             nStart = rText.Search( "\"" );
1969             if ( nStart == STRING_NOTFOUND ) {
1970                 rText = sOrigText;
1971                 return sal_False;
1972             }
1973 
1974             sal_Bool bFound = sal_False;
1975             for ( nEnd = nStart + 1; nEnd < rText.Len() && !bFound; nEnd++ ) {
1976                 if ( rText.GetChar( nEnd ) == '\"' )
1977                     bFound = sal_True;
1978             }
1979             if ( !bFound ) {
1980                 rText = sOrigText;
1981                 return sal_False;
1982             }
1983 
1984             nEnd --;
1985             sLastListLine = rText;
1986             if (( sLastListLine.Search( ">" ) != STRING_NOTFOUND ) &&
1987                 ( sLastListLine.Search( "<" ) == STRING_NOTFOUND ))
1988             {
1989                 ByteString sTmp = sLastListLine;
1990                 sLastListLine = "<";
1991                 sLastListLine += sTmp;
1992             }
1993             if ( pResData->sResTyp.EqualsIgnoreCaseAscii( "pairedlist" ) ){
1994                pResData->sId = GetPairedListID( sLastListLine );
1995             }
1996             else pResData->sId = ByteString::CreateFromInt32( nListIndex );
1997 
1998             if ( pResData->sGId.Len())
1999                 pResData->sGId += ".";
2000             pResData->sGId += sOldId;
2001             nTyp = STRING_TYP_TEXT;
2002         }
2003         break;
2004         case STRING_TYP_TEXT :
2005         case STRING_TYP_HELPTEXT :
2006         case STRING_TYP_QUICKHELPTEXT :
2007         case STRING_TYP_TITLE :
2008         {
2009             /*if ( bUnmerge ) {
2010                 if (( nLangIndex != ByteString("de") ) &&
2011                     ( nLangIndex != ByteString("en-US") ))
2012                 {
2013                     bDontWriteOutput = sal_True;
2014                 }
2015                 return sal_True;
2016             }*/
2017 
2018             nStart = rText.Search( "=" );
2019             if ( nStart == STRING_NOTFOUND ) {
2020                 rText = sOrigText;
2021                 return sal_False;
2022             }
2023 
2024             nStart++;
2025             sal_Bool bFound = sal_False;
2026             while(( nStart < rText.Len()) && !bFound ) {
2027                 if (( rText.GetChar( nStart ) != ' ' ) && ( rText.GetChar( nStart ) != '\t' ))
2028                     bFound = sal_True;
2029                 else
2030                     nStart ++;
2031             }
2032 
2033             // no start position found
2034             if ( !bFound ) {
2035                 rText = sOrigText;
2036                 return sal_False;
2037             }
2038 
2039             // position to end mergeing in
2040             nEnd = rText.Len() - 1;
2041             bFound = sal_False;
2042 
2043             while (( nEnd > nStart ) && !bFound ) {
2044                 if (( rText.GetChar( nEnd ) != ' ' ) && ( rText.GetChar( nEnd ) != '\t' ) &&
2045                     ( rText.GetChar( nEnd ) != '\n' ) && ( rText.GetChar( nEnd ) != ';' ) &&
2046                     ( rText.GetChar( nEnd ) != '{' ) && ( rText.GetChar( nEnd ) != '\\' ))
2047                 {
2048                     bFound = sal_True;
2049                 }
2050                 else
2051                     nEnd --;
2052             }
2053         }
2054         break;
2055     }
2056 
2057     // search for merge data
2058     if ( !pMergeDataFile ){
2059         pMergeDataFile = new MergeDataFile( sMergeSrc, sFile , bErrorLog, aCharSet);//, bUTF8 );
2060 
2061         // Init Languages
2062         ByteString sTmp = Export::sLanguages;
2063         if( sTmp.ToUpperAscii().Equals("ALL") )
2064             SetLanguages( pMergeDataFile->GetLanguages() );
2065         else if( !isInitialized )InitLanguages();
2066 
2067     }
2068 //  printf("*************DUMPING****************\n");
2069 //  printf("%s\n",pMergeDataFile->Dump().GetBuffer());
2070 //  printf("*************DUMPING****************\n");
2071 
2072 //  printf("Dumping ResData\n");
2073 //  pResData->Dump();
2074     PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData );
2075     //printf("Dumping pEntrys\n");
2076     //if( pEntrys ) pEntrys->Dump();
2077     pResData->sId = sOldId;
2078     pResData->sGId = sOldGId;
2079     pResData->sResTyp = sOldTyp;
2080 
2081     if ( !pEntrys ) {
2082         rText = sOrigText;
2083         return sal_False; // no data found
2084     }
2085 
2086     ByteString sContent;
2087     pEntrys->GetTransex3Text( sContent, nTyp, nLangIndex );
2088     //if ( !sContent.Len() && ( ! nLangIndex.EqualsIgnoreCaseAscii("en-US") )) {
2089     if ( !sContent.Len() && ( ! Export::isSourceLanguage( nLangIndex ) )) {
2090         rText = sOrigText;
2091         return sal_False; // no data found
2092     }
2093 
2094     //if ( nLangIndex.EqualsIgnoreCaseAscii("en-US") ) {
2095     if ( Export::isSourceLanguage( nLangIndex ) ) {
2096         return sal_False;
2097     }
2098 
2099     ByteString sPostFix( rText.Copy( ++nEnd ));
2100     rText.Erase( nStart );
2101 
2102     //ConvertMergeContent( sContent, nTyp );
2103     ConvertMergeContent( sContent );
2104 
2105 
2106 
2107     //printf("Merged %s\n",nLangIndex.GetBuffer());
2108     // merge new res. in text line
2109     rText += sContent;
2110     rText += sPostFix;
2111 
2112     return sal_True;
2113 }
2114 
2115 /*****************************************************************************/
2116 void Export::MergeRest( ResData *pResData, sal_uInt16 nMode )
2117 /*****************************************************************************/
2118 {
2119     //if ( bUnmerge ) { return;}
2120 
2121     //pResData->Dump();
2122 
2123     if ( !pMergeDataFile ){
2124         pMergeDataFile = new MergeDataFile( sMergeSrc, sFile ,bErrorLog, aCharSet);//, bUTF8 );
2125 
2126         // Init Languages
2127         ByteString sTmp = Export::sLanguages;
2128         if( sTmp.ToUpperAscii().Equals("ALL") )
2129             SetLanguages( pMergeDataFile->GetLanguages() );
2130         else if( !isInitialized )InitLanguages();
2131 
2132     }
2133     switch ( nMode ) {
2134         case MERGE_MODE_NORMAL : {
2135             PFormEntrys *pEntry = pMergeDataFile->GetPFormEntrys( pResData );
2136 
2137             bool bWriteNoSlash = false;
2138             if ( pEntry && pResData->bText ) {
2139 
2140                 sal_Bool bAddSemikolon = sal_False;
2141                 sal_Bool bFirst = sal_True;
2142                 ByteString sCur;
2143                 ByteString sTmp = Export::sLanguages;
2144 
2145                 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
2146                     sCur = aLanguages[ n ];
2147 
2148                     ByteString sText;
2149                     sal_Bool bText = pEntry->GetTransex3Text( sText, STRING_TYP_TEXT, sCur , sal_True );
2150                     if ( bText && sText.Len() && sText != "-" ) {
2151                         ByteString sOutput;
2152                         if ( bNextMustBeDefineEOL)  {
2153                             if ( bFirst )
2154                                 sOutput += "\t\\\n";
2155                             else
2156                                 sOutput += ";\t\\\n";
2157                         }
2158                         bFirst=sal_False;
2159                         sOutput += "\t";
2160                         sOutput += pResData->sTextTyp;
2161                         //if ( !sCur.EqualsIgnoreCaseAscii("en-US")) {
2162                         if ( ! Export::isSourceLanguage( sCur ) ) {
2163                             sOutput += "[ ";
2164                             sOutput += sCur;
2165                             sOutput += " ] ";
2166                         }
2167                         sOutput += "= ";
2168                         ConvertMergeContent( sText );
2169                         sOutput += sText;
2170 
2171                         if ( bDefine && bWriteNoSlash )
2172                             sOutput += ";\n";
2173 
2174                         if ( bDefine )
2175                             sOutput += ";\\\n";
2176                         else if ( !bNextMustBeDefineEOL )
2177                             sOutput += ";\n";
2178                         else
2179                             bAddSemikolon = sal_True;
2180                         for ( sal_uInt16 j = 1; j < nLevel; j++ )
2181                             sOutput += "\t";
2182                         WriteToMerged( sOutput , true );
2183                     }
2184                 }
2185 
2186 
2187                 if ( bAddSemikolon ) {
2188                     ByteString sOutput( ";" );
2189                     WriteToMerged( sOutput , false );
2190                 }
2191             }
2192 
2193             if ( pEntry && pResData->bQuickHelpText ) {
2194                 sal_Bool bAddSemikolon = sal_False;
2195                 sal_Bool bFirst = sal_True;
2196                 ByteString sCur;
2197 
2198                 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
2199                     sCur = aLanguages[ n ];
2200 
2201                     ByteString sText;
2202                     sal_Bool bText = pEntry->GetTransex3Text( sText, STRING_TYP_QUICKHELPTEXT, sCur, sal_True );
2203                     if ( bText && sText.Len() && sText != "-" ) {
2204                         ByteString sOutput;
2205                         if ( bNextMustBeDefineEOL)  {
2206                             if ( bFirst )
2207                                 sOutput += "\t\\\n";
2208                             else
2209                                 sOutput += ";\t\\\n";
2210                         }
2211                         bFirst=sal_False;
2212                         sOutput += "\t";
2213                         sOutput += "QuickHelpText";
2214                         //if ( !sCur.EqualsIgnoreCaseAscii("en-US") ) {
2215                         if ( ! Export::isSourceLanguage( sCur ) ) {
2216                             sOutput += "[ ";
2217                             sOutput += sCur;
2218                             sOutput += " ] ";
2219                         }
2220                         sOutput += "= ";
2221                         ConvertMergeContent( sText );
2222                         sOutput += sText;
2223                         if ( bDefine )
2224                             sOutput += ";\\\n";
2225                         else if ( !bNextMustBeDefineEOL )
2226                             sOutput += ";\n";
2227                         else
2228                             bAddSemikolon = sal_True;
2229                         for ( sal_uInt16 j = 1; j < nLevel; j++ )
2230                             sOutput += "\t";
2231                         WriteToMerged( sOutput ,true );
2232                     }
2233                 }
2234                 if ( bAddSemikolon ) {
2235                     ByteString sOutput( ";" );
2236                     WriteToMerged( sOutput , false );
2237                 }
2238             }
2239 
2240             if ( pEntry && pResData->bTitle ) {
2241                 sal_Bool bAddSemikolon = sal_False;
2242                 sal_Bool bFirst = sal_True;
2243                 ByteString sCur;
2244 
2245                 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
2246                     sCur = aLanguages[ n ];
2247 
2248                 ByteString sText;
2249                     sal_Bool bText = pEntry->GetTransex3Text( sText, STRING_TYP_TITLE, sCur, sal_True );
2250                     if ( bText && sText.Len() && sText != "-" ) {
2251                         ByteString sOutput;
2252                         if ( bNextMustBeDefineEOL)  {
2253                             if ( bFirst )
2254                                 sOutput += "\t\\\n";
2255                             else
2256                                 sOutput += ";\t\\\n";
2257                         }
2258                         bFirst=sal_False;
2259                         sOutput += "\t";
2260                         sOutput += "Title";
2261                         //if ( !sCur.EqualsIgnoreCaseAscii("en-US") ) {
2262                         if ( ! Export::isSourceLanguage( sCur ) ) {
2263                             sOutput += "[ ";
2264                             sOutput += sCur;
2265                             sOutput += " ] ";
2266                         }
2267                         sOutput += "= ";
2268                         ConvertMergeContent( sText );
2269                         sOutput += sText;
2270                         if ( bDefine )
2271                             sOutput += ";\\\n";
2272                         else if ( !bNextMustBeDefineEOL )
2273                             sOutput += ";\n";
2274                         else
2275                             bAddSemikolon = sal_True;
2276                         for ( sal_uInt16 j = 1; j < nLevel; j++ )
2277                             sOutput += "\t";
2278                         WriteToMerged( sOutput ,true );
2279                     }
2280                 }
2281                 if ( bAddSemikolon ) {
2282                     ByteString sOutput( ";" );
2283                     WriteToMerged( sOutput ,false);
2284                 }
2285             }
2286             // Merge Lists
2287 
2288             if ( pResData->bList ) {
2289                 //printf("Dumping ResData\n");
2290                 //pResData->Dump();
2291 
2292                 bool bPairedList = false;
2293                 ByteString sOldId = pResData->sId;
2294                 ByteString sOldGId = pResData->sGId;
2295                 ByteString sOldTyp = pResData->sResTyp;
2296                 if ( pResData->sGId.Len())
2297                     pResData->sGId += ".";
2298                 pResData->sGId += sOldId;
2299                 ByteString sSpace;
2300                 for ( sal_uInt16 i = 1; i < nLevel-1; i++ )
2301                     sSpace += "\t";
2302                 for ( sal_uInt16 nT = LIST_STRING; nT <= LIST_UIENTRIES; nT++ ) {
2303                     ExportList *pList = NULL;
2304                     switch ( nT ) {
2305                         case LIST_STRING : pResData->sResTyp = "stringlist"; pList = pResData->pStringList; bPairedList = false; break;
2306                         case LIST_FILTER : pResData->sResTyp = "filterlist"; pList = pResData->pFilterList; bPairedList = false; break;
2307                         case LIST_UIENTRIES : pResData->sResTyp = "uientries"; pList = pResData->pUIEntries;bPairedList = false; break;
2308                         case LIST_ITEM : pResData->sResTyp = "itemlist"; pList = pResData->pItemList;       bPairedList = false; break;
2309                         case LIST_PAIRED : pResData->sResTyp = "pairedlist"; pList = pResData->pPairedList; bPairedList = true;  break;
2310                     }
2311                     ByteString sCur;
2312                     for( unsigned int n = 0; n < aLanguages.size(); n++ ){
2313                         sCur = aLanguages[ n ];
2314                         sal_uInt16 nIdx = 1;
2315 
2316                         // Set matching pairedlist identifier
2317                         if( bPairedList && pResData->pPairedList && ( nIdx == 1 ) ){
2318                             ExportListEntry* pListE = ( ExportListEntry* ) pResData->pPairedList->GetObject( nIdx-1 );
2319                             pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] );
2320                         }
2321                         else
2322                             pResData->sId = ByteString("1");
2323 
2324                         PFormEntrys *pEntrys;
2325                         sal_uLong nLIndex = 0;
2326                         sal_uLong nMaxIndex = 0;
2327                         if ( pList )
2328                             nMaxIndex = pList->GetSourceLanguageListEntryCount();
2329                         pEntrys = pMergeDataFile->GetPFormEntrys( pResData );
2330                         while( pEntrys  && ( nLIndex < nMaxIndex )) {
2331                             //printf("Lang %s, List Index %d\n",sCur.GetBuffer(),(int)nLIndex);
2332                             ByteString sText;
2333                             sal_Bool bText;
2334                             bText = pEntrys->GetTransex3Text( sText, STRING_TYP_TEXT, sCur, sal_True );
2335                             if( !bText )
2336                                 bText = pEntrys->GetTransex3Text( sText , STRING_TYP_TEXT, SOURCE_LANGUAGE , sal_False );
2337 
2338                             // Use fallback, if data is missing in sdf file
2339                             //if( !bText && pResData->sResTyp.Equals( "pairedlist" ) ){
2340                             if( !bText && bPairedList ){
2341                                 if( pResData->isMerged( sCur ) ) break;
2342                                 const ByteString sPlist("pairedlist");
2343                                 ByteString sKey = MergeDataFile::CreateKey( sPlist , pResData->sGId , pResData->sId , sFilename );
2344                                 bText = pResData->getFallbackData( sKey , sText );
2345                             }else if ( !bText ){// new fallback
2346                                 if( pResData->isMerged( sCur ) ) break;
2347                                 const ByteString sPlist("list");
2348                                 ByteString sKey = MergeDataFile::CreateKey( sPlist , pResData->sGId , pResData->sId , sFilename );
2349                                 bText = pResData->getFallbackData( sKey , sText );
2350                             } // new fallback
2351 
2352                             if ( bText && sText.Len()) {
2353                                 //if( pEntrys ) pEntrys->Dump();
2354                                 if ( nIdx == 1 ) {
2355                                     ByteString sHead;
2356                                     if ( bNextMustBeDefineEOL )
2357                                         sHead = "\\\n\t";
2358                                     sHead += sSpace;
2359                                     switch ( nT ) {
2360                                         case LIST_STRING : sHead += "StringList "; break;
2361                                         case LIST_FILTER : sHead += "FilterList "; break;
2362                                         case LIST_ITEM : sHead += "ItemList "; break;
2363                                         case LIST_PAIRED : sHead += "PairedList "; break;
2364                                         case LIST_UIENTRIES : sHead += "UIEntries "; break;
2365                                     }
2366                                     sHead += "[ ";
2367                                     sHead += sCur;
2368                                     sHead += " ] ";
2369                                     //}
2370                                     if ( bDefine || bNextMustBeDefineEOL ) {
2371                                         sHead += "= \\\n";
2372                                         sHead += sSpace;
2373                                         sHead += "\t{\\\n\t";
2374                                     }
2375                                     else {
2376                                         sHead += "= \n";
2377                                         sHead += sSpace;
2378                                         sHead += "\t{\n\t";
2379                                     }
2380                                     WriteToMerged( sHead , true);
2381                                 }
2382                                 ByteString sLine;
2383                                 if ( pList && pList->GetObject( nLIndex ))
2384                                     sLine = ( *pList->GetObject( nLIndex ))[ SOURCE_LANGUAGE ];
2385                                 if ( !sLine.Len())
2386                                     sLine = sLastListLine;
2387 
2388                                 if ( sLastListLine.Search( "<" ) != STRING_NOTFOUND ) {
2389                                     if (( nT != LIST_UIENTRIES ) &&
2390                                         (( sLine.Search( "{" ) == STRING_NOTFOUND ) ||
2391                                         ( sLine.Search( "{" ) >= sLine.Search( "\"" ))) &&
2392                                         (( sLine.Search( "<" ) == STRING_NOTFOUND ) ||
2393                                         ( sLine.Search( "<" ) >= sLine.Search( "\"" ))))
2394                                     {
2395                                         sLine.SearchAndReplace( "\"", "< \"" );
2396                                     }
2397                                 }
2398 
2399                                 sal_uInt16 nStart, nEnd;
2400                                 nStart = sLine.Search( "\"" );
2401 
2402                                 ByteString sPostFix;
2403                                 if( !bPairedList ){
2404                                     nEnd = sLine.SearchBackward( '\"' );
2405                                     sPostFix = ByteString( sLine.Copy( ++nEnd ));
2406                                     sLine.Erase( nStart );
2407                                 }
2408 
2409 
2410                                 ConvertMergeContent( sText );
2411 
2412                                 // merge new res. in text line
2413                                 if( bPairedList ){
2414                                     sLine = MergePairedList( sLine , sText );
2415                                 }
2416                                 else{
2417                                     sLine += sText;
2418                                     sLine += sPostFix;
2419                                 }
2420 
2421                                 ByteString sText1( "\t" );
2422                                 sText1 += sLine;
2423                                 if ( bDefine || bNextMustBeDefineEOL )
2424                                     sText1 += " ;\\\n";
2425                                 else
2426                                     sText1 += " ;\n";
2427                                 sText1 += sSpace;
2428                                 sText1 += "\t";
2429                                 //printf("Writing '%s'\n",sText1.GetBuffer());
2430                                 WriteToMerged( sText1 ,true );
2431 
2432                                 // Set matching pairedlist identifier
2433                                 if ( bPairedList ){
2434                                     nIdx++;
2435                                     ExportListEntry* pListE = ( ExportListEntry* ) pResData->pPairedList->GetObject( ( nIdx ) -1 );
2436                                     if( pListE ){
2437                                         pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] );
2438                                     }
2439                                 }
2440                                 else
2441                                     pResData->sId = ByteString::CreateFromInt32( ++nIdx );
2442                             }
2443                             else
2444                                 break;
2445                             nLIndex ++;
2446                             PFormEntrys *oldEntry = pEntrys;
2447                             pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); // <--- game over
2448                             if( !pEntrys )
2449                                 pEntrys = oldEntry;
2450                         }
2451                         if ( nIdx > 1 ) {
2452                             ByteString sFooter( sSpace.Copy( 1 ));
2453                             if ( bNextMustBeDefineEOL )
2454                                 sFooter += "};";
2455                             else if ( !bDefine )
2456                                 sFooter += "};\n\t";
2457                             else
2458                                 sFooter += "\n\n";
2459                             WriteToMerged( sFooter ,true );
2460                         }
2461                     }
2462                 }
2463 
2464                 pResData->sId = sOldId;
2465                 pResData->sGId = sOldGId;
2466                 pResData->sResTyp = sOldTyp;
2467             }
2468         }
2469         break;
2470         case MERGE_MODE_LIST : {
2471             ExportList *pList = NULL;
2472             switch ( nList ) {
2473                 // PairedList
2474                 case LIST_STRING : pList = pResData->pStringList; break;
2475                 case LIST_FILTER : pList = pResData->pFilterList; break;
2476                 case LIST_UIENTRIES : pList = pResData->pUIEntries; break;
2477                 case LIST_ITEM : pList = pResData->pItemList; break;
2478                 case LIST_PAIRED : pList = pResData->pPairedList; break;
2479 
2480             }
2481 
2482             nListIndex++;
2483             sal_uLong nMaxIndex = 0;
2484             if ( pList )
2485                 nMaxIndex = pList->GetSourceLanguageListEntryCount();
2486             ByteString sLine;
2487             if ( pList && pList->GetObject( nListIndex ))
2488                 sLine = ( *pList->GetObject( nListIndex ))[ SOURCE_LANGUAGE ];
2489             if ( !sLine.Len())
2490                 sLine = sLastListLine;
2491 
2492             if ( sLastListLine.Search( "<" ) != STRING_NOTFOUND ) {
2493                 if (( nList != LIST_UIENTRIES ) &&
2494                     (( sLine.Search( "{" ) == STRING_NOTFOUND ) ||
2495                     ( sLine.Search( "{" ) >= sLine.Search( "\"" ))) &&
2496                     (( sLine.Search( "<" ) == STRING_NOTFOUND ) ||
2497                     ( sLine.Search( "<" ) >= sLine.Search( "\"" ))))
2498                 {
2499                     sLine.SearchAndReplace( "\"", "< \"" );
2500                 }
2501             }
2502 
2503             while( PrepareTextToMerge( sLine, nList, nListLang, pResData ) && ( nListIndex <= nMaxIndex )) {
2504                 ByteString sText( "\t" );
2505                 sText += sLine;
2506                 sText += " ;";
2507                 sText += "\n";
2508                 for ( sal_uInt16 i = 0; i < nLevel; i++ )
2509                     sText += "\t";
2510                 WriteToMerged( sText ,false );
2511                 nListIndex++;
2512                 if ( pList && pList->GetObject( nListIndex ))
2513                     sLine = ( *pList->GetObject( nListIndex ))[ SOURCE_LANGUAGE ];
2514                 if ( !sLine.Len())
2515                     sLine = sLastListLine;
2516                 sLine += " ;";
2517             }
2518         }
2519         break;
2520     }
2521     pParseQueue->bMflag = false;
2522 }
2523 
2524 ByteString Export::MergePairedList( ByteString& sLine , ByteString& sText ){
2525 // < "xy" ; IDENTIFIER ; >
2526     ByteString sPre  = sLine.Copy( 0 , sLine.Search('\"') );
2527     ByteString sPost = sLine.Copy( sLine.SearchBackward('\"') + 1 , sLine.Len() );
2528     sPre.Append( sText );
2529     sPre.Append( sPost );
2530     return sPre;
2531 }
2532 
2533 /*****************************************************************************/
2534 void Export::SetChildWithText()
2535 /*****************************************************************************/
2536 {
2537     if ( aResStack.Count() > 1 ) {
2538         for ( sal_uLong i = 0; i < aResStack.Count() - 1; i++ ) {
2539             aResStack.GetObject( i )->bChildWithText = sal_True;
2540         }
2541     }
2542 }
2543 
2544 void ParserQueue::Push( const QueueEntry& aEntry ){
2545 //    printf("nTyp = %d ",aEntry.nTyp);
2546     sal_uInt16 nLen = aEntry.sLine.Len();
2547 
2548     if( !bStart ){
2549         aQueueCur->push( aEntry );
2550         if( nLen > 1 && aEntry.sLine.GetChar( nLen-1 ) == '\n' )
2551             bStart = true;
2552         else if ( aEntry.nTyp != IGNOREDTOKENS ){
2553             if( nLen > 1 && ( aEntry.sLine.GetChar( nLen-1 ) == '\\') ){
2554                 // Next is Macro
2555                 bCurrentIsM = true;
2556              }else{
2557                 // Next is no Macro
2558                 bCurrentIsM = false;
2559              }
2560         }
2561     }
2562     else{
2563         aQueueNext->push( aEntry );
2564         if( nLen > 1 && aEntry.sLine.GetChar( nLen-1 ) != '\n' ){
2565             if( nLen > 1 && ( aEntry.sLine.GetChar( nLen-1  ) == '\\') ){
2566                 // Next is Macro
2567                 bNextIsM = true;
2568             }
2569             else{
2570                 // Next is no Macro
2571                 bNextIsM = false;
2572             }
2573         }else if( nLen > 2 && aEntry.sLine.GetChar( nLen-1 ) == '\n' ){
2574             if( aEntry.nTyp != IGNOREDTOKENS ){
2575                 if( nLen > 2 && ( aEntry.sLine.GetChar( nLen-2  ) == '\\') ){
2576                     // Next is Macro
2577                     bNextIsM = true;
2578                 }
2579                 else{
2580                     // Next is no Macro
2581                     bNextIsM = false;
2582                 }
2583             }
2584             // Pop current
2585             Pop( *aQueueCur );
2586             bLastWasM = bCurrentIsM;
2587             // next -> current
2588             bCurrentIsM = bNextIsM;
2589             aQref = aQueueCur;
2590             aQueueCur = aQueueNext;
2591             aQueueNext = aQref;
2592 
2593         }
2594 
2595         else{
2596             // Pop current
2597             Pop( *aQueueCur );
2598             bLastWasM = bCurrentIsM;
2599             // next -> current
2600             bCurrentIsM = bNextIsM;
2601             aQref = aQueueCur;
2602             aQueueCur = aQueueNext;
2603             aQueueNext = aQref;
2604         }
2605     }
2606 }
2607 
2608 void ParserQueue::Close(){
2609     // Pop current
2610     Pop( *aQueueCur );
2611     // next -> current
2612     bLastWasM = bCurrentIsM;
2613     bCurrentIsM = bNextIsM;
2614     aQref = aQueueCur;
2615     aQueueCur = aQueueNext;
2616     aQueueNext = aQref;
2617     bNextIsM = false;
2618     Pop( *aQueueNext );
2619 };
2620 void ParserQueue::Pop( std::queue<QueueEntry>& aQueue ){
2621     while( !aQueue.empty() ){
2622         QueueEntry aEntry = aQueue.front();
2623         aQueue.pop();
2624         aExport.Execute( aEntry.nTyp , (char*) aEntry.sLine.GetBuffer() );
2625     }
2626 }
2627 ParserQueue::ParserQueue( Export& aExportObj )
2628         :
2629           bCurrentIsM( false ),
2630           bNextIsM( false ) ,
2631           bLastWasM( false ),
2632           bMflag( false ) ,
2633           aExport( aExportObj ) ,
2634           bStart( false ) ,
2635           bStartNext( false )
2636 {
2637           aQueueNext = new std::queue<QueueEntry>;
2638           aQueueCur  = new std::queue<QueueEntry>;
2639 }
2640 
2641 
2642 ParserQueue::~ParserQueue(){
2643     if( aQueueNext )    delete aQueueNext;
2644     if( aQueueCur )     delete aQueueCur;
2645 }
2646