/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "sal/config.h" #include #include #include "boost/scoped_ptr.hpp" #include #include #include "common.hxx" #include "export.hxx" #include "helper.hxx" #include "tokens.h" #include #include void yyerror( const char * ); void YYWarning( const char * ); namespace { rtl::OString sActFileName; //TODO MergeDataFile * pMergeDataFile = 0; //TODO namespace global { bool mergeMode = false; bool errorLog = true; char const * prj = 0; char const * prjRoot = 0; char const * inputPathname = 0; char const * outputPathname = 0; char const * mergeSrc; boost::scoped_ptr< Export > exporter; } void handleArguments(int argc, char ** argv) { for (int i = 1; i != argc; ++i) { if (std::strcmp(argv[i], "-e") == 0) { global::errorLog = false; } else if (std::strcmp(argv[i], "-i") == 0) { if (++i == argc) { global::inputPathname = 0; // no valid command line break; } global::inputPathname = argv[i]; } else if (std::strcmp(argv[i], "-l") == 0) { if (++i == argc) { global::inputPathname = 0; // no valid command line break; } Export::sLanguages = argv[i]; } else if (std::strcmp(argv[i], "-m") == 0) { if (++i == argc) { global::inputPathname = 0; // no valid command line break; } global::mergeSrc = argv[i]; global::mergeMode = true; } else if (std::strcmp(argv[i], "-o") == 0) { if (++i == argc) { global::inputPathname = 0; // no valid command line break; } global::outputPathname = argv[i]; } else if (std::strcmp(argv[i], "-p") == 0) { if (++i == argc) { global::inputPathname = 0; // no valid command line break; } global::prj = argv[i]; } else if (std::strcmp(argv[i], "-r") == 0) { if (++i == argc) { global::inputPathname = 0; // no valid command line break; } global::prjRoot = argv[i]; } else { global::inputPathname = 0; // no valid command line break; } } if (global::inputPathname == 0 || global::outputPathname == 0) { std::fprintf( stderr, ("Syntax: transex3 [-p Prj] [-r PrjRoot] -i FileIn -o FileOut" " [-m DataBase] [-e] [-l l1,l2,...]\n" " Prj: Project\n" " PrjRoot: Path to project root (../.. etc.)\n" " FileIn: Source files (*.src)\n" " FileOut: Destination file (*.*)\n" " DataBase: Mergedata (*.sdf)\n" " -e: Disable writing errorlog\n" " -l: Restrict the handled languages; l1, l2, ... are elements of" " (de, en-US, ...)\n")); std::exit(EXIT_FAILURE); } Export::InitLanguages(); } } extern "C" { FILE * init(int argc, char ** argv) { handleArguments(argc, argv); FILE * pFile = std::fopen(global::inputPathname, "r"); if (pFile == 0) { std::fprintf( stderr, "Error: Cannot open file \"%s\"\n", global::inputPathname); std::exit(EXIT_FAILURE); } if (global::mergeMode) { global::exporter.reset( new Export(global::mergeSrc, global::outputPathname)); } else { sActFileName = common::pathnameToken(global::inputPathname, global::prjRoot); global::exporter.reset(new Export(global::outputPathname)); } global::exporter->Init(); return pFile; } int Parse( int nTyp, const char *pTokenText ){ global::exporter->Execute( nTyp , pTokenText ); return 1; } void Close(){ global::exporter->pParseQueue->Close(); global::exporter.reset(); // avoid nontrivial Export dtor being executed during exit } int WorkOnTokenSet( int nTyp, char *pTokenText ) { global::exporter->pParseQueue->Push( QueueEntry( nTyp , rtl::OString(pTokenText) ) ); return 1; } } // extern extern "C" { /*****************************************************************************/ int SetError() /*****************************************************************************/ { // set error at global instance of class Export global::exporter->SetError(); return 1; } } extern "C" { /*****************************************************************************/ int GetError() /*****************************************************************************/ { // get error at global instance of class Export if (global::exporter->GetError()) return 1; return sal_False; } } // // class ResData // /*****************************************************************************/ sal_Bool ResData::SetId( const rtl::OString& rId, sal_uInt16 nLevel ) /*****************************************************************************/ { if ( nLevel > nIdLevel ) { nIdLevel = nLevel; sId = rId; if ( bChild && bChildWithText ) { rtl::OString sError(RTL_CONSTASCII_STRINGPARAM("ResId after child definition")); yyerror(sError.getStr()); SetError(); } if ( sId.getLength() > 255 ) { YYWarning( "LocalId > 255 chars, truncating..." ); sId = sId.copy(0, 255).trim(); } return sal_True; } return sal_False; } // // class Export // Export::Export(const rtl::OString &rOutput) : pWordTransformer( NULL ), bDefine( sal_False ), bNextMustBeDefineEOL( sal_False ), nLevel( 0 ), nList( LIST_NON ), nListIndex( 0 ), nListLevel( 0 ), bSkipFile( false ), sProject( global::prj ), sRoot( global::prjRoot ), bMergeMode( false ), bError( sal_False ), bReadOver( sal_False ), bDontWriteOutput( sal_False ), sFilename( global::inputPathname ) { pParseQueue = new ParserQueue( *this ); if( !isInitialized ) InitLanguages(); // used when export is enabled // open output stream aOutput.open(rOutput.getStr(), std::ios_base::out | std::ios_base::trunc); if (!aOutput.is_open()) { fprintf(stderr, "ERROR : Can't open file %s\n", rOutput.getStr()); exit ( -1 ); } } Export::Export(const rtl::OString &rMergeSource, const rtl::OString &rOutput) : pWordTransformer( NULL ), bDefine( sal_False ), bNextMustBeDefineEOL( sal_False ), nLevel( 0 ), nList( LIST_NON ), nListIndex( 0 ), nListLevel( 0 ), bSkipFile( false ), sProject( global::prj ), sRoot( global::prjRoot ), bMergeMode( sal_True ), sMergeSrc( rMergeSource ), bError( sal_False ), bReadOver( sal_False ), bDontWriteOutput( sal_False ), sFilename( global::inputPathname ) { pParseQueue = new ParserQueue( *this ); if( !isInitialized ) InitLanguages( bMergeMode ); // used when merge is enabled // open output stream aOutput.open(rOutput.getStr(), std::ios_base::out | std::ios_base::trunc); } /*****************************************************************************/ void Export::Init() /*****************************************************************************/ { // resets the internal status, used before parseing another file sActPForm = ""; bDefine = sal_False; bNextMustBeDefineEOL = sal_False; nLevel = 0; nList = LIST_NON; m_sListLang = rtl::OString(); nListIndex = 0; for ( size_t i = 0, n = aResStack.size(); i < n; ++i ) delete aResStack[ i ]; aResStack.clear(); } /*****************************************************************************/ Export::~Export() /*****************************************************************************/ { if( pParseQueue ) delete pParseQueue; aOutput.close(); for ( size_t i = 0, n = aResStack.size(); i < n; ++i ) delete aResStack[ i ]; aResStack.clear(); if ( bMergeMode ) { if ( !pMergeDataFile ) pMergeDataFile = new MergeDataFile(sMergeSrc, global::inputPathname, global::errorLog); delete pMergeDataFile; } } /*****************************************************************************/ int Export::Execute( int nToken, const char * pToken ) /*****************************************************************************/ { rtl::OString sToken( pToken ); rtl::OString sOrig( sToken ); sal_Bool bWriteToMerged = bMergeMode; if ( nToken == CONDITION ) { rtl::OString sTestToken(pToken); sTestToken = sTestToken.replaceAll("\t", rtl::OString()). replaceAll(" ", rtl::OString()); if (( !bReadOver ) && ( sTestToken.indexOf("#ifndef__RSC_PARSER") == 0 )) bReadOver = sal_True; else if (( bReadOver ) && ( sTestToken.indexOf("#endif") == 0 )) bReadOver = sal_False; } if ((( nToken < FILTER_LEVEL ) || ( bReadOver )) && (!(( bNextMustBeDefineEOL ) && ( sOrig == "\n" )))) { // this tokens are not mandatory for parsing, so ignore them ... if ( bMergeMode ) WriteToMerged( sOrig , false ); // ... ore whrite them directly to dest. return 0; } ResData *pResData = NULL; if ( nLevel ) { // res. exists at cur. level pResData = ( (nLevel-1) < aResStack.size() ) ? aResStack[ nLevel-1 ] : NULL; } else if (( nToken != RESSOURCE ) && ( nToken != RESSOURCEEXPR ) && ( nToken != SMALRESSOURCE ) && ( nToken != LEVELUP ) && ( nToken != NORMDEFINE ) && ( nToken != RSCDEFINE ) && ( nToken != CONDITION ) && ( nToken != PRAGMA )) { // no res. exists at cur. level so return if ( bMergeMode ) WriteToMerged( sOrig , false ); return 0; } // #define NO_LOCALIZE_EXPORT if( bSkipFile ){ if ( bMergeMode ) { WriteToMerged( sOrig , false ); } return 1; } if ( bDefine ) { if (( nToken != EMPTYLINE ) && ( nToken != LEVELDOWN ) && ( nToken != LEVELUP )) { // cur. res. defined in macro if ( bNextMustBeDefineEOL ) { if ( nToken != RSCDEFINELEND ) { // end of macro found, so destroy res. bDefine = sal_False; if ( bMergeMode ) { MergeRest( pResData ); } bNextMustBeDefineEOL = sal_False; Execute( LEVELDOWN, "" ); } else { // next line also in macro definition bNextMustBeDefineEOL = sal_False; if ( bMergeMode ) WriteToMerged( sOrig , false ); return 1; } } } } sal_Bool bExecuteDown = sal_False; if ( nToken != LEVELDOWN ) { sal_uInt16 nOpen = 0; sal_uInt16 nClose = 0; sal_Bool bReadOver1 = sal_False; sal_uInt16 i = 0; for ( i = 0; i < sToken.getLength(); i++ ) { if ( sToken[i] == '"' ) bReadOver1 = !bReadOver1; if ( !bReadOver1 && ( sToken[i] == '{' )) nOpen++; } bReadOver1 = sal_False; for ( i = 0; i < sToken.getLength(); i++ ) { if ( sToken[i] == '"' ) bReadOver1 = !bReadOver1; if ( !bReadOver1 && ( sToken[i] == '}' )) nClose++; } if ( nOpen < nClose ) bExecuteDown = sal_True; } switch ( nToken ) { case NORMDEFINE: sToken = sToken.replace('\r', ' ').replace('\t', ' '); for (;;) { sal_Int32 n = 0; sToken = sToken.replaceFirst(" ", " ", &n); if (n == -1) { break; } } if( sToken.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("#define NO_LOCALIZE_EXPORT")) ){ bSkipFile = true; return 0; } if ( bMergeMode ) WriteToMerged( sOrig , false ); return 0; case RSCDEFINE: bDefine = sal_True; // res. defined in macro case RESSOURCE: case RESSOURCEEXPR: { bDontWriteOutput = sal_False; if ( nToken != RSCDEFINE ) bNextMustBeDefineEOL = sal_False; // this is the beginning of a new res. nLevel++; if ( nLevel > 1 ) { aResStack[ nLevel - 2 ]->bChild = sal_True; } // create new instance for this res. and fill mandatory fields pResData = new ResData( sActPForm, FullId() , sFilename ); aResStack.push_back( pResData ); sToken = sToken.replaceAll("\n", rtl::OString()). replaceAll("\r", rtl::OString()). replaceAll("{", rtl::OString()).replace('\t', ' '); sToken = sToken.trim(); rtl::OString sTLower = sToken.getToken(0, ' ').toAsciiLowerCase(); pResData->sResTyp = sTLower; rtl::OString sId( sToken.copy( pResData->sResTyp.getLength() + 1 )); rtl::OString sCondition; if ( sId.indexOf( '#' ) != -1 ) { // between ResTyp, Id and paranthes is a precomp. condition sCondition = "#"; sal_Int32 n = 0; sId = sId.getToken(0, '#', n); sCondition += sId.getToken(0, '#', n); } sId = sId.getToken(0, '/'); CleanValue( sId ); sId = sId.replaceAll("\t", rtl::OString()); pResData->SetId( sId, ID_LEVEL_IDENTIFIER ); if (!sCondition.isEmpty()) { Execute( CONDITION, ""); // execute the precomp. condition } } break; case SMALRESSOURCE: { bDontWriteOutput = sal_False; // this is the beginning of a new res. bNextMustBeDefineEOL = sal_False; nLevel++; if ( nLevel > 1 ) { aResStack[ nLevel - 2 ]->bChild = sal_True; } // create new instance for this res. and fill mandatory fields pResData = new ResData( sActPForm, FullId() , sFilename ); aResStack.push_back( pResData ); sToken = sToken.replaceAll("\n", rtl::OString()). replaceAll("\r", rtl::OString()). replaceAll("{", rtl::OString()). replaceAll("\t", rtl::OString()). replaceAll(" ", rtl::OString()). replaceAll("\\", rtl::OString()).toAsciiLowerCase(); pResData->sResTyp = sToken; } break; case LEVELUP: { // push if ( nList ) nListLevel++; if ( nList ) break; bDontWriteOutput = sal_False; rtl::OString sLowerTyp; if ( pResData ) sLowerTyp = "unknown"; nLevel++; if ( nLevel > 1 ) { aResStack[ nLevel - 2 ]->bChild = sal_True; } ResData *pNewData = new ResData( sActPForm, FullId() , sFilename ); pNewData->sResTyp = sLowerTyp; aResStack.push_back( pNewData ); } break; case LEVELDOWN: { // pop if ( !nList ) { bDontWriteOutput = sal_False; if ( nLevel ) { if ( bDefine && (nLevel == 1 )) { bDefine = sal_False; bNextMustBeDefineEOL = sal_False; } WriteData( pResData ); ResStack::iterator it = aResStack.begin(); ::std::advance( it, nLevel-1 ); delete *it; aResStack.erase( it ); nLevel--; } } else { if ( bDefine ) bNextMustBeDefineEOL = sal_True; if ( !nListLevel ) { if ( bMergeMode ) MergeRest( pResData, MERGE_MODE_LIST ); nList = LIST_NON; } else nListLevel--; } } break; case ASSIGNMENT: { bDontWriteOutput = sal_False; // interpret different types of assignement sal_Int32 n = 0; rtl::OString sKey = sToken.getToken(0, '=', n). replaceAll(" ", rtl::OString()). replaceAll("\t", rtl::OString()); rtl::OString sValue = sToken.getToken(0, '=', n); CleanValue( sValue ); sKey = sKey.toAsciiUpperCase(); if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("IDENTIFIER"))) { rtl::OString sId( sValue.replaceAll("\t", rtl::OString()). replaceAll(" ", rtl::OString())); pResData->SetId(sId, ID_LEVEL_IDENTIFIER); } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("HELPID"))) { pResData->sHelpId = sValue; } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("STRINGLIST"))) { pResData->bList = sal_True; nList = LIST_STRING; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("FILTERLIST"))) { pResData->bList = sal_True; nList = LIST_FILTER; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UIENTRIES"))) { pResData->bList = sal_True; nList = LIST_UIENTRIES; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } if (sToken.indexOf( '{' ) != -1 && (helper::countOccurrences(sToken, '{') > helper::countOccurrences(sToken, '}'))) { Parse( LEVELUP, "" ); } } break; case UIENTRIES: case LISTASSIGNMENT: { bDontWriteOutput = sal_False; rtl::OString sTmpToken( sToken.replaceAll(" ", rtl::OString()).toAsciiLowerCase()); sal_Int32 nPos = sTmpToken.indexOf("[en-us]="); if (nPos != -1) { rtl::OString sKey( sTmpToken.copy(0 , nPos).replaceAll(" ", rtl::OString()). replaceAll("\t", rtl::OString())); rtl::OString sValue = sToken.getToken(1, '='); CleanValue( sValue ); sKey = sKey.toAsciiUpperCase(); if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("STRINGLIST"))) { pResData->bList = sal_True; nList = LIST_STRING; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("FILTERLIST"))) { pResData->bList = sal_True; nList = LIST_FILTER; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } // PairedList else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("PAIREDLIST"))) { pResData->bList = sal_True; nList = LIST_PAIRED; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("ITEMLIST"))) { pResData->bList = sal_True; nList = LIST_ITEM; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UIENTRIES"))) { pResData->bList = sal_True; nList = LIST_UIENTRIES; m_sListLang = SOURCE_LANGUAGE; nListIndex = 0; nListLevel = 0; } } else { // new res. is a String- or FilterList sal_Int32 n = 0; rtl::OString sKey( sToken.getToken(0, '[', n).replaceAll(" ", rtl::OString()). replaceAll("\t", rtl::OString()).toAsciiUpperCase()); if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("STRINGLIST"))) nList = LIST_STRING; else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("FILTERLIST"))) nList = LIST_FILTER; else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("PAIREDLIST"))) nList = LIST_PAIRED; // abcd else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("ITEMLIST"))) nList = LIST_ITEM; else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UIENTRIES"))) nList = LIST_UIENTRIES; if ( nList ) { rtl::OString sLang = sToken.getToken(0, ']', n); CleanValue( sLang ); m_sListLang = sLang; nListIndex = 0; nListLevel = 0; } } } break; case TEXT: case _LISTTEXT: case LISTTEXT: { // this is an entry for a String- or FilterList if ( nList ) { SetChildWithText(); sal_Int32 n = 0; rtl::OString sEntry(sToken.getToken(1, '"', n)); if ( helper::countOccurrences(sToken, '"') > 2 ) sEntry += "\""; if ( sEntry == "\\\"" ) sEntry = "\""; InsertListEntry( sEntry, sOrig ); if ( bMergeMode && ( sEntry != "\"" )) { PrepareTextToMerge( sOrig, nList, m_sListLang, pResData ); } } } break; case LONGTEXTLINE: case TEXTLINE: bDontWriteOutput = sal_False; if ( nLevel ) { CutComment( sToken ); // this is a text line!!! rtl::OString t(sToken.getToken(0, '=')); rtl::OString sKey( t.getToken(0, '[').replaceAll(" ", rtl::OString()). replaceAll("\t", rtl::OString())); rtl::OString sText( GetText( sToken, nToken )); rtl::OString sLang; if ( sToken.getToken(0, '=').indexOf('[') != -1 ) { sLang = sToken.getToken(0, '=').getToken(1, '['). getToken(0, ']'); CleanValue( sLang ); } rtl::OString sLangIndex = sLang; rtl::OString sOrigKey = sKey; if ( !sText.isEmpty() && !sLang.isEmpty() ) { sKey = sKey.toAsciiUpperCase(); if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("TEXT")) || sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("MESSAGE")) || sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("CUSTOMUNITTEXT")) || sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("SLOTNAME")) || sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UINAME"))) { SetChildWithText(); if ( Export::isSourceLanguage( sLangIndex ) ) pResData->SetId( sText, ID_LEVEL_TEXT ); pResData->bText = sal_True; pResData->sTextTyp = sOrigKey; if ( bMergeMode ) { PrepareTextToMerge( sOrig, STRING_TYP_TEXT, sLangIndex, pResData ); } else { if (!pResData->sText[ sLangIndex ].isEmpty()) { rtl::OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language ")); sError.append(sLangIndex); sError.append(RTL_CONSTASCII_STRINGPARAM("defined twice")); yyerror(sError.getStr()); } pResData->sText[ sLangIndex ] = sText; } } else if ( sKey == "HELPTEXT" ) { SetChildWithText(); pResData->bHelpText = sal_True; if ( bMergeMode ) PrepareTextToMerge( sOrig, STRING_TYP_HELPTEXT, sLangIndex, pResData ); else { if (!pResData->sHelpText[ sLangIndex ].isEmpty()) { rtl::OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language ")); sError.append(sLangIndex); sError.append(" defined twice"); YYWarning(sError.getStr()); } pResData->sHelpText[ sLangIndex ] = sText; } } else if ( sKey == "QUICKHELPTEXT" ) { SetChildWithText(); pResData->bQuickHelpText = sal_True; if ( bMergeMode ) PrepareTextToMerge( sOrig, STRING_TYP_QUICKHELPTEXT, sLangIndex, pResData ); else { if (!pResData->sQuickHelpText[ sLangIndex ].isEmpty()) { rtl::OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language ")); sError.append(sLangIndex); sError.append(RTL_CONSTASCII_STRINGPARAM(" defined twice")); YYWarning(sError.getStr()); } pResData->sQuickHelpText[ sLangIndex ] = sText; } } else if ( sKey == "TITLE" ) { SetChildWithText(); pResData->bTitle = sal_True; if ( bMergeMode ) PrepareTextToMerge( sOrig, STRING_TYP_TITLE, sLangIndex, pResData ); else { if ( !pResData->sTitle[ sLangIndex ].isEmpty()) { rtl::OStringBuffer sError(RTL_CONSTASCII_STRINGPARAM("Language ")); sError.append(sLangIndex); sError.append(RTL_CONSTASCII_STRINGPARAM(" defined twice")); YYWarning(sError.getStr()); } pResData->sTitle[ sLangIndex ] = sText; } } else if ( sKey == "ACCESSPATH" ) { pResData->SetId( sText, ID_LEVEL_ACCESSPATH ); } else if ( sKey == "FIELDNAME" ) { pResData->SetId( sText, ID_LEVEL_FIELDNAME ); } } } break; case NEWTEXTINRES: { bDontWriteOutput = sal_True; } break; case APPFONTMAPPING: { bDontWriteOutput = sal_False; // this is a AppfontMapping, so look if its a definition // of field size sal_Int32 n = 0; rtl::OString sKey( sToken.getToken(0, '=', n).replaceAll(" ", rtl::OString()). replaceAll("\t", rtl::OString())); rtl::OString sMapping = sToken.getToken(0, '=', n); sMapping = sMapping.getToken(1, '('); sMapping = sMapping.getToken(0, ')'). replaceAll(rtl::OString(' '), rtl::OString()). replaceAll(rtl::OString('\t'), rtl::OString()). toAsciiUpperCase(); if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("SIZE"))) { pResData->nWidth = sMapping.getToken(0, ',').toInt32(); } else if (sKey.equalsL(RTL_CONSTASCII_STRINGPARAM("POSSIZE"))) { pResData->nWidth = sMapping.getToken(2, ',').toInt32(); } } break; case RSCDEFINELEND: bDontWriteOutput = sal_False; break; case CONDITION: { bDontWriteOutput = sal_False; sToken = sToken.replace('\r', ' ').replace('\t', ' '); for (;;) { sal_Int32 n = 0; sToken = sToken.replaceFirst(" ", " ", &n); if (n == -1) { break; } } sal_Int32 n = 0; rtl::OString sCondition(sToken.getToken(0, ' ', n)); if ( sCondition == "#ifndef" ) { sActPForm = "!defined "; sActPForm += sToken.getToken(0, ' ', n); } else if ( sCondition == "#ifdef" ) { sActPForm = "defined "; sActPForm += sToken.getToken(0, ' ', n); } else if ( sCondition == "#if" ) { sActPForm = sToken.copy( 4 ).replaceAll("||", "\\or"); } else if ( sCondition == "#elif" ) { sActPForm = sToken.copy( 6 ).replaceAll("||", "\\or"); } else if ( sCondition == "#else" ) { sActPForm = sCondition; } else if ( sCondition == "#endif" ) { sActPForm = ""; } else break; if ( nLevel ) { WriteData( pResData, sal_True ); pResData->sPForm = sActPForm; } } break; case EMPTYLINE : { bDontWriteOutput = sal_False; if ( bDefine ) { bNextMustBeDefineEOL = sal_False; bDefine = sal_False; while ( nLevel ) Parse( LEVELDOWN, "" ); } } break; case PRAGMA : { bDontWriteOutput = sal_False; fprintf(stderr, "ERROR: archaic PRAGMA %s\n", sToken.getStr()); exit(-1); } break; case TEXTREFID : { bDontWriteOutput = sal_True; } } if ( bWriteToMerged ) { // the current token must be written to dest. without merging if( bDefine && sOrig.getLength() > 2 ){ for( sal_uInt16 n = 0 ; n < sOrig.getLength() ; n++ ){ if( sOrig[n] == '\n' && sOrig[n-1] != '\\'){ sOrig = sOrig.replaceAt(n++, 0, "\\"); } } } WriteToMerged( sOrig , false); } if ( bExecuteDown ) { Parse( LEVELDOWN, "" ); } return 1; } /*****************************************************************************/ void Export::CutComment( rtl::OString &rText ) /*****************************************************************************/ { if (rText.indexOf("//") != -1) { rtl::OString sWork(rText.replaceAll("\\\"", "XX")); bool bInner = false; for (sal_Int32 i = 0; i < sWork.getLength() - 1; ++i) { if (sWork[i] == '"') { bInner = !bInner; } else if (sWork[i] == '/' && !bInner && sWork[i + 1] == '/' ) { rText = rText.copy(0, i); break; } } } } /*****************************************************************************/ sal_Bool Export::WriteData( ResData *pResData, sal_Bool bCreateNew ) /*****************************************************************************/ { if ( bMergeMode ) { MergeRest( pResData ); return sal_True; } // mandatory to export: en-US if (( !pResData->sText[ SOURCE_LANGUAGE ].isEmpty()) || ( !pResData->sHelpText[ SOURCE_LANGUAGE ].isEmpty()) || ( !pResData->sQuickHelpText[ SOURCE_LANGUAGE ].isEmpty()) || ( !pResData->sTitle[ SOURCE_LANGUAGE ].isEmpty())) { rtl::OString sGID = pResData->sGId; rtl::OString sLID; if (sGID.isEmpty()) sGID = pResData->sId; else sLID = pResData->sId; rtl::OString sXText; rtl::OString sXHText; rtl::OString sXQHText; rtl::OString sXTitle; sXText = pResData->sText[ SOURCE_LANGUAGE ]; if (!pResData->sText[ X_COMMENT ].isEmpty()) sXHText = pResData->sText[ X_COMMENT ]; else sXHText = pResData->sHelpText[ SOURCE_LANGUAGE ]; sXQHText = pResData->sQuickHelpText[ SOURCE_LANGUAGE ]; sXTitle = pResData->sTitle[ SOURCE_LANGUAGE ]; if (sXText.isEmpty()) sXText = "-"; rtl::OString sOutput( sProject ); sOutput += "\t"; if ( !sRoot.isEmpty()) sOutput += sActFileName; sOutput += "\t0\t"; sOutput += pResData->sResTyp; sOutput += "\t"; sOutput += sGID; sOutput += "\t"; sOutput += sLID; sOutput += "\t"; sOutput += pResData->sHelpId; sOutput += "\t"; sOutput += pResData->sPForm; sOutput += "\t"; sOutput += rtl::OString::valueOf(pResData->nWidth); sOutput += "\t"; sOutput += "en-US"; sOutput += "\t"; sOutput += sXText; sOutput += "\t"; sOutput += sXHText; sOutput += "\t"; sOutput += sXQHText; sOutput+= "\t"; sOutput += sXTitle; sOutput += "\t"; aOutput << sOutput.getStr() << '\n'; if ( bCreateNew ) { pResData->sText[ SOURCE_LANGUAGE ] = ""; pResData->sHelpText[ SOURCE_LANGUAGE ] = ""; pResData->sQuickHelpText[ SOURCE_LANGUAGE ]= ""; pResData->sTitle[ SOURCE_LANGUAGE ] = ""; } } if ( pResData->pStringList ) { rtl::OString sList( "stringlist" ); WriteExportList( pResData, pResData->pStringList, sList, bCreateNew ); if ( bCreateNew ) pResData->pStringList = 0; } if ( pResData->pFilterList ) { rtl::OString sList( "filterlist" ); WriteExportList( pResData, pResData->pFilterList, sList, bCreateNew ); if ( bCreateNew ) pResData->pFilterList = 0; } if ( pResData->pItemList ) { rtl::OString sList( "itemlist" ); WriteExportList( pResData, pResData->pItemList, sList, bCreateNew ); if ( bCreateNew ) pResData->pItemList = 0; } if ( pResData->pPairedList ) { rtl::OString sList( "pairedlist" ); WriteExportList( pResData, pResData->pPairedList, sList, bCreateNew ); if ( bCreateNew ) pResData->pItemList = 0; } if ( pResData->pUIEntries ) { rtl::OString sList( "uientries" ); WriteExportList( pResData, pResData->pUIEntries, sList, bCreateNew ); if ( bCreateNew ) pResData->pUIEntries = 0; } return sal_True; } rtl::OString Export::GetPairedListID(const rtl::OString& rText) { // < "STRING" ; IDENTIFIER ; > ; return rText.getToken(1, ';').toAsciiUpperCase().replace('\t', ' ').trim(); } rtl::OString Export::GetPairedListString(const rtl::OString& rText) { // < "STRING" ; IDENTIFIER ; > ; rtl::OString sString(rText.getToken(0, ';').replace('\t', ' ')); sString = sString.trim(); rtl::OString s1(sString.copy(sString.indexOf('"') + 1)); sString = s1.copy(0, s1.lastIndexOf('"')); return sString.trim(); } rtl::OString Export::StripList(const rtl::OString & rText) { rtl::OString s1 = rText.copy( rText.indexOf('\"') + 1); return s1.copy( 0 , s1.lastIndexOf('\"')); } sal_Bool Export::WriteExportList(ResData *pResData, ExportList *pExportList, const rtl::OString &rTyp, sal_Bool bCreateNew) { rtl::OString sGID(pResData->sGId); if (sGID.isEmpty()) sGID = pResData->sId; else { sGID += "."; sGID += pResData->sId; while (sGID.getLength() != 0 && sGID[sGID.getLength() - 1] == '.') { sGID = sGID.copy(0, sGID.getLength() - 1); } } rtl::OString sCur; for ( size_t i = 0; pExportList != NULL && i < pExportList->size(); i++ ) { ExportListEntry *pEntry = (*pExportList)[ i ]; rtl::OString sLID(rtl::OString::valueOf(static_cast(i + 1))); for (unsigned int n = 0; n < aLanguages.size(); ++n) { sCur = aLanguages[ n ]; if (!(*pEntry)[ SOURCE_LANGUAGE ].isEmpty()) { rtl::OString sText((*pEntry)[ SOURCE_LANGUAGE ] ); // Strip PairList Line String if (rTyp.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("pairedlist"))) { sLID = GetPairedListID( sText ); if (!(*pEntry)[ sCur ].isEmpty()) sText = (*pEntry)[ sCur ]; sText = GetPairedListString( sText ); } else { sText = StripList( (*pEntry)[ sCur ] ); if( sText == "\\\"" ) sText = "\""; } rtl::OStringBuffer sOutput(sProject); sOutput.append('\t'); if ( !sRoot.isEmpty()) sOutput.append(sActFileName); sOutput.append("\t0\t"); sOutput.append(rTyp).append('\t'); sOutput.append(sGID).append('\t'); sOutput.append(sLID).append("\t\t"); sOutput.append(pResData->sPForm).append("\t0\t"); sOutput.append(sCur).append('\t'); sOutput.append(sText).append("\t\t\t\t"); aOutput << sOutput.makeStringAndClear().getStr() << '\n'; } } if ( bCreateNew ) delete [] pEntry; } if ( bCreateNew ) delete pExportList; return sal_True; } rtl::OString Export::FullId() { rtl::OStringBuffer sFull; if ( nLevel > 1 ) { sFull.append(aResStack[ 0 ]->sId); for ( size_t i = 1; i < nLevel - 1; ++i ) { rtl::OString sToAdd = aResStack[ i ]->sId; if (!sToAdd.isEmpty()) sFull.append('.').append(sToAdd); } } if (sFull.getLength() > 255) { rtl::OString sError(RTL_CONSTASCII_STRINGPARAM("GroupId > 255 chars")); printf("GroupID = %s\n", sFull.getStr()); yyerror(sError.getStr()); } return sFull.makeStringAndClear(); } void Export::InsertListEntry(const rtl::OString &rText, const rtl::OString &rLine) { ResData *pResData = ( nLevel-1 < aResStack.size() ) ? aResStack[ nLevel-1 ] : NULL; ExportList *pList = NULL; if ( nList == LIST_STRING ) { pList = pResData->pStringList; if ( !pList ) { pResData->pStringList = new ExportList(); pList = pResData->pStringList; nListIndex = 0; } } else if ( nList == LIST_FILTER ) { pList = pResData->pFilterList; if ( !pList ) { pResData->pFilterList = new ExportList(); pList = pResData->pFilterList; nListIndex = 0; } } else if ( nList == LIST_ITEM ) { pList = pResData->pItemList; if ( !pList ) { pResData->pItemList = new ExportList(); pList = pResData->pItemList; nListIndex = 0; } } else if ( nList == LIST_PAIRED ) { pList = pResData->pPairedList; if ( !pList ) { pResData->pPairedList = new ExportList(); pList = pResData->pPairedList; nListIndex = 0; } } else if ( nList == LIST_UIENTRIES ) { pList = pResData->pUIEntries; if ( !pList ) { pResData->pUIEntries = new ExportList(); pList = pResData->pUIEntries; nListIndex = 0; } } else return; if ( nListIndex + 1 > pList->size()) { ExportListEntry *pNew = new ExportListEntry(); (*pNew)[LIST_REFID] = rtl::OString::valueOf(static_cast(REFID_NONE)); pList->push_back(pNew); } ExportListEntry *pCurEntry = (*pList)[ nListIndex ]; // For paired list use the line to set proper lid if( nList == LIST_PAIRED ){ (*pCurEntry)[ m_sListLang ] = rLine; }else (*pCurEntry)[ m_sListLang ] = rText; if ( Export::isSourceLanguage( m_sListLang ) ) { (*pCurEntry)[ SOURCE_LANGUAGE ] = rLine; pList->NewSourceLanguageListEntry(); } nListIndex++; } /*****************************************************************************/ void Export::CleanValue( rtl::OString &rValue ) /*****************************************************************************/ { while ( !rValue.isEmpty()) { if (( rValue[0] == ' ' ) || ( rValue[0] == '\t' )) rValue = rValue.copy( 1 ); else break; } if ( !rValue.isEmpty()) { for ( sal_Int32 i = rValue.getLength() - 1; i > 0; i-- ) { if (( rValue[i] == ' ' ) || ( rValue[i] == '\t' ) || ( rValue[i] == '\n' ) || ( rValue[i] == ';' ) || ( rValue[i] == '{' ) || ( rValue[i] == '\\' ) || ( rValue[i] == '\r' )) rValue = rValue.copy(0, i); else break; } } } #define TXT_STATE_NON 0x000 #define TXT_STATE_TEXT 0x001 #define TXT_STATE_MACRO 0x002 rtl::OString Export::GetText(const rtl::OString &rSource, int nToken) { rtl::OString sReturn; switch ( nToken ) { case TEXTLINE: case LONGTEXTLINE: { rtl::OString sTmp(rSource.copy(rSource.indexOf("="))); CleanValue( sTmp ); sTmp = sTmp.replaceAll("\n", rtl::OString()). replaceAll("\r", rtl::OString()). replaceAll("\\\\\"", "-=<[BSlashBSlashHKom]>=-\""). replaceAll("\\\"", "-=<[Hochkomma]>=-"). replaceAll("\\", "-=<[0x7F]>=-"). replaceAll("\\0x7F", "-=<[0x7F]>=-"); sal_uInt16 nState = TXT_STATE_TEXT; for (sal_Int32 i = 1; i <= helper::countOccurrences(sTmp, '"'); ++i) { rtl::OString sToken(sTmp.getToken(i, '"')); if (!sToken.isEmpty()) { if ( nState == TXT_STATE_TEXT ) { sReturn += sToken; nState = TXT_STATE_MACRO; } else { sToken = sToken.replace('\t', ' '); for (;;) { sal_Int32 n = 0; sToken = sToken.replaceFirst(" ", " ", &n); if (n == -1) { break; } } sToken = sToken.trim(); if (!sToken.isEmpty()) { sReturn += "\\\" "; sReturn += sToken; sReturn += " \\\""; } nState = TXT_STATE_TEXT; } } } sReturn = sReturn.replaceAll("-=<[0x7F]>=-", ""). replaceAll("-=<[Hochkomma]>=-", "\""). replaceAll("-=<[BSlashBSlashHKom]>=-", "\\\\"). replaceAll("\\\\", "-=<[BSlashBSlash]>=-"). replaceAll("-=<[BSlashBSlash]>=-", "\\"); } break; } return sReturn; } void Export::WriteToMerged(const rtl::OString &rText , bool bSDFContent) { rtl::OString sText(rText); for (;;) { sal_Int32 n = 0; sText = sText.replaceFirst(" \n", "\n", &n); if (n == -1) { break; } } if (pParseQueue->bNextIsM && bSDFContent && sText.getLength() > 2) { for (sal_Int32 n = 0; n < sText.getLength(); ++n) { if (sText[n] == '\n' && sText[n - 1] != '\\') { sText = sText.replaceAt(n++, 0, "\\"); } } } else if (pParseQueue->bLastWasM && sText.getLength() > 2) { for (sal_Int32 n = 0; n < sText.getLength(); ++n) { if (sText[n] == '\n' && sText[n - 1] != '\\') { sText = sText.replaceAt(n++, 0, "\\"); } if (sText[n] == '\n') { pParseQueue->bMflag = true; } } } else if (pParseQueue->bCurrentIsM && bSDFContent && sText.getLength() > 2) { for (sal_Int32 n = 0; n < sText.getLength(); ++n) { if (sText[n] == '\n' && sText[n - 1] != '\\') { sText = sText.replaceAt(n++, 0, "\\"); pParseQueue->bMflag = true; } } } else if (pParseQueue->bMflag) { for (sal_Int32 n = 1; n < sText.getLength(); ++n) { if (sText[n] == '\n' && sText[n - 1] != '\\') { sText = sText.replaceAt(n++, 0, "\\"); } } } for (sal_Int32 i = 0; i < sText.getLength(); ++i) { if (sText[i] == '\n') { aOutput << '\n'; } else { char cChar = sText[i]; aOutput << cChar; } } } /*****************************************************************************/ void Export::ConvertMergeContent( rtl::OString &rText ) /*****************************************************************************/ { sal_Bool bNoOpen = ( rText.indexOf( "\\\"" ) != 0 ); sal_Bool bNoClose = !rText.endsWithL(RTL_CONSTASCII_STRINGPARAM("\\\"")); rtl::OStringBuffer sNew; for ( sal_Int32 i = 0; i < rText.getLength(); i++ ) { rtl::OString sChar( rText[i]); if (sChar.equalsL(RTL_CONSTASCII_STRINGPARAM("\\"))) { if (( i + 1 ) < rText.getLength()) { sal_Char cNext = rText[i + 1]; if ( cNext == '\"' ) { sChar = rtl::OString('\"'); i++; } else if ( cNext == 'n' ) { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\n")); i++; } else if ( cNext == 't' ) { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\t")); i++; } else if ( cNext == '\'' ) { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\\'")); i++; } else { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\\\")); } } else { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\\\")); } } else if (sChar.equalsL(RTL_CONSTASCII_STRINGPARAM("\""))) { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\\"")); } else if (sChar.equalsL(RTL_CONSTASCII_STRINGPARAM(""))) { sChar = rtl::OString(RTL_CONSTASCII_STRINGPARAM("\\0x7F")); } sNew.append(sChar); } rText = sNew.makeStringAndClear(); if ( bNoOpen ) { rtl::OString sTmp( rText ); rText = "\""; rText += sTmp; } if ( bNoClose ) rText += "\""; } sal_Bool Export::PrepareTextToMerge(rtl::OString &rText, sal_uInt16 nTyp, rtl::OString &rLangIndex, ResData *pResData) { // position to merge in: sal_Int32 nStart = 0; sal_Int32 nEnd = 0; rtl::OString sOldId = pResData->sId; rtl::OString sOldGId = pResData->sGId; rtl::OString sOldTyp = pResData->sResTyp; rtl::OString sOrigText( rText ); switch ( nTyp ) { case LIST_STRING : case LIST_UIENTRIES : case LIST_FILTER : case LIST_PAIRED: case LIST_ITEM : { ExportList *pList = NULL; switch ( nTyp ) { case LIST_STRING : { pResData->sResTyp = "stringlist"; pList = pResData->pStringList; } break; case LIST_UIENTRIES : { pResData->sResTyp = "uientries"; pList = pResData->pUIEntries; } break; case LIST_FILTER : { pResData->sResTyp = "filterlist"; pList = pResData->pFilterList; } break; case LIST_ITEM : { pResData->sResTyp = "itemlist"; pList = pResData->pItemList; } break; case LIST_PAIRED : { pResData->sResTyp = "pairedlist"; pList = pResData->pPairedList; } break; } if (pList) { ExportListEntry *pCurEntry = (*pList)[ nListIndex - 1 ]; if ( pCurEntry ) rText = (*pCurEntry)[ SOURCE_LANGUAGE ]; } nStart = rText.indexOf( '"' ); if ( nStart == -1 ) { rText = sOrigText; return sal_False; } sal_Bool bFound = sal_False; for ( nEnd = nStart + 1; nEnd < rText.getLength() && !bFound; nEnd++ ) { if ( rText[nEnd] == '\"' ) bFound = sal_True; } if ( !bFound ) { rText = sOrigText; return sal_False; } nEnd --; sLastListLine = rText; if (( sLastListLine.indexOf( '>' ) != -1 ) && ( sLastListLine.indexOf( '<' ) == -1 )) { rtl::OString sTmp = sLastListLine; sLastListLine = "<"; sLastListLine += sTmp; } if ( pResData->sResTyp.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("pairedlist")) ) { pResData->sId = GetPairedListID( sLastListLine ); } else pResData->sId = rtl::OString::valueOf(static_cast(nListIndex)); if (!pResData->sGId.isEmpty()) pResData->sGId = pResData->sGId + rtl::OString('.'); pResData->sGId = pResData->sGId + sOldId; nTyp = STRING_TYP_TEXT; } break; case STRING_TYP_TEXT : case STRING_TYP_HELPTEXT : case STRING_TYP_QUICKHELPTEXT : case STRING_TYP_TITLE : { nStart = rText.indexOf( "=" ); if ( nStart == -1 ) { rText = sOrigText; return sal_False; } nStart++; sal_Bool bFound = sal_False; while(( nStart < rText.getLength()) && !bFound ) { if (( rText[nStart] != ' ' ) && ( rText[nStart] != '\t' )) bFound = sal_True; else nStart ++; } // no start position found if ( !bFound ) { rText = sOrigText; return sal_False; } // position to end mergeing in nEnd = rText.getLength() - 1; bFound = sal_False; while (( nEnd > nStart ) && !bFound ) { if (( rText[nEnd] != ' ' ) && ( rText[nEnd] != '\t' ) && ( rText[nEnd] != '\n' ) && ( rText[nEnd] != ';' ) && ( rText[nEnd] != '{' ) && ( rText[nEnd] != '\\' )) { bFound = sal_True; } else nEnd --; } } break; } // search for merge data if ( !pMergeDataFile ){ pMergeDataFile = new MergeDataFile( sMergeSrc, global::inputPathname, global::errorLog ); // Init Languages if( Export::sLanguages.equalsIgnoreAsciiCase("ALL") ) SetLanguages( pMergeDataFile->GetLanguages() ); else if( !isInitialized )InitLanguages(); } PFormEntrys *pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); pResData->sId = sOldId; pResData->sGId = sOldGId; pResData->sResTyp = sOldTyp; if ( !pEntrys ) { rText = sOrigText; return sal_False; // no data found } rtl::OString sContent; pEntrys->GetTransex3Text(sContent, nTyp, rLangIndex); if (sContent.isEmpty() && (!Export::isSourceLanguage(rLangIndex))) { rText = sOrigText; return sal_False; // no data found } if (Export::isSourceLanguage(rLangIndex)) return sal_False; rtl::OString sPostFix( rText.copy( ++nEnd )); rText = rText.copy(0, nStart); ConvertMergeContent( sContent ); // merge new res. in text line rText += sContent; rText += sPostFix; return sal_True; } void Export::ResData2Output( PFormEntrys *pEntry, sal_uInt16 nType, const rtl::OString& rTextType ) { sal_Bool bAddSemicolon = sal_False; sal_Bool bFirst = sal_True; rtl::OString sCur; for( unsigned int n = 0; n < aLanguages.size(); n++ ){ sCur = aLanguages[ n ]; rtl::OString sText; sal_Bool bText = pEntry->GetTransex3Text( sText, nType, sCur , sal_True ); if ( bText && !sText.isEmpty() && sText != "-" ) { rtl::OString sOutput; if ( bNextMustBeDefineEOL) { if ( bFirst ) sOutput += "\t\\\n"; else sOutput += ";\t\\\n"; } bFirst=sal_False; sOutput += "\t"; sOutput += rTextType; if ( ! Export::isSourceLanguage( sCur ) ) { sOutput += "[ "; sOutput += sCur; sOutput += " ] "; } sOutput += "= "; ConvertMergeContent( sText ); sOutput += sText; if ( bDefine ) sOutput += ";\\\n"; else if ( !bNextMustBeDefineEOL ) sOutput += ";\n"; else bAddSemicolon = sal_True; for ( sal_uInt16 j = 1; j < nLevel; j++ ) sOutput += "\t"; WriteToMerged( sOutput , true ); } } if ( bAddSemicolon ) { rtl::OString sOutput( ";" ); WriteToMerged( sOutput , false ); } } /*****************************************************************************/ void Export::MergeRest( ResData *pResData, sal_uInt16 nMode ) /*****************************************************************************/ { if ( !pMergeDataFile ){ pMergeDataFile = new MergeDataFile( sMergeSrc, global::inputPathname, global::errorLog ); // Init Languages if (Export::sLanguages.equalsIgnoreAsciiCase("ALL")) SetLanguages( pMergeDataFile->GetLanguages() ); else if( !isInitialized )InitLanguages(); } switch ( nMode ) { case MERGE_MODE_NORMAL : { PFormEntrys *pEntry = pMergeDataFile->GetPFormEntrys( pResData ); if ( pEntry ) { if ( pResData->bText ) ResData2Output( pEntry, STRING_TYP_TEXT, pResData->sTextTyp ); if ( pResData->bQuickHelpText ) ResData2Output( pEntry, STRING_TYP_QUICKHELPTEXT, rtl::OString("QuickHelpText") ); if ( pResData->bTitle ) ResData2Output( pEntry, STRING_TYP_TITLE, rtl::OString("Title") ); } // Merge Lists if ( pResData->bList ) { bool bPairedList = false; rtl::OString sOldId = pResData->sId; rtl::OString sOldGId = pResData->sGId; rtl::OString sOldTyp = pResData->sResTyp; if (!pResData->sGId.isEmpty()) pResData->sGId = pResData->sGId + rtl::OString('.'); pResData->sGId = pResData->sGId + sOldId; rtl::OString sSpace; for ( sal_uInt16 i = 1; i < nLevel-1; i++ ) sSpace += "\t"; for ( sal_uInt16 nT = LIST_STRING; nT <= LIST_UIENTRIES; nT++ ) { ExportList *pList = NULL; switch ( nT ) { case LIST_STRING : pResData->sResTyp = "stringlist"; pList = pResData->pStringList; bPairedList = false; break; case LIST_FILTER : pResData->sResTyp = "filterlist"; pList = pResData->pFilterList; bPairedList = false; break; case LIST_UIENTRIES : pResData->sResTyp = "uientries"; pList = pResData->pUIEntries;bPairedList = false; break; case LIST_ITEM : pResData->sResTyp = "itemlist"; pList = pResData->pItemList; bPairedList = false; break; case LIST_PAIRED : pResData->sResTyp = "pairedlist"; pList = pResData->pPairedList; bPairedList = true; break; } rtl::OString sCur; for( unsigned int n = 0; n < aLanguages.size(); n++ ) { sCur = aLanguages[ n ]; sal_uInt16 nIdx = 1; // Set matching pairedlist identifier if( bPairedList && pResData->pPairedList && ( nIdx == 1 ) ){ ExportListEntry* pListE = ( ExportListEntry* ) (*pResData->pPairedList)[ nIdx-1 ]; pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] ); } else pResData->sId = "1"; PFormEntrys *pEntrys; std::size_t nLIndex = 0; std::size_t nMaxIndex = 0; if ( pList ) nMaxIndex = pList->GetSourceLanguageListEntryCount(); pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); while( pEntrys && ( nLIndex < nMaxIndex )) { rtl::OString sText; sal_Bool bText; bText = pEntrys->GetTransex3Text( sText, STRING_TYP_TEXT, sCur, sal_True ); if( !bText ) bText = pEntrys->GetTransex3Text( sText , STRING_TYP_TEXT, SOURCE_LANGUAGE , sal_False ); if ( bText && !sText.isEmpty()) { if ( nIdx == 1 ) { rtl::OStringBuffer sHead; if ( bNextMustBeDefineEOL ) sHead.append(RTL_CONSTASCII_STRINGPARAM("\\\n\t")); sHead.append(sSpace); switch ( nT ) { case LIST_STRING: sHead.append(RTL_CONSTASCII_STRINGPARAM("StringList ")); break; case LIST_FILTER: sHead.append(RTL_CONSTASCII_STRINGPARAM("FilterList ")); break; case LIST_ITEM: sHead.append(RTL_CONSTASCII_STRINGPARAM("ItemList ")); break; case LIST_PAIRED: sHead.append(RTL_CONSTASCII_STRINGPARAM("PairedList ")); break; case LIST_UIENTRIES: sHead.append(RTL_CONSTASCII_STRINGPARAM("UIEntries ")); break; } sHead.append(RTL_CONSTASCII_STRINGPARAM("[ ")); sHead.append(sCur); sHead.append(RTL_CONSTASCII_STRINGPARAM(" ] ")); //} if ( bDefine || bNextMustBeDefineEOL ) { sHead.append(RTL_CONSTASCII_STRINGPARAM("= \\\n")); sHead.append(sSpace); sHead.append(RTL_CONSTASCII_STRINGPARAM("\t{\\\n\t")); } else { sHead.append(RTL_CONSTASCII_STRINGPARAM("= \n")); sHead.append(sSpace); sHead.append(RTL_CONSTASCII_STRINGPARAM("\t{\n\t")); } WriteToMerged(sHead.makeStringAndClear() , true); } rtl::OString sLine; if ( pList && (*pList)[ nLIndex ] ) sLine = ( *(*pList)[ nLIndex ])[ SOURCE_LANGUAGE ]; if ( sLine.isEmpty()) sLine = sLastListLine; if ( sLastListLine.indexOf( '<' ) != -1 ) { if (( nT != LIST_UIENTRIES ) && (( sLine.indexOf( '{' ) == -1 ) || ( sLine.indexOf( '{' ) >= sLine.indexOf( '"' ))) && (( sLine.indexOf( '<' ) == -1 ) || ( sLine.indexOf( '<' ) >= sLine.indexOf( '"' )))) { sLine = sLine.replaceFirst("\"", "< \"" ); } } sal_Int32 nStart, nEnd; nStart = sLine.indexOf( '"' ); rtl::OString sPostFix; if( !bPairedList ){ nEnd = sLine.lastIndexOf( '"' ); sPostFix = sLine.copy( ++nEnd ); sLine = sLine.copy(0, nStart); } ConvertMergeContent( sText ); // merge new res. in text line if( bPairedList ){ sLine = MergePairedList( sLine , sText ); } else{ sLine += sText; sLine += sPostFix; } rtl::OString sText1( "\t" ); sText1 += sLine; if ( bDefine || bNextMustBeDefineEOL ) sText1 += " ;\\\n"; else sText1 += " ;\n"; sText1 += sSpace; sText1 += "\t"; WriteToMerged( sText1 ,true ); // Set matching pairedlist identifier if ( bPairedList ){ nIdx++; ExportListEntry* pListE = ( ExportListEntry* )(*pResData->pPairedList)[ ( nIdx ) -1 ]; if( pListE ){ pResData->sId = GetPairedListID ( (*pListE)[ SOURCE_LANGUAGE ] ); } } else pResData->sId = rtl::OString::valueOf(static_cast(++nIdx)); } else break; nLIndex ++; PFormEntrys *oldEntry = pEntrys; pEntrys = pMergeDataFile->GetPFormEntrys( pResData ); if( !pEntrys ) pEntrys = oldEntry; } if ( nIdx > 1 ) { rtl::OString sFooter; if (!sSpace.isEmpty()) { sFooter = sSpace.copy(1); } if ( bNextMustBeDefineEOL ) sFooter += "};"; else if ( !bDefine ) sFooter += "};\n\t"; else sFooter += "\n\n"; WriteToMerged( sFooter ,true ); } } } pResData->sId = sOldId; pResData->sGId = sOldGId; pResData->sResTyp = sOldTyp; } } break; case MERGE_MODE_LIST : { ExportList *pList = NULL; switch ( nList ) { // PairedList case LIST_STRING : pList = pResData->pStringList; break; case LIST_FILTER : pList = pResData->pFilterList; break; case LIST_UIENTRIES : pList = pResData->pUIEntries; break; case LIST_ITEM : pList = pResData->pItemList; break; case LIST_PAIRED : pList = pResData->pPairedList; break; } nListIndex++; std::size_t nMaxIndex = 0; if ( pList ) nMaxIndex = pList->GetSourceLanguageListEntryCount(); rtl::OString sLine; if ( pList && (*pList)[ nListIndex ] ) sLine = ( *(*pList)[ nListIndex ])[ SOURCE_LANGUAGE ]; if ( sLine.isEmpty()) sLine = sLastListLine; if ( sLastListLine.indexOf( '<' ) != -1 ) { if (( nList != LIST_UIENTRIES ) && (( sLine.indexOf( '{' ) == -1 ) || ( sLine.indexOf( '{' ) >= sLine.indexOf( '"' ))) && (( sLine.indexOf( '<' ) == -1 ) || ( sLine.indexOf( '<' ) >= sLine.indexOf( '"' )))) { sLine = sLine.replaceFirst("\"", "< \""); } } while( PrepareTextToMerge( sLine, nList, m_sListLang, pResData ) && ( nListIndex <= nMaxIndex )) { rtl::OString sText( "\t" ); sText += sLine; sText += " ;"; sText += "\n"; for ( sal_uInt16 i = 0; i < nLevel; i++ ) sText += "\t"; WriteToMerged( sText ,false ); nListIndex++; if ( pList && (*pList)[ nListIndex ]) sLine = ( *(*pList)[ nListIndex ])[ SOURCE_LANGUAGE ]; if ( sLine.isEmpty()) sLine = sLastListLine; sLine += " ;"; } } break; } pParseQueue->bMflag = false; } rtl::OString Export::MergePairedList( rtl::OString const & sLine , rtl::OString const & sText ){ // < "xy" ; IDENTIFIER ; > rtl::OString sPre = sLine.copy( 0 , sLine.indexOf('"') ); rtl::OString sPost = sLine.copy( sLine.lastIndexOf('"') + 1 ); sPre += sText; sPre += sPost; return sPre; } /*****************************************************************************/ void Export::SetChildWithText() /*****************************************************************************/ { if ( aResStack.size() > 1 ) { for ( size_t i = 0; i < aResStack.size() - 1; i++ ) { aResStack[ i ]->bChildWithText = sal_True; } } } void ParserQueue::Push( const QueueEntry& aEntry ) { sal_Int32 nLen = aEntry.sLine.getLength(); if( !bStart ){ aQueueCur->push( aEntry ); if( nLen > 1 && aEntry.sLine[nLen-1] == '\n' ) bStart = true; else if ( aEntry.nTyp != IGNOREDTOKENS ){ if( nLen > 1 && ( aEntry.sLine[nLen-1] == '\\') ){ // Next is Macro bCurrentIsM = true; }else{ // Next is no Macro bCurrentIsM = false; } } } else{ aQueueNext->push( aEntry ); if( nLen > 1 && aEntry.sLine[nLen-1] != '\n' ){ if( nLen > 1 && ( aEntry.sLine[nLen-1] == '\\') ){ // Next is Macro bNextIsM = true; } else{ // Next is no Macro bNextIsM = false; } }else if( nLen > 2 && aEntry.sLine[nLen-1] == '\n' ){ if( aEntry.nTyp != IGNOREDTOKENS ){ if( nLen > 2 && ( aEntry.sLine[nLen-2] == '\\') ){ // Next is Macro bNextIsM = true; } else{ // Next is no Macro bNextIsM = false; } } // Pop current Pop( *aQueueCur ); bLastWasM = bCurrentIsM; // next -> current bCurrentIsM = bNextIsM; aQref = aQueueCur; aQueueCur = aQueueNext; aQueueNext = aQref; } else{ // Pop current Pop( *aQueueCur ); bLastWasM = bCurrentIsM; // next -> current bCurrentIsM = bNextIsM; aQref = aQueueCur; aQueueCur = aQueueNext; aQueueNext = aQref; } } } void ParserQueue::Close(){ // Pop current Pop( *aQueueCur ); // next -> current bLastWasM = bCurrentIsM; bCurrentIsM = bNextIsM; aQref = aQueueCur; aQueueCur = aQueueNext; aQueueNext = aQref; bNextIsM = false; Pop( *aQueueNext ); }; void ParserQueue::Pop( std::queue& aQueue ) { while (!aQueue.empty()) { QueueEntry aEntry = aQueue.front(); aQueue.pop(); aExport.Execute(aEntry.nTyp, aEntry.sLine.getStr()); } } ParserQueue::ParserQueue( Export& aExportObj ) : bCurrentIsM( false ), bNextIsM( false ) , bLastWasM( false ), bMflag( false ) , aExport( aExportObj ) , bStart( false ) , bStartNext( false ) { aQueueNext = new std::queue; aQueueCur = new std::queue; } ParserQueue::~ParserQueue(){ if( aQueueNext ) delete aQueueNext; if( aQueueCur ) delete aQueueCur; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */