LCOV - code coverage report
Current view: top level - l10ntools/source - gsicheck.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 545 0.0 %
Date: 2012-08-25 Functions: 0 30 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "sal/config.h"
      30                 :            : 
      31                 :            : #include <algorithm>
      32                 :            : #include <cassert>
      33                 :            : #include <cstddef>
      34                 :            : #include <fstream>
      35                 :            : #include <string>
      36                 :            : 
      37                 :            : #include <stdio.h>
      38                 :            : 
      39                 :            : #include <rtl/strbuf.hxx>
      40                 :            : #include "sal/main.h"
      41                 :            : #include "helper.hxx"
      42                 :            : #include "tagtest.hxx"
      43                 :            : #include "gsicheck.hxx"
      44                 :            : 
      45                 :            : namespace {
      46                 :            : 
      47                 :            : sal_Int32 const MAX_GID_LID_LEN = 250;
      48                 :            : 
      49                 :          0 : rtl::OString copyUpTo(
      50                 :            :     rtl::OString const & text, sal_Int32 start, sal_Int32 maximumLength)
      51                 :            : {
      52                 :            :     assert(start >= 0 && start <= text.getLength());
      53                 :          0 :     return text.copy(start, std::min(text.getLength() - start, maximumLength));
      54                 :            : }
      55                 :            : 
      56                 :          0 : rtl::OString addSuffix(
      57                 :            :     rtl::OString const & pathname, rtl::OString const & suffix)
      58                 :            : {
      59                 :          0 :     sal_Int32 n = pathname.lastIndexOf('.');
      60                 :          0 :     if (n == -1) {
      61                 :            :         fprintf(
      62                 :            :             stderr,
      63                 :            :             ("Error: pathname \"%s\" does not contain dot to add suffix in"
      64                 :            :              " front of\n"),
      65                 :          0 :             pathname.getStr());
      66                 :          0 :         exit(EXIT_FAILURE);
      67                 :            :     }
      68                 :          0 :     return pathname.replaceAt(n, 0, suffix);
      69                 :            : }
      70                 :            : 
      71                 :            : }
      72                 :            : 
      73                 :            : /*****************************************************************************/
      74                 :          0 : void PrintMessage( rtl::OString const & aType, rtl::OString const & aMsg, rtl::OString const & aPrefix,
      75                 :            :                    rtl::OString const & aContext, sal_Bool bPrintContext, std::size_t nLine, rtl::OString aUniqueId = rtl::OString() )
      76                 :            : /*****************************************************************************/
      77                 :            : {
      78                 :          0 :     fprintf( stdout, "%s %s, Line %u", aType.getStr(), aPrefix.getStr(), static_cast<unsigned>( nLine ) );
      79                 :          0 :     if ( !aUniqueId.isEmpty() )
      80                 :          0 :         fprintf( stdout, ", UniqueID %s", aUniqueId.getStr() );
      81                 :          0 :     fprintf( stdout, ": %s", aMsg.getStr() );
      82                 :            : 
      83                 :          0 :     if ( bPrintContext )
      84                 :          0 :         fprintf( stdout, "  \"%s\"", aContext.getStr() );
      85                 :          0 :     fprintf( stdout, "\n" );
      86                 :          0 : }
      87                 :            : 
      88                 :            : /*****************************************************************************/
      89                 :          0 : void PrintError( rtl::OString const & aMsg, rtl::OString const & aPrefix,
      90                 :            :                  rtl::OString const & aContext, sal_Bool bPrintContext, std::size_t nLine, rtl::OString const & aUniqueId = rtl::OString() )
      91                 :            : /*****************************************************************************/
      92                 :            : {
      93                 :          0 :     PrintMessage( "Error:", aMsg, aPrefix, aContext, bPrintContext, nLine, aUniqueId );
      94                 :          0 : }
      95                 :            : 
      96                 :          0 : bool LanguageOK( rtl::OString const & aLang )
      97                 :            : {
      98                 :          0 :     sal_Int32 n = 0;
      99                 :          0 :     rtl::OString t0(aLang.getToken(0, '-', n));
     100                 :          0 :     if (n == -1) {
     101                 :          0 :         return !t0.isEmpty()
     102                 :          0 :             && (helper::isAllAsciiDigits(t0)
     103                 :          0 :                 || helper::isAllAsciiLowerCase(t0));
     104                 :            :     }
     105                 :          0 :     rtl::OString t1(aLang.getToken(0, '-', n));
     106                 :            :     return n == -1
     107                 :          0 :         && !t0.isEmpty() && helper::isAllAsciiLowerCase(t0)
     108                 :          0 :         && !t1.isEmpty() && helper::isAllAsciiUpperCase(t1)
     109                 :          0 :         && !t0.equalsIgnoreAsciiCase(t1);
     110                 :            : }
     111                 :            : 
     112                 :          0 : class LazyStream: public std::ofstream
     113                 :            : {
     114                 :            : 
     115                 :            : private:
     116                 :            :     rtl::OString aFileName;
     117                 :            :     bool bOpened;
     118                 :            : 
     119                 :            : public:
     120                 :          0 :     LazyStream()
     121                 :            :     : aFileName()
     122                 :          0 :     , bOpened(false)
     123                 :          0 :     {};
     124                 :            : 
     125                 :          0 :     void SetFileName( const rtl::OString& rFileName )
     126                 :            :     {
     127                 :          0 :         aFileName = rFileName;
     128                 :          0 :     };
     129                 :            : 
     130                 :            :     void LazyOpen();
     131                 :            : };
     132                 :            : 
     133                 :          0 : void LazyStream::LazyOpen()
     134                 :            : {
     135                 :          0 :     if ( !bOpened )
     136                 :            :     {
     137                 :          0 :         open(aFileName.getStr(), std::ios_base::out | std::ios_base::trunc);
     138                 :          0 :         if (!is_open())
     139                 :            :         {
     140                 :            :             fprintf( stderr, "\nERROR: Could not open Output-File %s!\n\n",
     141                 :          0 :                      aFileName.getStr() );
     142                 :          0 :             exit ( 4 );
     143                 :            :         }
     144                 :          0 :         bOpened = true;
     145                 :            :     }
     146                 :          0 : }
     147                 :            : 
     148                 :            : 
     149                 :            : //
     150                 :            : // class GSILine
     151                 :            : //
     152                 :            : 
     153                 :            : /*****************************************************************************/
     154                 :          0 : GSILine::GSILine( const rtl::OString &rLine, std::size_t nLine )
     155                 :            : /*****************************************************************************/
     156                 :            :                 : nLineNumber( nLine )
     157                 :            :                 , bOK( sal_True )
     158                 :            :                 , bFixed ( sal_False )
     159                 :          0 :                 , data_( rLine )
     160                 :            : {
     161                 :          0 :     if (rLine.isEmpty()) {
     162                 :          0 :         NotOK();
     163                 :            :         return;
     164                 :            :     }
     165                 :            : 
     166                 :          0 :     aFormat = FORMAT_SDF;
     167                 :          0 :     sal_Int32 n = 0;
     168                 :          0 :     aUniqId = rLine.getToken(0, '\t', n); // token 0
     169                 :          0 :     aUniqId += "/";
     170                 :          0 :     aUniqId += rLine.getToken(0, '\t', n); // token 1
     171                 :          0 :     aUniqId += "/";
     172                 :          0 :     aUniqId += rLine.getToken(1, '\t', n); // token 3
     173                 :          0 :     aUniqId += "/";
     174                 :          0 :     rtl::OString gid(rLine.getToken(0, '\t', n)); // token 4
     175                 :          0 :     aUniqId += gid;
     176                 :          0 :     aUniqId += "/";
     177                 :          0 :     rtl::OString lid(rLine.getToken(0, '\t', n)); // token 5
     178                 :          0 :     aUniqId += lid;
     179                 :          0 :     aUniqId += "/";
     180                 :          0 :     aUniqId += rLine.getToken(0, '\t', n); // token 6
     181                 :          0 :     aUniqId += "/";
     182                 :          0 :     aUniqId += rLine.getToken(0, '\t', n); // token 7
     183                 :          0 :     rtl::OString length(rLine.getToken(0, '\t', n)); // token 8
     184                 :          0 :     aLineType = rtl::OString();
     185                 :          0 :     aLangId = rLine.getToken(0, '\t', n); // token 9
     186                 :          0 :     aText = rLine.getToken(0, '\t', n); // token 10
     187                 :          0 :     aQuickHelpText = rLine.getToken(1, '\t', n); // token 12
     188                 :          0 :     aTitle = rLine.getToken(0, '\t', n); // token 13
     189                 :          0 :     if (n == -1) {
     190                 :          0 :         NotOK();
     191                 :            :         return;
     192                 :            :     }
     193                 :          0 :     rLine.getToken(0, '\t', n); // token 14
     194                 :          0 :     if (n != -1) {
     195                 :          0 :         NotOK();
     196                 :            :         return;
     197                 :            :     }
     198                 :            : 
     199                 :            :     // do some more format checks here
     200                 :          0 :     if (!helper::isAllAsciiDigits(length)) {
     201                 :            :         PrintError(
     202                 :            :             "The length field does not contain a number!", "Line format",
     203                 :          0 :             length, true, GetLineNumber(), GetUniqId());
     204                 :          0 :         NotOK();
     205                 :            :     }
     206                 :          0 :     if (!LanguageOK(aLangId)) {
     207                 :            :         PrintError(
     208                 :            :             "The Language is invalid!", "Line format", aLangId, true,
     209                 :          0 :             GetLineNumber(), GetUniqId());
     210                 :          0 :         NotOK();
     211                 :            :     }
     212                 :            :     // Limit GID and LID to MAX_GID_LID_LEN chars each for database conformity,
     213                 :            :     // see #137575#:
     214                 :          0 :     if (gid.getLength() > MAX_GID_LID_LEN || lid.getLength() > MAX_GID_LID_LEN)
     215                 :            :     {
     216                 :            :         PrintError(
     217                 :            :             (rtl::OString(
     218                 :            :                 RTL_CONSTASCII_STRINGPARAM("GID and LID may only be "))
     219                 :            :              + rtl::OString::valueOf(MAX_GID_LID_LEN)
     220                 :            :              + rtl::OString(RTL_CONSTASCII_STRINGPARAM(" chars long each"))),
     221                 :          0 :             "Line format", aLangId, true, GetLineNumber(), GetUniqId());
     222                 :          0 :         NotOK();
     223                 :          0 :     }
     224                 :            : }
     225                 :            : 
     226                 :            : /*****************************************************************************/
     227                 :          0 : void GSILine::NotOK()
     228                 :            : /*****************************************************************************/
     229                 :            : {
     230                 :          0 :     bOK = sal_False;
     231                 :          0 : }
     232                 :            : 
     233                 :            : /*****************************************************************************/
     234                 :          0 : void GSILine::ReassembleLine()
     235                 :            : /*****************************************************************************/
     236                 :            : {
     237                 :          0 :     if (GetLineFormat() != FORMAT_SDF) {
     238                 :            :         PrintError(
     239                 :            :             "Cannot reassemble line of unknown type (internal Error).",
     240                 :            :             "Line format", rtl::OString(), false, GetLineNumber(),
     241                 :          0 :             GetUniqId());
     242                 :          0 :         return;
     243                 :            :     }
     244                 :          0 :     rtl::OStringBuffer b;
     245                 :          0 :     sal_Int32 n = 0;
     246                 :          0 :     for (sal_Int32 i = 0; i != 10; ++i) {
     247                 :          0 :         b.append(data_.getToken(0, '\t', n)); // token 0--9
     248                 :          0 :         b.append('\t');
     249                 :            :     }
     250                 :          0 :     b.append(aText);
     251                 :          0 :     b.append('\t');
     252                 :          0 :     b.append(data_.getToken(1, '\t', n));
     253                 :            :         // token 11; should be empty but there are some places in sc not
     254                 :            :         // reflected to sources
     255                 :          0 :     b.append('\t');
     256                 :          0 :     b.append(aQuickHelpText);
     257                 :          0 :     b.append('\t');
     258                 :          0 :     b.append(aTitle);
     259                 :          0 :     b.append('\t');
     260                 :          0 :     b.append(data_.getToken(2, '\t', n)); // token 14
     261                 :          0 :     data_ = b.makeStringAndClear();
     262                 :            : }
     263                 :            : 
     264                 :            : //
     265                 :            : // class GSIBlock
     266                 :            : //
     267                 :            : /*****************************************************************************/
     268                 :          0 : GSIBlock::GSIBlock( sal_Bool PbPrintContext, sal_Bool bSource, sal_Bool bTrans, sal_Bool bRef, sal_Bool bAllowSusp )
     269                 :            : /*****************************************************************************/
     270                 :            :             : pSourceLine( NULL )
     271                 :            :             , pReferenceLine( NULL )
     272                 :            :             , bPrintContext( PbPrintContext )
     273                 :            :             , bCheckSourceLang( bSource )
     274                 :            :             , bCheckTranslationLang( bTrans )
     275                 :            :             , bReference( bRef )
     276                 :            :             , bAllowSuspicious( bAllowSusp )
     277                 :          0 :             , bHasBlockError( sal_False )
     278                 :            : {
     279                 :          0 : }
     280                 :            : 
     281                 :            : /*****************************************************************************/
     282                 :          0 : GSIBlock::~GSIBlock()
     283                 :            : /*****************************************************************************/
     284                 :            : {
     285                 :          0 :     delete pSourceLine;
     286                 :          0 :     delete pReferenceLine;
     287                 :            : 
     288                 :          0 :     for ( size_t i = 0, n = maList.size(); i < n; ++i )
     289                 :          0 :         delete maList[ i ];
     290                 :          0 :     maList.clear();
     291                 :          0 : }
     292                 :            : 
     293                 :          0 : void GSIBlock::InsertLine( GSILine* pLine, const rtl::OString &rSourceLang)
     294                 :            : {
     295                 :          0 :     if ( pLine->GetLanguageId() == rSourceLang )
     296                 :            :     {
     297                 :          0 :         if ( pSourceLine )
     298                 :            :         {
     299                 :          0 :             PrintError( "Source Language entry double. Treating as Translation.", "File format", "", pLine->GetLineNumber(), pLine->GetUniqId() );
     300                 :          0 :             bHasBlockError = sal_True;
     301                 :          0 :             pSourceLine->NotOK();
     302                 :          0 :             pLine->NotOK();
     303                 :            :         }
     304                 :            :         else
     305                 :            :         {
     306                 :          0 :             pSourceLine = pLine;
     307                 :          0 :             return;
     308                 :            :         }
     309                 :            :     }
     310                 :            : 
     311                 :          0 :     if (!rSourceLang.isEmpty()) // only check blockstructure if source lang is given
     312                 :            :     {
     313                 :          0 :         for ( size_t nPos = 0, n = maList.size(); nPos < n; ++nPos )
     314                 :            :         {
     315                 :          0 :             if ( maList[ nPos ]->GetLanguageId() == pLine->GetLanguageId() )
     316                 :            :             {
     317                 :          0 :                 PrintError( "Translation Language entry double. Checking both.", "File format", "", pLine->GetLineNumber(), pLine->GetUniqId() );
     318                 :          0 :                 bHasBlockError = sal_True;
     319                 :          0 :                 maList[ nPos ]->NotOK();
     320                 :          0 :                 pLine->NotOK();
     321                 :            :             }
     322                 :          0 :             nPos++;
     323                 :            :         }
     324                 :            :     }
     325                 :          0 :     maList.push_back( pLine );
     326                 :            : }
     327                 :            : 
     328                 :            : /*****************************************************************************/
     329                 :          0 : void GSIBlock::SetReferenceLine( GSILine* pLine )
     330                 :            : /*****************************************************************************/
     331                 :            : {
     332                 :          0 :     pReferenceLine = pLine;
     333                 :          0 : }
     334                 :            : 
     335                 :            : /*****************************************************************************/
     336                 :          0 : void GSIBlock::PrintMessage( rtl::OString const & aType, rtl::OString const & aMsg, rtl::OString const & aPrefix,
     337                 :            :                              rtl::OString const & aContext, std::size_t nLine, rtl::OString const & aUniqueId )
     338                 :            : /*****************************************************************************/
     339                 :            : {
     340                 :          0 :     ::PrintMessage( aType, aMsg, aPrefix, aContext, bPrintContext, nLine, aUniqueId );
     341                 :          0 : }
     342                 :            : 
     343                 :            : /*****************************************************************************/
     344                 :          0 : void GSIBlock::PrintError( rtl::OString const & aMsg, rtl::OString const & aPrefix,
     345                 :            :                            rtl::OString const & aContext, std::size_t nLine, rtl::OString const & aUniqueId )
     346                 :            : /*****************************************************************************/
     347                 :            : {
     348                 :          0 :     PrintMessage( "Error:", aMsg, aPrefix, aContext, nLine, aUniqueId );
     349                 :          0 : }
     350                 :            : 
     351                 :            : /*****************************************************************************/
     352                 :          0 : void GSIBlock::PrintList( ParserMessageList *pList, rtl::OString const & aPrefix,
     353                 :            :     GSILine *pLine )
     354                 :            : /*****************************************************************************/
     355                 :            : {
     356                 :          0 :     for ( size_t i = 0 ; i < pList->size() ; i++ )
     357                 :            :     {
     358                 :          0 :         ParserMessage *pMsg = (*pList)[ i ];
     359                 :          0 :         rtl::OString aContext;
     360                 :          0 :         if ( bPrintContext )
     361                 :            :         {
     362                 :          0 :             if ( pMsg->GetTagBegin() == -1 )
     363                 :          0 :                 aContext = pLine->GetText().copy( 0, 300 );
     364                 :            :             else
     365                 :          0 :                 aContext = helper::abbreviate( pLine->data_, pMsg->GetTagBegin()-150, 300 );
     366                 :          0 :             aContext = aContext.trim();
     367                 :            :         }
     368                 :            : 
     369                 :          0 :         PrintMessage( pMsg->Prefix(), pMsg->GetErrorText(), aPrefix, aContext, pLine->GetLineNumber(), pLine->GetUniqId() );
     370                 :          0 :     }
     371                 :          0 : }
     372                 :            : 
     373                 :            : /*****************************************************************************/
     374                 :          0 : sal_Bool GSIBlock::IsUTF8( const rtl::OString &aTestee, sal_Bool bFixTags, sal_Int32 &nErrorPos, rtl::OString &aErrorMsg, sal_Bool &bHasBeenFixed, rtl::OString &aFixed ) const
     375                 :            : /*****************************************************************************/
     376                 :            : {
     377                 :            :     rtl::OUString aUTF8Tester(
     378                 :          0 :         rtl::OStringToOUString(aTestee, RTL_TEXTENCODING_UTF8));
     379                 :            :     rtl::OString aTestee2(
     380                 :          0 :         rtl::OUStringToOString(aUTF8Tester, RTL_TEXTENCODING_UTF8));
     381                 :          0 :     sal_Int32 i = 0;
     382                 :          0 :     while (i != std::min(aTestee.getLength(), aTestee2.getLength())
     383                 :          0 :            && aTestee[i] == aTestee2[i])
     384                 :            :     {
     385                 :          0 :         ++i;
     386                 :            :     }
     387                 :          0 :     if (i != aTestee.getLength() || i != aTestee2.getLength())
     388                 :            :     {
     389                 :          0 :         aUTF8Tester = rtl::OUString(aTestee.getStr(), i, RTL_TEXTENCODING_UTF8);
     390                 :          0 :         nErrorPos = aUTF8Tester.getLength();
     391                 :          0 :         aErrorMsg = "UTF8 Encoding seems to be broken";
     392                 :          0 :         return sal_False;
     393                 :            :     }
     394                 :            : 
     395                 :            :     nErrorPos = helper::indexOfAnyAsciiL(
     396                 :            :         aUTF8Tester,
     397                 :            :         RTL_CONSTASCII_STRINGPARAM(
     398                 :            :             "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12"
     399                 :          0 :             "\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"));
     400                 :          0 :     if (nErrorPos != -1)
     401                 :            :     {
     402                 :          0 :         aErrorMsg = "String contains illegal character";
     403                 :          0 :         return sal_False;
     404                 :            :     }
     405                 :            : 
     406                 :          0 :     if ( bFixTags )
     407                 :            :     {
     408                 :          0 :         bHasBeenFixed = sal_False;
     409                 :          0 :         aFixed = rtl::OString();
     410                 :            :     }
     411                 :            : 
     412                 :          0 :     return sal_True;
     413                 :            : }
     414                 :            : 
     415                 :            : /*****************************************************************************/
     416                 :          0 : sal_Bool GSIBlock::TestUTF8( GSILine* pTestee, sal_Bool bFixTags )
     417                 :            : /*****************************************************************************/
     418                 :            : {
     419                 :          0 :     sal_Int32 nErrorPos = 0;
     420                 :          0 :     rtl::OString aErrorMsg;
     421                 :          0 :     sal_Bool bError = sal_False;
     422                 :          0 :     rtl::OString aFixed;
     423                 :          0 :     sal_Bool bHasBeenFixed = sal_False;
     424                 :          0 :     if ( !IsUTF8( pTestee->GetText(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) )
     425                 :            :     {
     426                 :          0 :         rtl::OString aContext(copyUpTo(pTestee->GetText(), nErrorPos, 20));
     427                 :          0 :         PrintError(rtl::OStringBuffer(aErrorMsg).append(RTL_CONSTASCII_STRINGPARAM(" in Text at Position "))
     428                 :          0 :              .append(nErrorPos).getStr(),
     429                 :          0 :             "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId());
     430                 :          0 :         bError = sal_True;
     431                 :          0 :         if ( bHasBeenFixed )
     432                 :            :         {
     433                 :          0 :             pTestee->SetText( aFixed );
     434                 :          0 :             pTestee->SetFixed();
     435                 :          0 :         }
     436                 :            :     }
     437                 :          0 :     if ( !IsUTF8( pTestee->GetQuickHelpText(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) )
     438                 :            :     {
     439                 :            :         rtl::OString aContext(
     440                 :          0 :             copyUpTo(pTestee->GetQuickHelpText(), nErrorPos, 20));
     441                 :          0 :         PrintError(rtl::OStringBuffer(aErrorMsg).append(RTL_CONSTASCII_STRINGPARAM(" in QuickHelpText at Position "))
     442                 :          0 :              .append(nErrorPos).getStr(),
     443                 :          0 :             "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId());
     444                 :          0 :         bError = sal_True;
     445                 :          0 :         if ( bHasBeenFixed )
     446                 :            :         {
     447                 :          0 :             pTestee->SetQuickHelpText( aFixed );
     448                 :          0 :             pTestee->SetFixed();
     449                 :          0 :         }
     450                 :            :     }
     451                 :          0 :     if ( !IsUTF8( pTestee->GetTitle(), bFixTags, nErrorPos, aErrorMsg, bHasBeenFixed, aFixed ) )
     452                 :            :     {
     453                 :          0 :         rtl::OString aContext( pTestee->GetTitle().copy( nErrorPos, 20 ) );
     454                 :          0 :         PrintError(rtl::OStringBuffer(aErrorMsg).append(RTL_CONSTASCII_STRINGPARAM(" in Title at Position "))
     455                 :          0 :              .append(nErrorPos).getStr(),
     456                 :          0 :             "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId());
     457                 :          0 :         bError = sal_True;
     458                 :          0 :         if ( bHasBeenFixed )
     459                 :            :         {
     460                 :          0 :             pTestee->SetTitle( aFixed );
     461                 :          0 :             pTestee->SetFixed();
     462                 :          0 :         }
     463                 :            :     }
     464                 :          0 :     if ( bError )
     465                 :          0 :         pTestee->NotOK();
     466                 :          0 :     return !bError;
     467                 :            : }
     468                 :            : 
     469                 :            : 
     470                 :            : /*****************************************************************************/
     471                 :          0 : sal_Bool GSIBlock::HasSuspiciousChars( GSILine* pTestee, GSILine* pSource )
     472                 :            : /*****************************************************************************/
     473                 :            : {
     474                 :          0 :     sal_Int32 nPos = 0;
     475                 :          0 :     if ( !bAllowSuspicious && ( nPos = pTestee->GetText().indexOf("??")) != -1 )
     476                 :          0 :         if ( pSource->GetText().indexOf("??") == -1 )
     477                 :            :         {
     478                 :            :             rtl::OUString aUTF8Tester(
     479                 :            :                 rtl::OStringToOUString(
     480                 :          0 :                     pTestee->GetText().copy(0, nPos), RTL_TEXTENCODING_UTF8));
     481                 :          0 :             sal_Int32 nErrorPos = aUTF8Tester.getLength();
     482                 :          0 :             rtl::OString aContext( helper::abbreviate( pTestee->GetText(), nPos, 20 ) );
     483                 :            :             PrintError(rtl::OStringBuffer(RTL_CONSTASCII_STRINGPARAM("Found double questionmark in translation only. Looks like an encoding problem at Position "))
     484                 :          0 :                  .append(nErrorPos).getStr(),
     485                 :          0 :                 "Text format", aContext, pTestee->GetLineNumber(), pTestee->GetUniqId());
     486                 :          0 :             pTestee->NotOK();
     487                 :          0 :             return sal_True;
     488                 :            :         }
     489                 :            : 
     490                 :          0 :     return sal_False;
     491                 :            : }
     492                 :            : 
     493                 :            : 
     494                 :            : /*****************************************************************************/
     495                 :          0 : sal_Bool GSIBlock::CheckSyntax( std::size_t nLine, sal_Bool bRequireSourceLine, sal_Bool bFixTags )
     496                 :            : /*****************************************************************************/
     497                 :            : {
     498                 :          0 :     static LingTest aTester;
     499                 :          0 :     sal_Bool bHasError = sal_False;
     500                 :            : 
     501                 :          0 :     if ( !pSourceLine )
     502                 :            :     {
     503                 :          0 :         if ( bRequireSourceLine )
     504                 :            :         {
     505                 :          0 :             PrintError( "No source language entry defined!", "File format", "", nLine );
     506                 :          0 :             bHasBlockError = sal_True;
     507                 :            :         }
     508                 :            :     }
     509                 :            :     else
     510                 :            :     {
     511                 :          0 :         aTester.CheckReference( pSourceLine );
     512                 :          0 :         if ( pSourceLine->HasMessages() )
     513                 :            :         {
     514                 :          0 :             PrintList( pSourceLine->GetMessageList(), "ReferenceString", pSourceLine );
     515                 :          0 :             pSourceLine->NotOK();
     516                 :          0 :             bHasError = sal_True;
     517                 :            :         }
     518                 :            :     }
     519                 :          0 :     if ( bReference )
     520                 :            :     {
     521                 :          0 :         if ( !pReferenceLine )
     522                 :            :         {
     523                 :            :             GSILine *pSource;
     524                 :          0 :             if ( pSourceLine )
     525                 :          0 :                 pSource = pSourceLine;
     526                 :            :             else
     527                 :          0 :                 pSource = maList.empty() ? NULL : maList[ 0 ];   // get some other line
     528                 :          0 :             if ( pSource )
     529                 :          0 :                 PrintError( "No reference line found. Entry is new in source file", "File format", "", pSource->GetLineNumber(), pSource->GetUniqId() );
     530                 :            :             else
     531                 :          0 :                 PrintError( "No reference line found. Entry is new in source file", "File format", "", nLine );
     532                 :          0 :             bHasBlockError = sal_True;
     533                 :            :         }
     534                 :            :         else
     535                 :            :         {
     536                 :          0 :             if ( pSourceLine && pSourceLine->data_ != pReferenceLine->data_ )
     537                 :            :             {
     538                 :          0 :                 sal_Int32 nPos = pSourceLine->data_.indexOf( pReferenceLine->data_ );
     539                 :          0 :                 rtl::OStringBuffer aContext( pReferenceLine->data_.copy( nPos - 5, 15) );
     540                 :          0 :                 aContext.append( "\" --> \"" ).append( pSourceLine->data_.copy( nPos - 5, 15) );
     541                 :          0 :                 PrintError( "Source Language Entry has changed.", "File format", aContext.makeStringAndClear(), pSourceLine->GetLineNumber(), pSourceLine->GetUniqId() );
     542                 :          0 :                 pSourceLine->NotOK();
     543                 :          0 :                 bHasError = sal_True;
     544                 :            :             }
     545                 :            :         }
     546                 :            :     }
     547                 :            : 
     548                 :          0 :     if ( pSourceLine )
     549                 :          0 :         bHasError |= !TestUTF8( pSourceLine, bFixTags );
     550                 :            : 
     551                 :          0 :     for ( size_t i = 0, n = maList.size(); i < n; ++i )
     552                 :            :     {
     553                 :          0 :         GSILine* pItem = maList[ i ];
     554                 :          0 :         aTester.CheckTestee( pItem, pSourceLine != NULL, bFixTags );
     555                 :          0 :         if ( pItem->HasMessages() || aTester.HasCompareWarnings() )
     556                 :            :         {
     557                 :          0 :             if ( pItem->HasMessages() || aTester.GetCompareWarnings().HasErrors() )
     558                 :          0 :                 pItem->NotOK();
     559                 :          0 :             bHasError = sal_True;
     560                 :          0 :             PrintList( pItem->GetMessageList(), "Translation", pItem );
     561                 :          0 :             PrintList( &(aTester.GetCompareWarnings()), "Translation Tag Mismatch", pItem );
     562                 :            :         }
     563                 :          0 :         bHasError |= !TestUTF8( pItem, bFixTags );
     564                 :          0 :         if ( pSourceLine )
     565                 :          0 :             bHasError |= HasSuspiciousChars( pItem, pSourceLine );
     566                 :            :     }
     567                 :            : 
     568                 :          0 :     return bHasError || bHasBlockError;
     569                 :            : }
     570                 :            : 
     571                 :          0 : void GSIBlock::WriteError( LazyStream &aErrOut, sal_Bool bRequireSourceLine  )
     572                 :            : {
     573                 :          0 :     if ( pSourceLine && pSourceLine->IsOK() && bCheckSourceLang && !bHasBlockError )
     574                 :          0 :         return;
     575                 :            : 
     576                 :          0 :     sal_Bool bHasError = sal_False;
     577                 :          0 :     sal_Bool bCopyAll = ( !pSourceLine && bRequireSourceLine ) || ( pSourceLine && !pSourceLine->IsOK() && !bCheckTranslationLang ) || bHasBlockError;
     578                 :          0 :     for ( size_t i = 0, n = maList.size(); i < n; ++i )
     579                 :            :     {
     580                 :          0 :         GSILine* pItem = maList[ i ];
     581                 :          0 :         if ( !pItem->IsOK() || bCopyAll )
     582                 :            :         {
     583                 :          0 :             bHasError = sal_True;
     584                 :          0 :             aErrOut.LazyOpen();
     585                 :          0 :             aErrOut << pItem->data_.getStr() << '\n';
     586                 :            :         }
     587                 :            :     }
     588                 :            : 
     589                 :          0 :     if ( pSourceLine && ( bHasError || !pSourceLine->IsOK() ) && !( !bHasError && bCheckTranslationLang ) )
     590                 :            :     {
     591                 :          0 :         aErrOut.LazyOpen();
     592                 :          0 :         aErrOut << pSourceLine->data_.getStr() << '\n';
     593                 :            :     }
     594                 :            : }
     595                 :            : 
     596                 :          0 : void GSIBlock::WriteCorrect( LazyStream &aOkOut, sal_Bool bRequireSourceLine )
     597                 :            : {
     598                 :          0 :     if ( ( !pSourceLine && bRequireSourceLine ) || ( pSourceLine && !pSourceLine->IsOK() && !bCheckTranslationLang ) )
     599                 :          0 :         return;
     600                 :            : 
     601                 :          0 :     sal_Bool bHasOK = sal_False;
     602                 :          0 :     for ( size_t i = 0, n = maList.size(); i < n; ++i )
     603                 :            :     {
     604                 :          0 :         GSILine* pItem = maList[ i ];
     605                 :          0 :         if ( ( pItem->IsOK() || bCheckSourceLang ) && !bHasBlockError )
     606                 :            :         {
     607                 :          0 :             bHasOK = sal_True;
     608                 :          0 :             aOkOut.LazyOpen();
     609                 :          0 :             aOkOut << pItem->data_.getStr() << '\n';
     610                 :            :         }
     611                 :            :     }
     612                 :            : 
     613                 :          0 :     if ( ( pSourceLine && pSourceLine->IsOK() && ( !maList.empty() || !bCheckTranslationLang ) ) || ( bHasOK && bCheckTranslationLang ) )
     614                 :            :     {
     615                 :          0 :         aOkOut.LazyOpen();
     616                 :          0 :         aOkOut << pSourceLine->data_.getStr() << '\n';
     617                 :            :     }
     618                 :            : }
     619                 :            : 
     620                 :          0 : void GSIBlock::WriteFixed( LazyStream &aFixOut )
     621                 :            : {
     622                 :          0 :     if ( pSourceLine && !pSourceLine->IsFixed() && bCheckSourceLang )
     623                 :          0 :         return;
     624                 :            : 
     625                 :          0 :     sal_Bool bHasFixes = sal_False;
     626                 :          0 :     for ( size_t i = 0, n = maList.size(); i < n; ++i )
     627                 :            :     {
     628                 :          0 :         GSILine* pItem = maList[ i ];
     629                 :          0 :         if ( pItem->IsFixed() )
     630                 :            :         {
     631                 :          0 :             bHasFixes = sal_True;
     632                 :          0 :             aFixOut.LazyOpen();
     633                 :          0 :             aFixOut << pItem->data_.getStr() << '\n';
     634                 :            :         }
     635                 :            :     }
     636                 :            : 
     637                 :          0 :     if ( pSourceLine && ( bHasFixes || pSourceLine->IsFixed() ) )
     638                 :            :     {
     639                 :          0 :         aFixOut.LazyOpen();
     640                 :          0 :         aFixOut << pSourceLine->data_.getStr() << '\n';
     641                 :            :     }
     642                 :            : }
     643                 :            : 
     644                 :            : /*****************************************************************************/
     645                 :          0 : void Help()
     646                 :            : /*****************************************************************************/
     647                 :            : {
     648                 :          0 :     fprintf( stdout, "\n" );
     649                 :          0 :     fprintf( stdout, "gsicheck checks the syntax of tags in SDF-Files\n" );
     650                 :          0 :     fprintf( stdout, "         checks for inconsistencies and malicious UTF8 encoding\n" );
     651                 :          0 :     fprintf( stdout, "         checks tags in Online Help\n" );
     652                 :            :     fprintf( stdout, "         relax GID/LID length to %s\n",
     653                 :          0 :         rtl::OString::valueOf(static_cast<sal_Int32>(MAX_GID_LID_LEN)).getStr() );
     654                 :          0 :     fprintf( stdout, "\n" );
     655                 :          0 :     fprintf( stdout, "Syntax: gsicheck [ -c ] [-f] [ -we ] [ -wef ErrorFilename ] [ -wc ]\n" );
     656                 :          0 :     fprintf( stdout, "                 [ -wcf CorrectFilename ] [ -s | -t ] [ -l LanguageID ]\n" );
     657                 :          0 :     fprintf( stdout, "                 [ -r ReferenceFile ] filename\n" );
     658                 :          0 :     fprintf( stdout, "\n" );
     659                 :          0 :     fprintf( stdout, "-c    Add context to error message (Print the line containing the error)\n" );
     660                 :          0 :     fprintf( stdout, "-f    try to fix errors. See also -wf -wff \n" );
     661                 :          0 :     fprintf( stdout, "-wf   Write File containing all fixed parts\n" );
     662                 :          0 :     fprintf( stdout, "-wff  Same as above but give own filename\n" );
     663                 :          0 :     fprintf( stdout, "-we   Write File containing all errors\n" );
     664                 :          0 :     fprintf( stdout, "-wef  Same as above but give own filename\n" );
     665                 :          0 :     fprintf( stdout, "-wc   Write File containing all correct parts\n" );
     666                 :          0 :     fprintf( stdout, "-wcf  Same as above but give own filename\n" );
     667                 :          0 :     fprintf( stdout, "-s    Check only source language. Should be used before handing out to vendor.\n" );
     668                 :          0 :     fprintf( stdout, "-t    Check only Translation language(s). Should be used before merging.\n" );
     669                 :          0 :     fprintf( stdout, "-e    disable encoding checks. E.g.: double questionmark \'??\' which may be the\n" );
     670                 :          0 :     fprintf( stdout, "      result of false conversions\n" );
     671                 :          0 :     fprintf( stdout, "-l    ISO language code of the source language.\n" );
     672                 :          0 :     fprintf( stdout, "      Default is en-US. Use \"\" (empty string) or 'none'\n" );
     673                 :          0 :     fprintf( stdout, "      to disable source language dependent checks\n" );
     674                 :          0 :     fprintf( stdout, "-r    Reference filename to check that source language entries\n" );
     675                 :          0 :     fprintf( stdout, "      have not been changed\n" );
     676                 :          0 :        fprintf( stdout, "\n" );
     677                 :          0 : }
     678                 :            : 
     679                 :          0 : SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
     680                 :          0 :     sal_Bool bError = sal_False;
     681                 :          0 :     sal_Bool bPrintContext = sal_False;
     682                 :          0 :     sal_Bool bCheckSourceLang = sal_False;
     683                 :          0 :     sal_Bool bCheckTranslationLang = sal_False;
     684                 :          0 :     sal_Bool bWriteError = sal_False;
     685                 :          0 :     sal_Bool bWriteCorrect = sal_False;
     686                 :          0 :     sal_Bool bWriteFixed = sal_False;
     687                 :          0 :     sal_Bool bFixTags = sal_False;
     688                 :          0 :     sal_Bool bAllowSuspicious = sal_False;
     689                 :          0 :     rtl::OString aErrorFilename;
     690                 :          0 :     rtl::OString aCorrectFilename;
     691                 :          0 :     rtl::OString aFixedFilename;
     692                 :          0 :     sal_Bool bFileHasError = sal_False;
     693                 :          0 :     rtl::OString aSourceLang( "en-US" );     // English is default
     694                 :          0 :     rtl::OString aFilename;
     695                 :          0 :     rtl::OString aReferenceFilename;
     696                 :          0 :     sal_Bool bReferenceFile = sal_False;
     697                 :          0 :     for ( int i = 1 ; i < argc ; i++ )
     698                 :            :     {
     699                 :          0 :         if ( *argv[ i ] == '-' )
     700                 :            :         {
     701                 :          0 :             switch (*(argv[ i ]+1))
     702                 :            :             {
     703                 :          0 :                 case 'c':bPrintContext = sal_True;
     704                 :          0 :                     break;
     705                 :            :                 case 'w':
     706                 :            :                     {
     707                 :          0 :                         if ( (*(argv[ i ]+2)) == 'e' )
     708                 :            :                         {
     709                 :          0 :                             if ( (*(argv[ i ]+3)) == 'f' )
     710                 :          0 :                                 if ( (i+1) < argc )
     711                 :            :                                 {
     712                 :          0 :                                     aErrorFilename = argv[i + 1];
     713                 :          0 :                                     bWriteError = sal_True;
     714                 :          0 :                                     i++;
     715                 :            :                                 }
     716                 :            :                                 else
     717                 :            :                                 {
     718                 :          0 :                                     fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] );
     719                 :          0 :                                     bError = sal_True;
     720                 :            :                                 }
     721                 :            :                             else
     722                 :          0 :                                    bWriteError = sal_True;
     723                 :            :                         }
     724                 :          0 :                         else if ( (*(argv[ i ]+2)) == 'c' )
     725                 :          0 :                             if ( (*(argv[ i ]+3)) == 'f' )
     726                 :          0 :                                 if ( (i+1) < argc )
     727                 :            :                                 {
     728                 :          0 :                                     aCorrectFilename = argv[i + 1];
     729                 :          0 :                                     bWriteCorrect = sal_True;
     730                 :          0 :                                     i++;
     731                 :            :                                 }
     732                 :            :                                 else
     733                 :            :                                 {
     734                 :          0 :                                     fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] );
     735                 :          0 :                                     bError = sal_True;
     736                 :            :                                 }
     737                 :            :                             else
     738                 :          0 :                                    bWriteCorrect = sal_True;
     739                 :          0 :                         else if ( (*(argv[ i ]+2)) == 'f' )
     740                 :          0 :                             if ( (*(argv[ i ]+3)) == 'f' )
     741                 :          0 :                                 if ( (i+1) < argc )
     742                 :            :                                 {
     743                 :          0 :                                     aFixedFilename = argv[i + 1];
     744                 :          0 :                                     bWriteFixed = sal_True;
     745                 :          0 :                                     bFixTags = sal_True;
     746                 :          0 :                                     i++;
     747                 :            :                                 }
     748                 :            :                                 else
     749                 :            :                                 {
     750                 :          0 :                                     fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] );
     751                 :          0 :                                     bError = sal_True;
     752                 :            :                                 }
     753                 :            :                             else
     754                 :            :                             {
     755                 :          0 :                                    bWriteFixed = sal_True;
     756                 :          0 :                                 bFixTags = sal_True;
     757                 :            :                             }
     758                 :            :                         else
     759                 :            :                         {
     760                 :          0 :                             fprintf( stderr, "\nERROR: Unknown Switch %s!\n\n", argv[ i ] );
     761                 :          0 :                             bError = sal_True;
     762                 :            :                         }
     763                 :            :                     }
     764                 :          0 :                     break;
     765                 :          0 :                 case 's':bCheckSourceLang = sal_True;
     766                 :          0 :                     break;
     767                 :          0 :                 case 't':bCheckTranslationLang = sal_True;
     768                 :          0 :                     break;
     769                 :            :                 case 'l':
     770                 :            :                     {
     771                 :          0 :                         if ( (i+1) < argc )
     772                 :            :                         {
     773                 :          0 :                             aSourceLang = argv[ i+1 ];
     774                 :          0 :                             if ( aSourceLang.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("none")) )
     775                 :          0 :                                 aSourceLang = rtl::OString();
     776                 :          0 :                             i++;
     777                 :            :                         }
     778                 :            :                         else
     779                 :            :                         {
     780                 :          0 :                             fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] );
     781                 :          0 :                             bError = sal_True;
     782                 :            :                         }
     783                 :            :                     }
     784                 :          0 :                     break;
     785                 :            :                 case 'r':
     786                 :            :                     {
     787                 :          0 :                         if ( (i+1) < argc )
     788                 :            :                         {
     789                 :          0 :                             aReferenceFilename = argv[ i+1 ];
     790                 :          0 :                             bReferenceFile = sal_True;
     791                 :          0 :                             i++;
     792                 :            :                         }
     793                 :            :                         else
     794                 :            :                         {
     795                 :          0 :                             fprintf( stderr, "\nERROR: Switch %s requires parameter!\n\n", argv[ i ] );
     796                 :          0 :                             bError = sal_True;
     797                 :            :                         }
     798                 :            :                     }
     799                 :          0 :                     break;
     800                 :            :                 case 'f':
     801                 :            :                     {
     802                 :          0 :                         bFixTags = sal_True;
     803                 :            :                     }
     804                 :          0 :                     break;
     805                 :            :                 case 'e':
     806                 :            :                     {
     807                 :          0 :                         bAllowSuspicious = sal_True;
     808                 :            :                     }
     809                 :          0 :                     break;
     810                 :            :                 default:
     811                 :          0 :                     fprintf( stderr, "\nERROR: Unknown Switch %s!\n\n", argv[ i ] );
     812                 :          0 :                     bError = sal_True;
     813                 :            :             }
     814                 :            :         }
     815                 :            :         else
     816                 :            :         {
     817                 :          0 :             if  (aFilename.isEmpty())
     818                 :          0 :                 aFilename = argv[i];
     819                 :            :             else
     820                 :            :             {
     821                 :          0 :                 fprintf( stderr, "\nERROR: Only one filename may be specified!\n\n");
     822                 :          0 :                 bError = sal_True;
     823                 :            :             }
     824                 :            :         }
     825                 :            :     }
     826                 :            : 
     827                 :            : 
     828                 :          0 :     if (aFilename.isEmpty() || bError)
     829                 :            :     {
     830                 :          0 :         Help();
     831                 :          0 :         exit ( 0 );
     832                 :            :     }
     833                 :            : 
     834                 :          0 :     if ( !aSourceLang.isEmpty() && !LanguageOK( aSourceLang ) )
     835                 :            :     {
     836                 :          0 :         fprintf( stderr, "\nERROR: The Language '%s' is invalid!\n\n", aSourceLang.getStr() );
     837                 :          0 :         Help();
     838                 :          0 :         exit ( 1 );
     839                 :            :     }
     840                 :            : 
     841                 :          0 :     if ( bCheckSourceLang && bCheckTranslationLang )
     842                 :            :     {
     843                 :          0 :         fprintf( stderr, "\nERROR: The Options -s and -t are mutually exclusive.\nUse only one of them.\n\n" );
     844                 :          0 :         Help();
     845                 :          0 :         exit ( 1 );
     846                 :            :     }
     847                 :            : 
     848                 :            : 
     849                 :            : 
     850                 :          0 :     std::ifstream aGSI(aFilename.getStr());
     851                 :          0 :     if (!aGSI.is_open()) {
     852                 :          0 :         fprintf( stderr, "\nERROR: Could not open GSI-File %s!\n\n", aFilename.getStr() );
     853                 :          0 :         exit ( 3 );
     854                 :            :     }
     855                 :            : 
     856                 :          0 :     std::ifstream aReferenceGSI;
     857                 :          0 :     if ( bReferenceFile )
     858                 :            :     {
     859                 :          0 :         aReferenceGSI.open(aReferenceFilename.getStr());
     860                 :          0 :         if (!aReferenceGSI.is_open()) {
     861                 :          0 :             fprintf( stderr, "\nERROR: Could not open Input-File %s!\n\n", aFilename.getStr() );
     862                 :          0 :             exit ( 3 );
     863                 :            :         }
     864                 :            :     }
     865                 :            : 
     866                 :          0 :     LazyStream aOkOut;
     867                 :          0 :     if ( bWriteCorrect )
     868                 :            :     {
     869                 :          0 :         if (aCorrectFilename.isEmpty())
     870                 :            :         {
     871                 :            :             aCorrectFilename = addSuffix(
     872                 :          0 :                 aFilename, rtl::OString(RTL_CONSTASCII_STRINGPARAM("_ok")));
     873                 :            :         }
     874                 :          0 :         aOkOut.SetFileName(aCorrectFilename);
     875                 :            :     }
     876                 :            : 
     877                 :          0 :     LazyStream aErrOut;
     878                 :          0 :     if ( bWriteError )
     879                 :            :     {
     880                 :          0 :         if (aErrorFilename.isEmpty())
     881                 :            :         {
     882                 :            :             aErrorFilename = addSuffix(
     883                 :          0 :                 aFilename, rtl::OString(RTL_CONSTASCII_STRINGPARAM("_err")));
     884                 :            :         }
     885                 :          0 :         aErrOut.SetFileName(aErrorFilename);
     886                 :            :     }
     887                 :            : 
     888                 :          0 :     LazyStream aFixOut;
     889                 :          0 :     if ( bWriteFixed )
     890                 :            :     {
     891                 :          0 :         if (aFixedFilename.isEmpty())
     892                 :            :         {
     893                 :            :             aFixedFilename = addSuffix(
     894                 :          0 :                 aFilename, rtl::OString(RTL_CONSTASCII_STRINGPARAM("_fix")));
     895                 :            :         }
     896                 :          0 :         aFixOut.SetFileName(aFixedFilename);
     897                 :            :     }
     898                 :            : 
     899                 :            : 
     900                 :          0 :     GSILine* pReferenceLine = NULL;
     901                 :          0 :     std::size_t nReferenceLine = 0;
     902                 :            : 
     903                 :          0 :     GSILine* pGSILine = NULL;
     904                 :          0 :     rtl::OString aOldId("No Valid ID");   // just set to something which can never be an ID
     905                 :          0 :     GSIBlock *pBlock = NULL;
     906                 :          0 :     std::size_t nLine = 0;
     907                 :            : 
     908                 :          0 :     while (!aGSI.eof())
     909                 :            :     {
     910                 :          0 :         std::string s;
     911                 :          0 :         std::getline(aGSI, s);
     912                 :          0 :         nLine++;
     913                 :          0 :         pGSILine = new GSILine(rtl::OString(s.data(), s.length()), nLine );
     914                 :          0 :         sal_Bool bDelete = sal_True;
     915                 :            : 
     916                 :            : 
     917                 :          0 :         if ( !pGSILine->data_.isEmpty() )
     918                 :            :         {
     919                 :          0 :             if ( FORMAT_UNKNOWN == pGSILine->GetLineFormat() )
     920                 :            :             {
     921                 :          0 :                 PrintError( "Format of line is unknown. Ignoring!", "Line format", pGSILine->data_.copy( 0,40 ), bPrintContext, pGSILine->GetLineNumber() );
     922                 :          0 :                 pGSILine->NotOK();
     923                 :          0 :                 if ( bWriteError )
     924                 :            :                 {
     925                 :          0 :                     bFileHasError = sal_True;
     926                 :          0 :                     aErrOut.LazyOpen();
     927                 :          0 :                     aErrOut << pGSILine->data_.getStr();
     928                 :            :                 }
     929                 :            :             }
     930                 :          0 :             else if ( pGSILine->GetLineType().equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("res-comment")) )
     931                 :            :             {   // ignore comment lines, but write them to Correct Items File
     932                 :          0 :                 if ( bWriteCorrect )
     933                 :            :                 {
     934                 :          0 :                     aOkOut.LazyOpen();
     935                 :          0 :                     aOkOut << pGSILine->data_.getStr() << '\n';
     936                 :            :                 }
     937                 :            :             }
     938                 :            :             else
     939                 :            :             {
     940                 :          0 :                 rtl::OString aId = pGSILine->GetUniqId();
     941                 :          0 :                 if ( aId != aOldId )
     942                 :            :                 {
     943                 :          0 :                     if ( pBlock )
     944                 :            :                     {
     945                 :          0 :                         bFileHasError |= pBlock->CheckSyntax( nLine, !aSourceLang.isEmpty(), bFixTags );
     946                 :            : 
     947                 :          0 :                         if ( bWriteError )
     948                 :          0 :                             pBlock->WriteError( aErrOut, !aSourceLang.isEmpty() );
     949                 :          0 :                         if ( bWriteCorrect )
     950                 :          0 :                             pBlock->WriteCorrect( aOkOut, !aSourceLang.isEmpty() );
     951                 :          0 :                         if ( bWriteFixed )
     952                 :          0 :                             pBlock->WriteFixed( aFixOut );
     953                 :            : 
     954                 :          0 :                         delete pBlock;
     955                 :            :                     }
     956                 :          0 :                     pBlock = new GSIBlock( bPrintContext, bCheckSourceLang, bCheckTranslationLang, bReferenceFile, bAllowSuspicious );
     957                 :            : 
     958                 :          0 :                     aOldId = aId;
     959                 :            : 
     960                 :            : 
     961                 :            :                     // find corresponding line in reference file
     962                 :          0 :                     if ( bReferenceFile )
     963                 :            :                     {
     964                 :          0 :                         sal_Bool bContinueSearching = sal_True;
     965                 :          0 :                         while ( ( !aReferenceGSI.eof() || pReferenceLine ) && bContinueSearching )
     966                 :            :                         {
     967                 :          0 :                             if ( !pReferenceLine )
     968                 :            :                             {
     969                 :          0 :                                 std::string s2;
     970                 :          0 :                                 std::getline(aReferenceGSI, s2);
     971                 :          0 :                                 nReferenceLine++;
     972                 :            :                                 pReferenceLine = new GSILine(
     973                 :          0 :                                     rtl::OString(s2.data(), s2.length()),
     974                 :          0 :                                     nReferenceLine);
     975                 :            :                             }
     976                 :          0 :                             if ( pReferenceLine->GetLineFormat() != FORMAT_UNKNOWN )
     977                 :            :                             {
     978                 :          0 :                                 if ( pReferenceLine->GetUniqId() == aId && pReferenceLine->GetLanguageId() == aSourceLang )
     979                 :            :                                 {
     980                 :          0 :                                     pBlock->SetReferenceLine( pReferenceLine );
     981                 :          0 :                                     pReferenceLine = NULL;
     982                 :            :                                 }
     983                 :          0 :                                 else if ( pReferenceLine->GetUniqId() > aId )
     984                 :            :                                 {
     985                 :          0 :                                     bContinueSearching = sal_False;
     986                 :            :                                 }
     987                 :            :                                 else
     988                 :            :                                 {
     989                 :          0 :                                     if ( pReferenceLine->GetUniqId() < aId  && pReferenceLine->GetLanguageId() == aSourceLang )
     990                 :          0 :                                         PrintError( "No Entry in source file found. Entry has been removed from source file", "File format", "", bPrintContext, pGSILine->GetLineNumber(), pReferenceLine->GetUniqId() );
     991                 :          0 :                                     delete pReferenceLine;
     992                 :          0 :                                     pReferenceLine = NULL;
     993                 :            :                                 }
     994                 :            :                             }
     995                 :            :                             else
     996                 :            :                             {
     997                 :          0 :                                 delete pReferenceLine;
     998                 :          0 :                                 pReferenceLine = NULL;
     999                 :            :                             }
    1000                 :            : 
    1001                 :            :                         }
    1002                 :            :                     }
    1003                 :            : 
    1004                 :            :                 }
    1005                 :            : 
    1006                 :          0 :                 pBlock->InsertLine( pGSILine, aSourceLang );
    1007                 :          0 :                 bDelete = sal_False;
    1008                 :            :             }
    1009                 :            :         }
    1010                 :          0 :         if ( bDelete )
    1011                 :          0 :             delete pGSILine;
    1012                 :            : 
    1013                 :          0 :     }
    1014                 :          0 :     if ( pBlock )
    1015                 :            :     {
    1016                 :          0 :         bFileHasError |= pBlock->CheckSyntax( nLine, !aSourceLang.isEmpty(), bFixTags );
    1017                 :            : 
    1018                 :          0 :         if ( bWriteError )
    1019                 :          0 :             pBlock->WriteError( aErrOut, !aSourceLang.isEmpty() );
    1020                 :          0 :         if ( bWriteCorrect )
    1021                 :          0 :             pBlock->WriteCorrect( aOkOut, !aSourceLang.isEmpty() );
    1022                 :          0 :         if ( bWriteFixed )
    1023                 :          0 :             pBlock->WriteFixed( aFixOut );
    1024                 :            : 
    1025                 :          0 :         delete pBlock;
    1026                 :            :     }
    1027                 :          0 :     aGSI.close();
    1028                 :            : 
    1029                 :          0 :     if ( bWriteError )
    1030                 :          0 :         aErrOut.close();
    1031                 :          0 :     if ( bWriteCorrect )
    1032                 :          0 :         aOkOut.close();
    1033                 :          0 :     if ( bWriteFixed )
    1034                 :          0 :         aFixOut.close();
    1035                 :            : 
    1036                 :          0 :     if ( bFileHasError )
    1037                 :          0 :         return 55;
    1038                 :            :     else
    1039                 :          0 :         return 0;
    1040                 :            : }
    1041                 :            : 
    1042                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10