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