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