merge the formfield patch from ooo-build
[ooovba.git] / transex3 / source / xrmmerge.cxx
blob1c257c0b53519306954e8a984cb55497318f3c6f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xrmmerge.cxx,v $
10 * $Revision: 1.20 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_transex3.hxx"
33 #include <stdio.h>
34 #include <tools/string.hxx>
35 #include <tools/fsys.hxx>
37 // local includes
38 #include "export.hxx"
39 #include "xrmmerge.hxx"
40 #include "utf8conv.hxx"
41 #include "tokens.h"
42 #include <iostream>
43 #include <vector>
45 using namespace std;
47 extern "C" { int yyerror( char * ); }
48 extern "C" { int YYWarning( char * ); }
50 // defines to parse command line
51 #define STATE_NON 0x0001
52 #define STATE_INPUT 0x0002
53 #define STATE_OUTPUT 0x0003
54 #define STATE_PRJ 0x0004
55 #define STATE_ROOT 0x0005
56 #define STATE_MERGESRC 0x0006
57 #define STATE_ERRORLOG 0x0007
58 #define STATE_UTF8 0x000B
59 #define STATE_LANGUAGES 0x000C
60 #define STATE_ISOCODE99 0x000D
62 // set of global variables
63 BOOL bEnableExport;
64 BOOL bMergeMode;
65 BOOL bErrorLog;
66 BOOL bUTF8;
67 bool bQuiet;
68 ByteString sPrj;
69 ByteString sPrjRoot;
70 ByteString sInputFileName;
71 ByteString sActFileName;
72 ByteString sOutputFile;
73 ByteString sMergeSrc;
74 String sUsedTempFile;
75 XRMResParser *pParser = NULL;
77 extern "C" {
78 // the whole interface to lexer is in this extern "C" section
80 /*****************************************************************************/
81 extern char *GetOutputFile( int argc, char* argv[])
82 /*****************************************************************************/
84 bEnableExport = FALSE;
85 bMergeMode = FALSE;
86 bErrorLog = TRUE;
87 bUTF8 = TRUE;
88 sPrj = "";
89 sPrjRoot = "";
90 sInputFileName = "";
91 sActFileName = "";
92 Export::sLanguages = "";
93 bQuiet = false;
94 USHORT nState = STATE_NON;
95 BOOL bInput = FALSE;
97 // parse command line
98 for( int i = 1; i < argc; i++ ) {
99 if ( ByteString( argv[ i ] ).ToUpperAscii() == "-I" ) {
100 nState = STATE_INPUT; // next token specifies source file
102 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-O" ) {
103 nState = STATE_OUTPUT; // next token specifies the dest file
105 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-P" ) {
106 nState = STATE_PRJ; // next token specifies the cur. project
108 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-R" ) {
109 nState = STATE_ROOT; // next token specifies path to project root
111 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-M" ) {
112 nState = STATE_MERGESRC; // next token specifies the merge database
114 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-QQ" ) {
115 bQuiet = true;
117 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-E" ) {
118 nState = STATE_ERRORLOG;
119 bErrorLog = FALSE;
121 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-UTF8" ) {
122 nState = STATE_UTF8;
123 bUTF8 = TRUE;
125 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-NOUTF8" ) {
126 nState = STATE_UTF8;
127 bUTF8 = FALSE;
129 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-L" ) {
130 nState = STATE_LANGUAGES;
132 else if ( ByteString( argv[ i ] ).ToUpperAscii() == "-ISO99" ) {
133 nState = STATE_ISOCODE99;
135 else {
136 switch ( nState ) {
137 case STATE_NON: {
138 return NULL; // no valid command line
140 case STATE_INPUT: {
141 sInputFileName = argv[ i ];
142 bInput = TRUE; // source file found
144 break;
145 case STATE_OUTPUT: {
146 sOutputFile = argv[ i ]; // the dest. file
148 break;
149 case STATE_PRJ: {
150 sPrj = ByteString( argv[ i ]);
152 break;
153 case STATE_ROOT: {
154 sPrjRoot = ByteString( argv[ i ]); // path to project root
156 break;
157 case STATE_MERGESRC: {
158 sMergeSrc = ByteString( argv[ i ]);
159 bMergeMode = TRUE; // activate merge mode, cause merge database found
161 break;
162 case STATE_LANGUAGES: {
163 Export::sLanguages = ByteString( argv[ i ]);
165 break;
166 case STATE_ISOCODE99: {
167 Export::sIsoCode99 = ByteString( argv[ i ]);
169 break;
174 if ( bInput ) {
175 // command line is valid
176 bEnableExport = TRUE;
177 char *pReturn = new char[ sOutputFile.Len() + 1 ];
178 strcpy( pReturn, sOutputFile.GetBuffer()); // #100211# - checked
179 return pReturn;
182 // command line is not valid
183 return NULL;
185 void removeTempFile(){
186 if( !sUsedTempFile.EqualsIgnoreCaseAscii( "" ) ){
187 DirEntry aTempFile( sUsedTempFile );
188 aTempFile.Kill();
191 /*****************************************************************************/
192 int InitXrmExport( char *pOutput , char* pFilename)
193 /*****************************************************************************/
195 // instanciate Export
196 ByteString sOutput( pOutput );
197 ByteString sFilename( pFilename );
198 Export::InitLanguages( false );
200 if ( bMergeMode )
201 pParser = new XRMResMerge( sMergeSrc, sOutputFile, sFilename );
202 else if ( sOutputFile.Len()) {
203 pParser = new XRMResExport( sOutputFile, sPrj, sActFileName );
206 return 1;
209 int isQuiet(){
210 if( bQuiet ) return 1;
211 else return 0;
213 /*****************************************************************************/
214 int EndXrmExport()
215 /*****************************************************************************/
217 delete pParser;
218 return 1;
220 extern const char* getFilename()
222 return sInputFileName.GetBuffer();
224 /*****************************************************************************/
225 extern FILE *GetXrmFile()
226 /*****************************************************************************/
228 FILE *pFile = 0;
229 // look for valid filename
230 if ( sInputFileName.Len()) {
231 if( Export::fileHasUTF8ByteOrderMarker( sInputFileName ) ){
232 DirEntry aTempFile = Export::GetTempFile();
233 DirEntry aSourceFile( String( sInputFileName , RTL_TEXTENCODING_ASCII_US ) );
234 aSourceFile.CopyTo( aTempFile , FSYS_ACTION_COPYFILE );
235 String sTempFile = aTempFile.GetFull();
236 Export::RemoveUTF8ByteOrderMarkerFromFile( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ) );
237 pFile = fopen( ByteString( sTempFile , RTL_TEXTENCODING_ASCII_US ).GetBuffer(), "r" );
238 sUsedTempFile = sTempFile;
239 }else{
240 // able to open file?
241 pFile = fopen( sInputFileName.GetBuffer(), "r" );
242 sUsedTempFile = String::CreateFromAscii("");
244 if ( !pFile ){
245 fprintf( stderr, "Error: Could not open file %s\n",
246 sInputFileName.GetBuffer());
248 else {
249 // this is a valid file which can be opened, so
250 // create path to project root
251 DirEntry aEntry( String( sInputFileName, RTL_TEXTENCODING_ASCII_US ));
252 aEntry.ToAbs();
253 ByteString sFullEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
254 aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US ));
255 aEntry += DirEntry( sPrjRoot );
256 ByteString sPrjEntry( aEntry.GetFull(), RTL_TEXTENCODING_ASCII_US );
258 // create file name, beginnig with project root
259 // (e.g.: source\ui\src\menue.src)
260 sActFileName = sFullEntry.Copy( sPrjEntry.Len() + 1 );
262 if( !bQuiet )
263 fprintf( stdout, "\nProcessing File %s ...\n", sInputFileName.GetBuffer());
265 sActFileName.SearchAndReplaceAll( "/", "\\" );
267 return pFile;
270 // this means the file could not be opened
271 return NULL;
274 /*****************************************************************************/
275 int WorkOnTokenSet( int nTyp, char *pTokenText )
276 /*****************************************************************************/
278 // printf("Typ = %d , text = '%s'\n",nTyp , pTokenText );
279 pParser->Execute( nTyp, pTokenText );
281 return 1;
284 /*****************************************************************************/
285 int SetError()
286 /*****************************************************************************/
288 pParser->SetError();
289 return 1;
293 extern "C" {
294 /*****************************************************************************/
295 int GetError()
296 /*****************************************************************************/
298 return pParser->GetError();
303 // class XRMResParser
307 /*****************************************************************************/
308 XRMResParser::XRMResParser()
309 /*****************************************************************************/
310 : bError( FALSE ),
311 bText( FALSE )
313 aLanguages = Export::GetLanguages();
316 /*****************************************************************************/
317 XRMResParser::~XRMResParser()
318 /*****************************************************************************/
322 /*****************************************************************************/
323 int XRMResParser::Execute( int nToken, char * pToken )
324 /*****************************************************************************/
326 ByteString rToken( pToken );
328 switch ( nToken ) {
329 case XRM_README_START:
330 sLID = "";
331 sGID = GetAttribute( rToken, "name" );
332 break;
334 case XRM_README_END:
335 sGID = "";
336 break;
338 case XRM_SECTION_START:
339 sLID = "";
340 sGID += ".";
341 sGID += GetAttribute( rToken, "id" );
342 //sLocalized = "1";
344 //sLocalized = "X:";
345 sLocalized = true;
346 break;
348 case XRM_SECTION_END:
349 sGID = sGID.GetToken( 0, '.' );
350 break;
352 case XRM_PARAGRAPH_START:
353 sLID = "";
354 sGID += ".";
355 sGID += GetAttribute( rToken, "id" );
356 if ( GetAttribute( rToken, "localized" ) == "false" )
357 // sLocalized += "0";
358 sLocalized = false;
359 else
360 // sLocalized += "1";
361 sLocalized = true;
362 break;
364 case XRM_PARAGRAPH_END: {
365 if ( sLID.Len())
366 EndOfText( sCurrentOpenTag, sCurrentCloseTag );
367 ByteString sTmp = sGID;
368 sGID = "";
369 for ( USHORT i = 0; i + 1 < sTmp.GetTokenCount( '.' ); i++ ) {
370 if ( sGID.Len())
371 sGID += ".";
372 sGID += sTmp.GetToken( i, '.' );
374 //sLocalized = sLocalized.Copy( 0, sLocalized.Len() - 1 );
376 break;
378 case XRM_TEXT_START:
379 // if ( sLocalized.GetChar( sLocalized.Len() - 1 ) == '1' ) {
380 if ( sLocalized ) {
382 ByteString sNewLID = GetAttribute( rToken, "id" );
383 if ( sNewLID != sLID ) {
384 EndOfText( sCurrentOpenTag, sCurrentCloseTag );
385 sLID = sNewLID;
387 bText = TRUE;
388 sCurrentText = "";
389 sCurrentOpenTag = rToken;
390 Output( rToken );
392 break;
394 case XRM_TEXT_END: {
395 // if ( sLocalized.GetChar( sLocalized.Len() - 1 ) == '1' ) {
396 if( sLocalized ){
397 sCurrentCloseTag = rToken;
399 ByteString sLang = GetAttribute( sCurrentOpenTag, "xml:lang" );
400 if( sLang.EqualsIgnoreCaseAscii("de") ){
401 ULONG nLen = 0;
402 while ( sCurrentText.Len() != nLen )
404 nLen = sCurrentText.Len();
405 sCurrentText.SearchAndReplaceAll( "\n\t", "\n" );
406 sCurrentText.SearchAndReplaceAll( "\n ", "\n" );
408 sCurrentText.SearchAndReplaceAll( "\n", " " );
409 sCurrentCloseTag = rToken;
411 WorkOnText( sCurrentOpenTag, sCurrentText );
412 Output( sCurrentText );
414 //fprintf( stdout, "%s %s\n", sGID.GetBuffer(), sLID.GetBuffer());
415 //fprintf( stdout, "%s\n\n", sCurrentText.GetBuffer());
417 bText = FALSE;
420 break;
422 case XRM_LIST_START:
423 sLID = "";
424 break;
426 case XRM_LIST_END:
427 if ( sLID.Len())
428 EndOfText( sCurrentOpenTag, sCurrentCloseTag );
429 break;
431 default:
432 if ( bText ) {
433 sCurrentText += rToken;
435 break;
438 if ( !bText )
439 Output( rToken );
441 return 0;
444 /*****************************************************************************/
445 ByteString XRMResParser::GetAttribute( const ByteString &rToken, const ByteString &rAttribute )
446 /*****************************************************************************/
448 ByteString sTmp( rToken );
449 sTmp.SearchAndReplaceAll( "\t", " " );
451 ByteString sSearch( " " );
452 sSearch += rAttribute;
453 sSearch += "=";
454 USHORT nPos = sTmp.Search( sSearch );
456 if ( nPos != STRING_NOTFOUND ) {
457 sTmp = sTmp.Copy( nPos );
458 ByteString sId = sTmp.GetToken( 1, '\"' );
459 return sId;
461 return "";
465 /*****************************************************************************/
466 void XRMResParser::Error( const ByteString &rError )
467 /*****************************************************************************/
469 yyerror(( char * ) rError.GetBuffer());
472 /*****************************************************************************/
473 void XRMResParser::ConvertStringToDBFormat( ByteString &rString )
474 /*****************************************************************************/
476 ByteString sResult;
477 do {
478 sResult = rString;
479 rString.EraseLeadingChars( _LF );
480 // rString.EraseLeadingChars( ' ' );
481 rString.EraseLeadingChars( '\t' );
482 // rString.EraseTrailingChars( ' ' );
483 rString.EraseTrailingChars( '\t' );
484 } while ( sResult != rString );
486 rString.SearchAndReplaceAll( "\t", "\\t" );
489 /*****************************************************************************/
490 void XRMResParser::ConvertStringToXMLFormat( ByteString &rString )
491 /*****************************************************************************/
493 rString.SearchAndReplaceAll( "\\t", "\t" );
499 // class XRMResOutputParser
502 /*****************************************************************************/
503 XRMResOutputParser::XRMResOutputParser ( const ByteString &rOutputFile )
504 /*****************************************************************************/
506 aLanguages = Export::GetLanguages();
507 pOutputStream =
508 new SvFileStream(
509 String( rOutputFile, RTL_TEXTENCODING_ASCII_US ),
510 STREAM_STD_WRITE | STREAM_TRUNC
512 pOutputStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
513 if ( !pOutputStream->IsOpen()) {
514 ByteString sError( "Unable to open output file: " );
515 sError += rOutputFile;
516 Error( sError );
517 delete pOutputStream;
518 pOutputStream = NULL;
522 /*****************************************************************************/
523 XRMResOutputParser::~XRMResOutputParser()
524 /*****************************************************************************/
526 if ( pOutputStream ) {
527 pOutputStream->Close();
528 delete pOutputStream;
533 // class XMLResExport
536 /*****************************************************************************/
537 XRMResExport::XRMResExport(
538 const ByteString &rOutputFile, const ByteString &rProject,
539 const ByteString &rFilePath )
540 /*****************************************************************************/
541 : XRMResOutputParser( rOutputFile ),
542 pResData( NULL ),
543 sPrj( rProject ),
544 sPath( rFilePath )
546 aLanguages = Export::GetLanguages();
549 /*****************************************************************************/
550 XRMResExport::~XRMResExport()
551 /*****************************************************************************/
553 delete pResData;
556 void XRMResExport::Output( const ByteString& rOutput )
558 // Dummy to suppress warnings caused by poor class design
559 (void) rOutput;
562 /*****************************************************************************/
563 void XRMResExport::WorkOnText(
564 const ByteString &rOpenTag,
565 ByteString &rText
567 /*****************************************************************************/
569 ByteString sLang( GetAttribute( rOpenTag, "xml:lang" ));
571 if ( !pResData ) {
572 ByteString sPlatform( "" );
573 pResData = new ResData( sPlatform, GetGID() );
574 pResData->sId = GetLID();
577 pResData->sText[ sLang ] = rText;
578 ConvertStringToDBFormat( pResData->sText[ sLang ] );
581 /*****************************************************************************/
582 void XRMResExport::EndOfText(
583 const ByteString &rOpenTag,
584 const ByteString &rCloseTag
586 /*****************************************************************************/
589 (void) rOpenTag; // FIXME
590 (void) rCloseTag; // FIXME
592 if ( pResData && pOutputStream ) {
594 char cSearch = 0x00;
595 ByteString sSearch( cSearch );
597 // if ( !pResData->sText[ ByteString("en-US") ].Len() )
598 // pResData->sText[ ByteString("en-US") ] = pResData->sText[ ByteString("de") ];
600 Export::FillInFallbacks( pResData );
602 ByteString sTimeStamp( Export::GetTimeStamp());
603 ByteString sCur;
604 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
605 sCur = aLanguages[ n ];
607 ByteString sAct = pResData->sText[ sCur ];
608 Export::UnquotHTML( sAct );
609 sAct.EraseAllChars( 0x0A );
611 ByteString sOutput( sPrj ); sOutput += "\t";
612 sOutput += sPath;
613 sOutput += "\t0\t";
614 sOutput += "readmeitem\t";
615 sOutput += pResData->sGId; sOutput += "\t";
616 sOutput += pResData->sId; sOutput += "\t\t\t0\t";
617 sOutput += sCur;
618 sOutput += "\t";
620 sOutput += sAct; sOutput += "\t\t\t\t";
621 sOutput += sTimeStamp;
623 sOutput.SearchAndReplaceAll( sSearch, "_" );
624 //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( sPrj ) ) )
625 pOutputStream->WriteLine( sOutput );
628 delete pResData;
629 pResData = NULL;
633 // class XRMResMerge
636 /*****************************************************************************/
637 XRMResMerge::XRMResMerge(
638 const ByteString &rMergeSource, const ByteString &rOutputFile,
639 ByteString &rFilename)
640 /*****************************************************************************/
641 : XRMResOutputParser( rOutputFile ),
642 pMergeDataFile( NULL ),
643 sFilename( rFilename ) ,
644 pResData( NULL )
646 if ( rMergeSource.Len())
647 pMergeDataFile = new MergeDataFile(
648 rMergeSource, sInputFileName , bErrorLog, RTL_TEXTENCODING_MS_1252);//, bUTF8 );
649 if( Export::sLanguages.EqualsIgnoreCaseAscii("ALL") ){
650 Export::SetLanguages( pMergeDataFile->GetLanguages() );
651 aLanguages = pMergeDataFile->GetLanguages();
653 else aLanguages = Export::GetLanguages();
656 /*****************************************************************************/
657 XRMResMerge::~XRMResMerge()
658 /*****************************************************************************/
660 delete pMergeDataFile;
661 delete pResData;
664 /*****************************************************************************/
665 void XRMResMerge::WorkOnText(
666 const ByteString &rOpenTag,
667 ByteString &rText
669 /*****************************************************************************/
671 ByteString sLang( GetAttribute( rOpenTag, "xml:lang" ));
673 if ( pMergeDataFile ) {
674 if ( !pResData ) {
675 ByteString sPlatform( "" );
676 pResData = new ResData( sPlatform, GetGID() , sFilename );
677 pResData->sId = GetLID();
678 pResData->sResTyp = "readmeitem";
681 PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData );
682 if ( pEntrys ) {
683 ByteString sContent;
684 if ( Export::isAllowed( sLang ) &&
685 ( pEntrys->GetText(
686 sContent, STRING_TYP_TEXT, sLang )) &&
687 ( sContent != "-" ) && ( sContent.Len()))
690 rText = sContent;
691 ConvertStringToXMLFormat( rText );
692 Export::QuotHTMLXRM( rText );
698 /*****************************************************************************/
699 void XRMResMerge::Output( const ByteString& rOutput )
700 /*****************************************************************************/
702 if ( pOutputStream )
703 pOutputStream->Write( rOutput.GetBuffer(), rOutput.Len());
706 /*****************************************************************************/
707 void XRMResMerge::EndOfText(
708 const ByteString &rOpenTag,
709 const ByteString &rCloseTag
711 /*****************************************************************************/
713 if ( pMergeDataFile && pResData ) {
714 PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData );
715 if ( pEntrys ) {
716 ByteString sCur;
717 for( unsigned int n = 0; n < aLanguages.size(); n++ ){
718 sCur = aLanguages[ n ];
719 ByteString sContent;
720 //<<<<<<< xrmmerge.cxx
721 if ( !sCur.EqualsIgnoreCaseAscii("en-US") &&
722 // ( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && Export::isMergingGermanAllowed( sPrj ) )) &&
723 //=======
724 // if ( Export::isAllowed( sCur ) &&
725 //>>>>>>> 1.17
726 ( pEntrys->GetText(
727 sContent, STRING_TYP_TEXT, sCur, TRUE )) &&
728 ( sContent != "-" ) && ( sContent.Len()))
730 ByteString sText( sContent );
731 Export::QuotHTMLXRM( sText );
733 ByteString sAdditionalLine( "\t" );
734 sAdditionalLine += rOpenTag;
735 ByteString sSearch = "xml:lang=\"";
736 ByteString sReplace( sSearch );
738 sSearch += GetAttribute( rOpenTag, "xml:lang" );
739 sReplace += sCur;
741 sAdditionalLine.SearchAndReplace( sSearch, sReplace );
743 sAdditionalLine += sText;
744 sAdditionalLine += rCloseTag;
745 sAdditionalLine += "\n";
747 for ( USHORT i = 0; i + 1 < GetGID().GetTokenCount( '.' ); i++ )
748 sAdditionalLine += "\t";
750 Output( sAdditionalLine );
755 delete pResData;
756 pResData = NULL;