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, beginnig 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