xref: /trunk/main/l10ntools/source/cfgmerge.cxx (revision a893be29)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_l10ntools.hxx"
26 #include <stdio.h>
27 #include <tools/string.hxx>
28 #include <tools/fsys.hxx>
29 
30 // local includes
31 #include "export.hxx"
32 #include "cfgmerge.hxx"
33 #include "tokens.h"
34 #include "utf8conv.hxx"
35 
36 extern "C" { int yyerror( char * ); }
37 extern "C" { int YYWarning( char * ); }
38 
39 // defines to parse command line
40 #define STATE_NON  		0x0001
41 #define STATE_INPUT		0x0002
42 #define STATE_OUTPUT	0x0003
43 #define STATE_PRJ		0x0004
44 #define STATE_ROOT		0x0005
45 #define STATE_MERGESRC	0x0006
46 #define STATE_ERRORLOG	0x0007
47 #define STATE_UTF8		0x0008
48 #define STATE_LANGUAGES	0X0009
49 #define STATE_ISOCODE99	0x000A
50 #define STATE_FORCE		0x000B
51 
52 // set of global variables
53 sal_Bool bEnableExport;
54 sal_Bool bMergeMode;
55 sal_Bool bErrorLog;
56 sal_Bool bForce;
57 sal_Bool bUTF8;
58 ByteString sPrj;
59 ByteString sPrjRoot;
60 ByteString sInputFileName;
61 ByteString sActFileName;
62 ByteString sFullEntry;
63 ByteString sOutputFile;
64 ByteString sMergeSrc;
65 String sUsedTempFile;
66 
67 CfgParser *pParser;
68 
69 extern "C" {
70 // the whole interface to lexer is in this extern "C" section
71 
72 /*****************************************************************************/
GetOutputFile(int argc,char * argv[])73 extern char *GetOutputFile( int argc, char* argv[])
74 /*****************************************************************************/
75 {
76 	bEnableExport   = sal_False;
77 	bMergeMode      = sal_False;
78 	bErrorLog       = sal_True;
79 	bForce          = sal_False;
80 	bUTF8           = sal_True;
81     sPrj            = "";
82 	sPrjRoot        = "";
83 	sInputFileName  = "";
84 	sActFileName    = "";
85 
86 	sal_uInt16 nState = STATE_NON;
87 	sal_Bool bInput = sal_False;
88 
89 	// parse command line
90 	for( int i = 1; i < argc; i++ ) {
91         ByteString sSwitch( argv[ i ] );
92         sSwitch.ToUpperAscii();
93 
94         if ( sSwitch == "-I" ) {
95 			nState = STATE_INPUT; // next token specifies source file
96 		}
97 		else if ( sSwitch == "-O" ) {
98 			nState = STATE_OUTPUT; // next token specifies the dest file
99 		}
100 		else if ( sSwitch == "-P" ) {
101 			nState = STATE_PRJ; // next token specifies the cur. project
102 		}
103 		else if ( sSwitch == "-R" ) {
104 			nState = STATE_ROOT; // next token specifies path to project root
105 		}
106 		else if ( sSwitch == "-M" ) {
107 			nState = STATE_MERGESRC; // next token specifies the merge database
108 		}
109 		else if ( sSwitch == "-E" ) {
110 			nState = STATE_ERRORLOG;
111 			bErrorLog = sal_False;
112 		}
113 		else if ( sSwitch == "-UTF8" ) {
114 			nState = STATE_UTF8;
115 			bUTF8 = sal_True;
116 		}
117 		else if ( sSwitch == "-NOUTF8" ) {
118 			nState = STATE_UTF8;
119 			bUTF8 = sal_False;
120 		}
121 		else if ( sSwitch == "-F" ) {
122 			nState = STATE_FORCE;
123 			bForce = sal_True;
124 		}
125         else if ( sSwitch == "-L" ) {
126 			nState = STATE_LANGUAGES;
127 		}
128 		else if ( sSwitch.ToUpperAscii() == "-ISO99" ) {
129 			nState = STATE_ISOCODE99;
130 		}
131 		else {
132 			switch ( nState ) {
133 				case STATE_NON: {
134 					return NULL;	// no valid command line
135 				}
136 				case STATE_INPUT: {
137 					sInputFileName = argv[ i ];
138 					bInput = sal_True; // source file found
139 				}
140 				break;
141 				case STATE_OUTPUT: {
142 					sOutputFile = argv[ i ]; // the dest. file
143 				}
144 				break;
145 				case STATE_PRJ: {
146 					sPrj = ByteString( argv[ i ]);
147 //					sPrj.ToLowerAscii(); // the project
148 				}
149 				break;
150 				case STATE_ROOT: {
151 					sPrjRoot = ByteString( argv[ i ]); // path to project root
152 				}
153 				break;
154 				case STATE_MERGESRC: {
155 					sMergeSrc = ByteString( argv[ i ]);
156 					bMergeMode = sal_True; // activate merge mode, cause merge database found
157 				}
158 				break;
159 				case STATE_LANGUAGES: {
160 					Export::sLanguages = ByteString( argv[ i ]);
161 				}
162 				break;
163 			}
164 		}
165 	}
166 
167 	if ( bInput ) {
168 		// command line is valid
169 		bEnableExport = sal_True;
170 		char *pReturn = new char[ sOutputFile.Len() + 1 ];
171 		strcpy( pReturn, sOutputFile.GetBuffer());  // #100211# - checked
172 		return pReturn;
173 	}
174 
175 	// command line is not valid
176 	return NULL;
177 }
178 /*****************************************************************************/
InitCfgExport(char * pOutput,char * pFilename)179 int InitCfgExport( char *pOutput , char* pFilename )
180 /*****************************************************************************/
181 {
182 	// instanciate Export
183 	ByteString sOutput( pOutput );
184 	ByteString sFilename( pFilename );
185     Export::InitLanguages();
186 
187 	if ( bMergeMode )
188 		pParser = new CfgMerge( sMergeSrc, sOutputFile, sFilename );
189   	else if ( sOutputFile.Len())
190 		pParser = new CfgExport( sOutputFile, sPrj, sActFileName );
191 
192 	return 1;
193 }
194 
195 /*****************************************************************************/
EndCfgExport()196 int EndCfgExport()
197 /*****************************************************************************/
198 {
199 	delete pParser;
200 
201 	return 1;
202 }
203 
removeTempFile()204 void removeTempFile(){
205     if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){
206         DirEntry aTempFile( sUsedTempFile );
207         aTempFile.Kill();
208     }
209 }
getFilename()210 extern const char* getFilename()
211 {
212 	return sInputFileName.GetBuffer();
213 }
214 /*****************************************************************************/
GetCfgFile()215 extern FILE *GetCfgFile()
216 /*****************************************************************************/
217 {
218 	FILE *pFile = 0;
219     // look for valid filename
220 	if ( sInputFileName.Len()) {
221         if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){
222             DirEntry aTempFile = Export::GetTempFile();
223             DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) );
224             aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE );
225             String sTempFile = aTempFile.GetFull();
226             Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) );
227             pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" );
228             sUsedTempFile = sTempFile;
229         }else{
230             // able to open file?
231             pFile = fopen( sInputFileName.GetBuffer(), "r" );
232             sUsedTempFile = String::CreateFromAscii("");
233         }
234 		if ( !pFile ){
235 			fprintf( stderr, "Error: Could not open file %s\n",
236 				sInputFileName.GetBuffer());
237             exit( -13 );
238         }
239 		else {
240 			// this is a valid file which can be opened, so
241 			// create path to project root
242 			DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US ));
243 			aEntry.ToAbs();
244 			sFullEntry= ByteString( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
245 			aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US ));
246 			aEntry += DirEntry( sPrjRoot );
247 			ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
248 
249 			// create file name, beginning with project root
250 			// (e.g.: source\ui\src\menue.src)
251 //			printf("sFullEntry = %s\n",sFullEntry.GetBuffer());
252             sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 );
253 //            printf("sActFileName = %s\n",sActFileName.GetBuffer());
254 
255 			sActFileName.SearchAndReplaceAll( "/", "\\" );
256 
257 			return pFile;
258 		}
259 	}
260 	// this means the file could not be opened
261 	return NULL;
262 }
263 
264 /*****************************************************************************/
WorkOnTokenSet(int nTyp,char * pTokenText)265 int WorkOnTokenSet( int nTyp, char *pTokenText )
266 /*****************************************************************************/
267 {
268 	pParser->Execute( nTyp, pTokenText );
269 
270 	return 1;
271 }
272 
273 
274 /*****************************************************************************/
SetError()275 int SetError()
276 /*****************************************************************************/
277 {
278 	return 1;
279 }
280 
281 /*****************************************************************************/
GetError()282 int GetError()
283 /*****************************************************************************/
284 {
285 	return 0;
286 }
287 }
288 
289 //
290 // class CfgStackData
291 //
292 
Push(const ByteString & rTag,const ByteString & rId)293 CfgStackData* CfgStack::Push( const ByteString &rTag, const ByteString &rId )
294 {
295     CfgStackData *pD = new CfgStackData( rTag, rId );
296     Insert( pD, LIST_APPEND );
297     return pD;
298 }
299 
300 //
301 // class CfgStack
302 //
303 
304 /*****************************************************************************/
~CfgStack()305 CfgStack::~CfgStack()
306 /*****************************************************************************/
307 {
308 	for ( sal_uLong i = 0; i < Count(); i++ )
309 		delete GetObject( i );
310 }
311 
312 /*****************************************************************************/
GetAccessPath(sal_uLong nPos)313 ByteString CfgStack::GetAccessPath( sal_uLong nPos )
314 /*****************************************************************************/
315 {
316 	if ( nPos == LIST_APPEND )
317 		nPos = Count() - 1;
318 
319 	ByteString sReturn;
320 	for ( sal_uLong i = 0; i <= nPos; i++ ) {
321 		if ( i )
322 			sReturn += ".";
323 		sReturn += GetStackData( i )->GetIdentifier();
324 	}
325 
326 	return sReturn;
327 }
328 
329 /*****************************************************************************/
GetStackData(sal_uLong nPos)330 CfgStackData *CfgStack::GetStackData( sal_uLong nPos )
331 /*****************************************************************************/
332 {
333 	if ( nPos == LIST_APPEND )
334 		nPos = Count() - 1;
335 
336 	return GetObject( nPos );
337 }
338 
339 //
340 // class CfgParser
341 //
342 
343 /*****************************************************************************/
CfgParser()344 CfgParser::CfgParser()
345 /*****************************************************************************/
346 				: pStackData( NULL ),
347 				bLocalize( sal_False )
348 {
349 }
350 
351 /*****************************************************************************/
~CfgParser()352 CfgParser::~CfgParser()
353 /*****************************************************************************/
354 {
355 }
356 
357 
358 /*****************************************************************************/
IsTokenClosed(const ByteString & rToken)359 sal_Bool CfgParser::IsTokenClosed( const ByteString &rToken )
360 /*****************************************************************************/
361 {
362 	return rToken.GetChar( rToken.Len() - 2 ) == '/';
363 }
364 
365 /*****************************************************************************/
AddText(ByteString & rText,const ByteString & rIsoLang,const ByteString & rResTyp)366 void CfgParser::AddText(
367 	ByteString &rText,
368 	const ByteString &rIsoLang,
369 	const ByteString &rResTyp
370 )
371 /*****************************************************************************/
372 {
373 		sal_uInt16 nTextLen = 0;
374 		while ( rText.Len() != nTextLen ) {
375 			nTextLen = rText.Len();
376 			rText.SearchAndReplaceAll( "\n", " " );
377 			rText.SearchAndReplaceAll( "\r", " " );
378 			rText.SearchAndReplaceAll( "\t", " " );
379 			rText.SearchAndReplaceAll( "  ", " " );
380 		}
381 		pStackData->sResTyp = rResTyp;
382         WorkOnText( rText, rIsoLang );
383 
384         pStackData->sText[ rIsoLang ] = rText;
385 }
386 
387 
388 /*****************************************************************************/
WorkOnRessourceEnd()389 void CfgParser::WorkOnRessourceEnd()
390 /*****************************************************************************/
391 {
392 }
393 
394 /*****************************************************************************/
ExecuteAnalyzedToken(int nToken,char * pToken)395 int CfgParser::ExecuteAnalyzedToken( int nToken, char *pToken )
396 /*****************************************************************************/
397 {
398 	ByteString sToken( pToken );
399 
400 	if ( sToken == " " || sToken == "\t" )
401 		sLastWhitespace += sToken;
402 
403 	ByteString sTokenName;
404 	ByteString sTokenId;
405 
406 	sal_Bool bOutput = sal_True;
407 
408 	switch ( nToken ) {
409 		case CFG_TOKEN_PACKAGE:
410 		case CFG_TOKEN_COMPONENT:
411 		case CFG_TOKEN_TEMPLATE:
412 		case CFG_TOKEN_CONFIGNAME:
413 		case CFG_TOKEN_OORNAME:
414 		case CFG_TOKEN_OORVALUE:
415 		case CFG_TAG:
416 		case ANYTOKEN:
417 		case CFG_TEXT_START:
418 		{
419 			sTokenName = sToken.GetToken( 1, '<' ).GetToken( 0, '>' ).GetToken( 0, ' ' );
420 
421 	  		if ( !IsTokenClosed( sToken )) {
422 				ByteString sSearch;
423 				switch ( nToken ) {
424 					case CFG_TOKEN_PACKAGE:
425 						sSearch = "package-id=";
426 					break;
427 					case CFG_TOKEN_COMPONENT:
428 						sSearch = "component-id=";
429 					break;
430 					case CFG_TOKEN_TEMPLATE:
431 						sSearch = "template-id=";
432 					break;
433 					case CFG_TOKEN_CONFIGNAME:
434 						sSearch = "cfg:name=";
435 					break;
436 					case CFG_TOKEN_OORNAME:
437 						sSearch = "oor:name=";
438 						bLocalize = sal_True;
439 					break;
440 					case CFG_TOKEN_OORVALUE:
441 						sSearch = "oor:value=";
442 					break;
443 					case CFG_TEXT_START: {
444 						if ( sCurrentResTyp != sTokenName ) {
445 							WorkOnRessourceEnd();
446                             ByteString sCur;
447                             for( unsigned int n = 0; n < aLanguages.size(); n++ ){
448                                 sCur = aLanguages[ n ];
449                                 pStackData->sText[ sCur ] = ByteString("");
450                             }
451                      	}
452 						sCurrentResTyp = sTokenName;
453 
454 						ByteString sTemp = sToken.Copy( sToken.Search( "xml:lang=" ));
455 						sCurrentIsoLang = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' );
456 
457 						if ( sCurrentIsoLang == NO_TRANSLATE_ISO )
458 							bLocalize = sal_False;
459 
460 						pStackData->sTextTag = sToken;
461 
462 						sCurrentText = "";
463 					}
464 					break;
465 				}
466 				if ( sSearch.Len()) {
467 					ByteString sTemp = sToken.Copy( sToken.Search( sSearch ));
468 					sTokenId = sTemp.GetToken( 1, '\"' ).GetToken( 0, '\"' );
469 				}
470 				pStackData = aStack.Push( sTokenName, sTokenId );
471 
472 				if ( sSearch == "cfg:name=" ) {
473 					ByteString sTemp( sToken );
474 					sTemp.ToUpperAscii();
475 					bLocalize = (( sTemp.Search( "CFG:TYPE=\"STRING\"" ) != STRING_NOTFOUND ) &&
476 						( sTemp.Search( "CFG:LOCALIZED=\"sal_True\"" ) != STRING_NOTFOUND ));
477 				}
478 			}
479 			else if ( sTokenName == "label" ) {
480 				if ( sCurrentResTyp != sTokenName ) {
481 					WorkOnRessourceEnd();
482                     ByteString sCur;
483                     for( unsigned int n = 0; n < aLanguages.size(); n++ ){
484                         sCur = aLanguages[ n ];
485                         pStackData->sText[ sCur ] = ByteString("");
486                     }
487         		}
488 				sCurrentResTyp = sTokenName;
489 			}
490 		}
491 		break;
492 		case CFG_CLOSETAG:
493 			sTokenName = sToken.GetToken( 1, '/' ).GetToken( 0, '>' ).GetToken( 0, ' ' );
494 		   	if ( aStack.GetStackData() && ( aStack.GetStackData()->GetTagType() == sTokenName )) {
495 				if ( ! sCurrentText.Len())
496 					WorkOnRessourceEnd();
497 				aStack.Pop();
498 				pStackData = aStack.GetStackData();
499 			}
500 			else {
501 				ByteString sError( "Missplaced close tag: " );
502                 ByteString sInFile(" in file ");
503                 sError += sToken;
504                 sError += sInFile;
505                 sError += sFullEntry;
506 				Error( sError );
507                 exit ( 13 );
508 			}
509 		break;
510 
511 		case CFG_TEXTCHAR:
512 			sCurrentText += sToken;
513 			bOutput = sal_False;
514 		break;
515 
516 		case CFG_TOKEN_NO_TRANSLATE:
517 			bLocalize = sal_False;
518 		break;
519 	}
520 
521 	if ( sCurrentText.Len() && nToken != CFG_TEXTCHAR ) {
522 		AddText( sCurrentText, sCurrentIsoLang, sCurrentResTyp );
523 		Output( sCurrentText );
524 		sCurrentText = "";
525 		pStackData->sEndTextTag = sToken;
526 	}
527 
528 	if ( bOutput )
529 		Output( sToken );
530 
531 	if ( sToken != " " && sToken != "\t" )
532 		sLastWhitespace = "";
533 
534 	return 1;
535 }
536 
537 /*****************************************************************************/
Output(const ByteString & rOutput)538 void CfgExport::Output( const ByteString& rOutput )
539 /*****************************************************************************/
540 {
541     // Dummy operation to suppress warnings caused by poor class design
542     ByteString a( rOutput );
543 }
544 
545 /*****************************************************************************/
Execute(int nToken,char * pToken)546 int CfgParser::Execute( int nToken, char * pToken )
547 /*****************************************************************************/
548 {
549 	ByteString sToken( pToken );
550 
551 	switch ( nToken ) {
552 		case CFG_TAG:
553 			if ( sToken.Search( "package-id=" ) != STRING_NOTFOUND )
554 				return ExecuteAnalyzedToken( CFG_TOKEN_PACKAGE, pToken );
555 			else if ( sToken.Search( "component-id=" ) != STRING_NOTFOUND )
556 				return ExecuteAnalyzedToken( CFG_TOKEN_COMPONENT, pToken );
557 			else if ( sToken.Search( "template-id=" ) != STRING_NOTFOUND )
558 				return ExecuteAnalyzedToken( CFG_TOKEN_TEMPLATE, pToken );
559 			else if ( sToken.Search( "cfg:name=" ) != STRING_NOTFOUND )
560 				return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken );
561 			else if ( sToken.Search( "oor:name=" ) != STRING_NOTFOUND )
562 				return ExecuteAnalyzedToken( CFG_TOKEN_OORNAME, pToken );
563 			else if ( sToken.Search( "oor:value=" ) != STRING_NOTFOUND )
564 				return ExecuteAnalyzedToken( CFG_TOKEN_OORVALUE, pToken );
565 		break;
566 	}
567 	return ExecuteAnalyzedToken( nToken, pToken );
568 }
569 
570 
571 /*****************************************************************************/
Error(const ByteString & rError)572 void CfgParser::Error( const ByteString &rError )
573 /*****************************************************************************/
574 {
575 //	ByteString sError( rError );
576 //    sError.Append("Error: In file ");
577 //    sError.Append( sActFileName );
578     yyerror(( char * ) rError.GetBuffer());
579 }
580 
581 
582 //
583 // class CfgOutputParser
584 //
585 
586 /*****************************************************************************/
CfgOutputParser(const ByteString & rOutputFile)587 CfgOutputParser::CfgOutputParser( const ByteString &rOutputFile )
588 /*****************************************************************************/
589 {
590 	pOutputStream =
591 		new SvFileStream(
592 			String( rOutputFile, RTL_TEXTENCODING_ASCII_US ),
593 			STREAM_STD_WRITE | STREAM_TRUNC
594 		);
595     pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
596 
597 	if ( !pOutputStream->IsOpen()) {
598 		ByteString sError( "ERROR: Unable to open output file: " );
599 		sError += rOutputFile;
600 		Error( sError );
601 		delete pOutputStream;
602 		pOutputStream = NULL;
603         exit( -13 );
604 	}
605 }
606 
607 /*****************************************************************************/
~CfgOutputParser()608 CfgOutputParser::~CfgOutputParser()
609 /*****************************************************************************/
610 {
611 	if ( pOutputStream ) {
612 		pOutputStream->Close();
613 		delete pOutputStream;
614 	}
615 }
616 
617 //
618 // class CfgExport
619 //
620 
621 /*****************************************************************************/
CfgExport(const ByteString & rOutputFile,const ByteString & rProject,const ByteString & rFilePath)622 CfgExport::CfgExport(
623 		const ByteString &rOutputFile,
624 		const ByteString &rProject,
625 		const ByteString &rFilePath
626 )
627 /*****************************************************************************/
628 				: CfgOutputParser( rOutputFile ),
629 				sPrj( rProject ),
630 				sPath( rFilePath )
631 {
632     Export::InitLanguages( false );
633     aLanguages = Export::GetLanguages();
634 }
635 
636 /*****************************************************************************/
~CfgExport()637 CfgExport::~CfgExport()
638 /*****************************************************************************/
639 {
640 }
641 
642 /*****************************************************************************/
WorkOnRessourceEnd()643 void CfgExport::WorkOnRessourceEnd()
644 /*****************************************************************************/
645 {
646 	if ( pOutputStream && bLocalize ) {
647 	if (( pStackData->sText[ ByteString("en-US") ].Len()
648         ) ||
649 			( bForce &&
650 				( pStackData->sText[ ByteString("de") ].Len() ||
651                     pStackData->sText[ ByteString("en-US") ].Len() )))
652 		{
653             ByteString sFallback = pStackData->sText[ ByteString("en-US") ];
654 
655             //if ( pStackData->sText[ ByteString("en-US") ].Len())
656 			//	sFallback = pStackData->sText[ ByteString("en-US") ];
657 
658 			ByteString sLocalId = pStackData->sIdentifier;
659 			ByteString sGroupId;
660 			if ( aStack.Count() == 1 ) {
661 				sGroupId = sLocalId;
662 				sLocalId = "";
663 			}
664 			else {
665 				sGroupId = aStack.GetAccessPath( aStack.Count() - 2 );
666 			}
667 
668 			ByteString sTimeStamp( Export::GetTimeStamp());
669 
670             ByteString sCur;
671             for( unsigned int n = 0; n < aLanguages.size(); n++ ){
672                 sCur = aLanguages[ n ];
673 
674 					ByteString sText = pStackData->sText[ sCur ];
675 					if ( !sText.Len())
676 						sText = sFallback;
677 
678                     Export::UnquotHTML( sText );
679 
680 					ByteString sOutput( sPrj ); sOutput += "\t";
681 					sOutput += sPath;
682 					sOutput += "\t0\t";
683 					sOutput += pStackData->sResTyp; sOutput += "\t";
684 					sOutput += sGroupId; sOutput += "\t";
685 					sOutput += sLocalId; sOutput += "\t\t\t0\t";
686                     sOutput += sCur;
687 					sOutput += "\t";
688 
689                     sOutput += sText; sOutput += "\t\t\t\t";
690 					sOutput += sTimeStamp;
691 
692                     //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) )
693 					pOutputStream->WriteLine( sOutput );
694 			}
695 		}
696 	}
697 }
698 
699 /*****************************************************************************/
WorkOnText(ByteString & rText,const ByteString & rIsoLang)700 void CfgExport::WorkOnText(
701 	ByteString &rText,
702     const ByteString &rIsoLang
703 )
704 /*****************************************************************************/
705 {
706     if( rIsoLang.Len() ) Export::UnquotHTML( rText );
707 }
708 
709 
710 //
711 // class CfgMerge
712 //
713 
714 /*****************************************************************************/
CfgMerge(const ByteString & rMergeSource,const ByteString & rOutputFile,ByteString & rFilename)715 CfgMerge::CfgMerge(
716 	const ByteString &rMergeSource, const ByteString &rOutputFile,
717 	ByteString &rFilename )
718 /*****************************************************************************/
719 				: CfgOutputParser( rOutputFile ),
720 				pMergeDataFile( NULL ),
721 				pResData( NULL ),
722 				bGerman( sal_False ),
723 				sFilename( rFilename ),
724 				bEnglish( sal_False )
725 {
726     if ( rMergeSource.Len()){
727 		pMergeDataFile = new MergeDataFile(
728 		rMergeSource, sInputFileName  , bErrorLog, RTL_TEXTENCODING_MS_1252, true );
729         if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){
730             Export::SetLanguages( pMergeDataFile->GetLanguages() );
731             aLanguages = pMergeDataFile->GetLanguages();
732         }
733         else aLanguages = Export::GetLanguages();
734     }else
735         aLanguages = Export::GetLanguages();
736 }
737 
738 /*****************************************************************************/
~CfgMerge()739 CfgMerge::~CfgMerge()
740 /*****************************************************************************/
741 {
742 	delete pMergeDataFile;
743 	delete pResData;
744 }
745 
746 /*****************************************************************************/
WorkOnText(ByteString & rText,const ByteString & nLangIndex)747 void CfgMerge::WorkOnText(
748 	ByteString &rText,
749     const ByteString& nLangIndex
750 )
751 /*****************************************************************************/
752 {
753 
754     if ( pMergeDataFile && bLocalize ) {
755 		if ( !pResData ) {
756 			ByteString sLocalId = pStackData->sIdentifier;
757 			ByteString sGroupId;
758 			if ( aStack.Count() == 1 ) {
759 				sGroupId = sLocalId;
760 				sLocalId = "";
761 			}
762 			else {
763 				sGroupId = aStack.GetAccessPath( aStack.Count() - 2 );
764 			}
765 
766 			ByteString sPlatform( "" );
767 
768 			pResData = new ResData( sPlatform, sGroupId , sFilename );
769 			pResData->sId = sLocalId;
770 			pResData->sResTyp = pStackData->sResTyp;
771 		}
772 
773         //if ( nLangIndex.EqualsIgnoreCaseAscii("de") )
774 		//	bGerman = sal_True;
775 		if (( nLangIndex.EqualsIgnoreCaseAscii("en-US") ))
776 			bEnglish = sal_True;
777 
778 		PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData );
779 		if ( pEntrys ) {
780 			ByteString sContent;
781             pEntrys->GetText( sContent, STRING_TYP_TEXT, nLangIndex );
782 
783 			if ( Export::isAllowed( nLangIndex ) &&
784 				( sContent != "-" ) && ( sContent.Len()))
785 			{
786 #ifdef MERGE_SOURCE_LANGUAGES
787                     if( nLangIndex.EqualsIgnoreCaseAscii("de") || nLangIndex.EqualsIgnoreCaseAscii("en-US") )
788                         rText = sContent;
789 #endif
790                 Export::QuotHTML( rText );
791 			}
792 		}
793 	}
794 }
795 
796 /*****************************************************************************/
Output(const ByteString & rOutput)797 void CfgMerge::Output( const ByteString& rOutput )
798 /*****************************************************************************/
799 {
800 	if ( pOutputStream )
801 		pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len());
802 }
803 
Push(CfgStackData * pStackData)804 sal_uLong CfgStack::Push( CfgStackData *pStackData )
805 {
806     Insert( pStackData, LIST_APPEND );
807     return Count() - 1;
808 }
809 
810 /*****************************************************************************/
WorkOnRessourceEnd()811 void CfgMerge::WorkOnRessourceEnd()
812 /*****************************************************************************/
813 {
814 
815 	if ( pMergeDataFile && pResData && bLocalize && (( bEnglish ) || bForce )) {
816 		PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrysCaseSensitive( pResData );
817 		if ( pEntrys ) {
818             ByteString sCur;
819 
820             for( unsigned int n = 0; n < aLanguages.size(); n++ ){
821                 sCur = aLanguages[ n ];
822 
823 				ByteString sContent;
824                 pEntrys->GetText( sContent, STRING_TYP_TEXT, sCur , sal_True );
825                 if (
826                     // (!sCur.EqualsIgnoreCaseAscii("de") )    &&
827 					( !sCur.EqualsIgnoreCaseAscii("en-US") ) &&
828 
829 					( sContent != "-" ) && ( sContent.Len()))
830 				{
831 
832 					ByteString sText = sContent;
833                     Export::QuotHTML( sText );
834 
835 					ByteString sAdditionalLine( "\t" );
836 
837 					ByteString sTextTag = pStackData->sTextTag;
838 					ByteString sTemp = sTextTag.Copy( sTextTag.Search( "xml:lang=" ));
839 
840 					ByteString sSearch = sTemp.GetToken( 0, '\"' );
841 					sSearch += "\"";
842 					sSearch += sTemp.GetToken( 1, '\"' );
843 					sSearch += "\"";
844 
845 					ByteString sReplace = sTemp.GetToken( 0, '\"' );
846 					sReplace += "\"";
847                     sReplace += sCur;
848 					sReplace += "\"";
849 
850 					sTextTag.SearchAndReplace( sSearch, sReplace );
851 
852 					sAdditionalLine += sTextTag;
853 					sAdditionalLine += sText;
854 					sAdditionalLine += pStackData->sEndTextTag;
855 
856 					sAdditionalLine += "\n";
857 					sAdditionalLine += sLastWhitespace;
858 
859 					Output( sAdditionalLine );
860 				}
861 			}
862 		}
863 	}
864 	delete pResData;
865 	pResData = NULL;
866 	bGerman = sal_False;
867 	bEnglish = sal_False;
868 }
869