summaryrefslogtreecommitdiff
path: root/transex3/source/tagtest.cxx
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2010-01-25 17:20:55 +0100
committerIvo Hinkelmann <ihi@openoffice.org>2010-01-25 17:20:55 +0100
commit282d42b81a5ae3f9f7be1a70218ae8df91d256a3 (patch)
tree675ac0d589e9a6696fa7ceb6281695a586aeb798 /transex3/source/tagtest.cxx
parent60e367c8168aa3193df0ba4d64a803e909c18f11 (diff)
l10ntools: #i108657# rename transex3 to l10ntools
Diffstat (limited to 'transex3/source/tagtest.cxx')
-rw-r--r--transex3/source/tagtest.cxx1577
1 files changed, 0 insertions, 1577 deletions
diff --git a/transex3/source/tagtest.cxx b/transex3/source/tagtest.cxx
deleted file mode 100644
index 3e134a0a94..0000000000
--- a/transex3/source/tagtest.cxx
+++ /dev/null
@@ -1,1577 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: tagtest.cxx,v $
- * $Revision: 1.20 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_transex3.hxx"
-#include <tools/string.hxx>
-#include "tagtest.hxx"
-
-#if OSL_DEBUG_LEVEL > 1
-#include <stdio.h>
-#endif
-
-#include "gsicheck.hxx"
-
-#define HAS_FLAG( nFlags, nFlag ) ( ( nFlags & nFlag ) != 0 )
-#define SET_FLAG( nFlags, nFlag ) ( nFlags |= nFlag )
-#define RESET_FLAG( nFlags, nFlag ) ( nFlags &= ~nFlag ) // ~ = Bitweises NOT
-
-
-
-TokenInfo::TokenInfo( TokenId pnId, USHORT nP, String paStr, ParserMessageList &rErrorList )
-: bClosed(FALSE)
-, bCloseTag(FALSE)
-, bIsBroken(FALSE)
-, bHasBeenFixed(FALSE)
-, bDone(FALSE)
-, aTokenString( paStr )
-, nId( pnId )
-, nPos(nP)
-{
- if ( nId == TAG_COMMONSTART || nId == TAG_COMMONEND )
- SplitTag( rErrorList );
-}
-
-enum tagcheck { TC_START, TC_HAS_TAG_NAME, TC_HAS_PROP_NAME_EQ, TC_HAS_PROP_NAME_EQ_SP, TC_HAS_PROP_NAME_SP, TC_INSIDE_STRING, TC_PROP_FINISHED, TC_CLOSED, TC_CLOSED_SPACE, TC_CLOSETAG, TC_CLOSETAG_HAS_TAG_NAME, TC_FINISHED, TC_ERROR };
-
-/*
- \< link href = \"text\" name = \"C\" \>
-START ' ' -> HAS_TAG_NAME
-START '/' -> CLOSED
-START '/' -> CLOSETAG - no Portion (starting with /)
-START '>' -> FINISHED
-HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ
-HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP
-HAS_TAG_NAME '/' -> CLOSED
-HAS_TAG_NAME '>' -> FINISHED
-HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ
-HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP
-HAS_PROP_NAME_EQ '"' -> INSIDE_STRING
-HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING
-INSIDE_STRING ' ' -> INSIDE_STRING
-INSIDE_STRING '=' -> INSIDE_STRING
-INSIDE_STRING '>' -> INSIDE_STRING
-INSIDE_STRING '"' -> PROP_FINISHED
-PROP_FINISHED ' ' -> HAS_TAG_NAME
-PROP_FINISHED '/' -> CLOSED
-PROP_FINISHED '>' -> FINISHED
-CLOSED ' ' -> CLOSED_SPACE
-CLOSED '>' -> FINISHED
-CLOSED_SPACE '>' -> FINISHED
-
-CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME
-CLOSETAG '>' -> FINISHED
-CLOSETAG_HAS_TAG_NAME '>' -> FINISHED
-
-*/
-void TokenInfo::SplitTag( ParserMessageList &rErrorList )
-{
- USHORT nLastPos = 2; // skip initial \<
- USHORT nCheckPos = nLastPos;
- String aDelims( String::CreateFromAscii( " \\=>/" ) );
- String aPortion;
- String aValue; // store the value of a property
- ByteString aName; // store the name of a property/tag
- BOOL bCheckName = FALSE;
- BOOL bCheckEmpty = FALSE;
- sal_Unicode cDelim;
- tagcheck aState = TC_START;
-
- // skip blanks
- while ( nLastPos < aTokenString.Len() && aTokenString.GetChar( nLastPos ) == ' ')
- nLastPos++;
-
- nCheckPos = aTokenString.SearchChar( aDelims.GetBuffer(), nLastPos );
- while ( nCheckPos != STRING_NOTFOUND && !( aState == TC_FINISHED || aState == TC_ERROR ) )
- {
- aPortion = aTokenString.Copy( nLastPos, nCheckPos-nLastPos );
-
- if ( aTokenString.GetChar( nCheckPos ) == '\\' )
- nCheckPos++;
-
- cDelim = aTokenString.GetChar( nCheckPos );
- nCheckPos++;
-
- switch ( aState )
- {
-// START ' ' -> HAS_TAG_NAME
-// START '/' -> CLOSED
-// START '>' -> FINISHED
- case TC_START:
- aTagName = aPortion;
- switch ( cDelim )
- {
- case ' ': aState = TC_HAS_TAG_NAME;
- bCheckName = TRUE;
- break;
- case '/':
- {
- if ( aPortion.Len() == 0 )
- {
- aState = TC_CLOSETAG;
- }
- else
- {
- aState = TC_CLOSED;
- bCheckName = TRUE;
- }
- }
- break;
- case '>': aState = TC_FINISHED;
- bCheckName = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ
-// HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP
-// HAS_TAG_NAME '/' -> CLOSED
-// HAS_TAG_NAME '>' -> FINISHED
- case TC_HAS_TAG_NAME:
- switch ( cDelim )
- {
- case '=': aState = TC_HAS_PROP_NAME_EQ;
- bCheckName = TRUE;
- break;
- case ' ': aState = TC_HAS_PROP_NAME_SP;
- bCheckName = TRUE;
- break;
- case '/': aState = TC_CLOSED;
- bCheckEmpty = TRUE;
- break;
- case '>': aState = TC_FINISHED;
- bCheckEmpty = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ
- case TC_HAS_PROP_NAME_SP:
- switch ( cDelim )
- {
- case '=': aState = TC_HAS_PROP_NAME_EQ;
- bCheckEmpty = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP
-// HAS_PROP_NAME_EQ '"' -> INSIDE_STRING
- case TC_HAS_PROP_NAME_EQ:
- switch ( cDelim )
- {
- case ' ': aState = TC_HAS_PROP_NAME_EQ_SP;
- bCheckEmpty = TRUE;
- break;
- case '\"': aState = TC_INSIDE_STRING;
- bCheckEmpty = TRUE;
- aValue.Erase();
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING
- case TC_HAS_PROP_NAME_EQ_SP:
- switch ( cDelim )
- {
- case '\"': aState = TC_INSIDE_STRING;
- bCheckEmpty = TRUE;
- aValue.Erase();
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// INSIDE_STRING * -> INSIDE_STRING
-// INSIDE_STRING '"' -> PROP_FINISHED
- case TC_INSIDE_STRING:
- switch ( cDelim )
- {
- case '\"':
- {
- aState = TC_PROP_FINISHED;
- aValue += aPortion;
- if ( aProperties.find( aName ) == aProperties.end() )
- {
- if ( !IsPropertyValueValid( aName, aValue ) )
- {
- rErrorList.AddError( 25, ByteString("Property '").Append(aName).Append("' has invalid value '").Append(ByteString( aValue, RTL_TEXTENCODING_UTF8 )).Append("' "), *this );
- bIsBroken = TRUE;
- }
- aProperties[ aName ] = aValue;
- }
- else
- {
- rErrorList.AddError( 25, ByteString("Property '").Append(aName).Append("' defined twice "), *this );
- bIsBroken = TRUE;
- }
- }
- break;
- default:
- {
- aState = TC_INSIDE_STRING;
- aValue += aPortion;
- aValue += cDelim;
- }
- }
- break;
-
-// PROP_FINISHED ' ' -> HAS_TAG_NAME
-// PROP_FINISHED '/' -> CLOSED
-// PROP_FINISHED '>' -> FINISHED
- case TC_PROP_FINISHED:
- switch ( cDelim )
- {
- case ' ': aState = TC_HAS_TAG_NAME;
- bCheckEmpty = TRUE;
- break;
- case '/': aState = TC_CLOSED;
- bCheckEmpty = TRUE;
- break;
- case '>': aState = TC_FINISHED;
- bCheckEmpty = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// CLOSED ' ' -> CLOSED_SPACE
-// CLOSED '>' -> FINISHED
- case TC_CLOSED:
- switch ( cDelim )
- {
- case ' ': aState = TC_CLOSED_SPACE;
- bCheckEmpty = TRUE;
- bClosed = TRUE;
- break;
- case '>': aState = TC_FINISHED;
- bCheckEmpty = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// CLOSED_SPACE '>' -> FINISHED
- case TC_CLOSED_SPACE:
- switch ( cDelim )
- {
- case '>': aState = TC_FINISHED;
- bCheckEmpty = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME
-// CLOSETAG '>' -> FINISHED
- case TC_CLOSETAG:
- bCloseTag = TRUE;
- switch ( cDelim )
- {
- case ' ': aState = TC_CLOSETAG_HAS_TAG_NAME;
- aTagName = aPortion;
- bCheckName = TRUE;
- break;
- case '>': aState = TC_FINISHED;
- aTagName = aPortion;
- bCheckName = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-// CLOSETAG_HAS_TAG_NAME '>' -> FINISHED
- case TC_CLOSETAG_HAS_TAG_NAME:
- switch ( cDelim )
- {
- case '>': aState = TC_FINISHED;
- bCheckEmpty = TRUE;
- break;
- default: aState = TC_ERROR;
- }
- break;
-
-
- default: rErrorList.AddError( 99, "Internal error Parsing Tag ", *this );
- bIsBroken = TRUE;
-
- }
-
- if ( bCheckName )
- {
- if ( aPortion.Len() == 0 )
- {
- rErrorList.AddError( 25, "Tag/Property name missing ", *this );
- bIsBroken = TRUE;
- }
- else
- {
- aName = ByteString( aPortion, RTL_TEXTENCODING_UTF8 );
- // "a-zA-Z_-.0-9"
- xub_StrLen nCount;
- BOOL bBroken = FALSE;
- const sal_Char* aBuf = aName.GetBuffer();
- for ( nCount = 0 ; !bBroken && nCount < aName.Len() ; nCount++ )
- {
- bBroken = ! ( ( aBuf[nCount] >= 'a' && aBuf[nCount] <= 'z' )
- ||( aBuf[nCount] >= 'A' && aBuf[nCount] <= 'Z' )
- ||( aBuf[nCount] >= '0' && aBuf[nCount] <= '9' )
- ||( aBuf[nCount] == '_' )
- ||( aBuf[nCount] == '-' )
- ||( aBuf[nCount] == '.' )
- );
- }
-
- if ( bBroken )
- {
- rErrorList.AddError( 25, "Found illegal character in Tag/Property name ", *this );
- bIsBroken = TRUE;
- }
- }
-
- bCheckName = FALSE;
- }
-
- if ( bCheckEmpty )
- {
- if ( aPortion.Len() )
- {
- rErrorList.AddError( 25, ByteString("Found displaced characters '").Append(ByteString( aPortion, RTL_TEXTENCODING_UTF8 )).Append("' in Tag "), *this );
- bIsBroken = TRUE;
- }
- bCheckEmpty = FALSE;
- }
-
-
- nLastPos = nCheckPos;
-
- // skip further blanks
- if ( cDelim == ' ' && aState != TC_INSIDE_STRING )
- while ( nLastPos < aTokenString.Len() && aTokenString.GetChar( nLastPos ) == ' ')
- nLastPos++;
-
- nCheckPos = aTokenString.SearchChar( aDelims.GetBuffer(), nLastPos );
- }
- if ( aState != TC_FINISHED )
- {
- rErrorList.AddError( 25, "Parsing error in Tag ", *this );
- bIsBroken = TRUE;
- }
-}
-
-BOOL TokenInfo::IsPropertyRelevant( const ByteString &aName, const String &aValue ) const
-{
- if ( aTagName.EqualsAscii( "alt" ) && aName.Equals( "xml-lang" ) )
- return FALSE;
- if ( aTagName.EqualsAscii( "ahelp" ) && aName.Equals( "visibility" ) && aValue.EqualsAscii("visible") )
- return FALSE;
- if ( aTagName.EqualsAscii( "image" ) && (aName.Equals( "width" ) || aName.Equals( "height" )) )
- return FALSE;
-
- return TRUE;
-}
-
-BOOL TokenInfo::IsPropertyValueValid( const ByteString &aName, const String &aValue ) const
-{
-/* removed due to i56740
- if ( aTagName.EqualsAscii( "switchinline" ) && aName.Equals( "select" ) )
- {
- return aValue.EqualsAscii("sys") ||
- aValue.EqualsAscii("appl") ||
- aValue.EqualsAscii("distrib");
- } */
- if ( aTagName.EqualsAscii( "caseinline" ) && aName.Equals( "select" ) )
- {
- return /*!aValue.EqualsAscii("OS2") && removed due to i56740 */
- !aValue.EqualsAscii("");
- }
-
- // we don't know any better so we assume it to be OK
- return TRUE;
-}
-
-BOOL TokenInfo::IsPropertyInvariant( const ByteString &aName, const String &aValue ) const
-{
- if ( aTagName.EqualsAscii( "link" ) && aName.Equals( "name" ) )
- return FALSE;
- if ( aTagName.EqualsAscii( "link" ) && aName.Equals( "href" ) )
- { // check for external reference
- if ( aValue.Copy( 0, 5 ).EqualsIgnoreCaseAscii( "http:" )
- || aValue.Copy( 0, 6 ).EqualsIgnoreCaseAscii( "https:" )
- || aValue.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "ftp:" ) )
- return FALSE;
- else
- return TRUE;
- }
- return TRUE;
-}
-
-BOOL TokenInfo::IsPropertyFixable( const ByteString &aName ) const
-{
- // name everything that is allowed to be fixed automatically here
- if ( (aTagName.EqualsAscii( "ahelp" ) && aName.Equals( "hid" ))
- || (aTagName.EqualsAscii( "link" ) && aName.Equals( "href" ))
- || (aTagName.EqualsAscii( "alt" ) && aName.Equals( "id" ))
- || (aTagName.EqualsAscii( "variable" ) && aName.Equals( "id" ))
- || (aTagName.EqualsAscii( "image" ) && aName.Equals( "src" ))
- || (aTagName.EqualsAscii( "image" ) && aName.Equals( "id" ) ))
- return TRUE;
- return FALSE;
-}
-
-BOOL TokenInfo::MatchesTranslation( TokenInfo& rInfo, BOOL bGenErrors, ParserMessageList &rErrorList, BOOL bFixTags ) const
-{
- // check if tags are equal
- // check if all existing properties are in the translation as well and
- // wether they have a matching content (the same in most cases)
-
- if ( nId != rInfo.nId )
- return FALSE;
-
- if ( !aTagName.Equals( rInfo.aTagName ) )
- return FALSE;
-
- // If one of the tags has formating errors already it does make no sense to check here, so return right away
- if ( bGenErrors && ( bIsBroken || rInfo.bIsBroken ) )
- return TRUE;
-
- StringHashMap::const_iterator iProp;
- for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp )
- {
- if ( rInfo.aProperties.find( iProp->first ) != rInfo.aProperties.end() )
- {
- if ( IsPropertyRelevant( iProp->first, iProp->second ) || IsPropertyRelevant( iProp->first, rInfo.aProperties.find( iProp->first )->second ) )
- {
- if ( IsPropertyInvariant( iProp->first, iProp->second ) )
- {
- if ( !rInfo.aProperties.find( iProp->first )->second.Equals( iProp->second ) )
- {
- if ( bGenErrors )
- {
- if ( bFixTags && IsPropertyFixable( iProp->first ) )
- {
- rInfo.aProperties.find( iProp->first )->second = iProp->second;
- rInfo.SetHasBeenFixed();
- rErrorList.AddWarning( 25, ByteString("Property '").Append(iProp->first).Append("': FIXED different value in Translation "), *this );
- }
- else
- rErrorList.AddError( 25, ByteString("Property '").Append(iProp->first).Append("': value different in Translation "), *this );
- }
- else return FALSE;
- }
- }
- }
- }
- else
- {
- if ( IsPropertyRelevant( iProp->first, iProp->second ) )
- {
- if ( bGenErrors )
- rErrorList.AddError( 25, ByteString("Property '").Append(iProp->first).Append("' missing in Translation "), *this );
- else return FALSE;
- }
- }
- }
- for( iProp = rInfo.aProperties.begin() ; iProp != rInfo.aProperties.end(); ++iProp )
- {
- if ( aProperties.find( iProp->first ) == aProperties.end() )
- {
- if ( IsPropertyRelevant( iProp->first, iProp->second ) )
- {
- if ( bGenErrors )
- rErrorList.AddError( 25, ByteString("Extra Property '").Append(iProp->first).Append("' in Translation "), rInfo );
- else return FALSE;
- }
- }
- }
-
- // if we reach here eather
- // the tags match completely or
- // the tags match but not the properties and we generated errors for that
- return TRUE;
-}
-
-String TokenInfo::GetTagName() const
-{
- return aTagName;
-}
-
-String TokenInfo::MakeTag() const
-{
- String aRet;
- aRet.AppendAscii("\\<");
- if ( bCloseTag )
- aRet.AppendAscii("/");
- aRet.Append( GetTagName() );
- StringHashMap::const_iterator iProp;
-
- for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp )
- {
- aRet.AppendAscii(" ");
- aRet.Append( String( iProp->first, RTL_TEXTENCODING_UTF8 ) );
- aRet.AppendAscii("=\\\"");
- aRet.Append( iProp->second );
- aRet.AppendAscii("\\\"");
- }
- if ( bClosed )
- aRet.AppendAscii("/");
- aRet.AppendAscii("\\>");
- return aRet;
-}
-
-
-void ParserMessageList::AddError( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag )
-{
- Insert( new ParserError( nErrorNr, aErrorText, rTag ), LIST_APPEND );
-}
-
-void ParserMessageList::AddWarning( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag )
-{
- Insert( new ParserWarning( nErrorNr, aErrorText, rTag ), LIST_APPEND );
-}
-
-BOOL ParserMessageList::HasErrors()
-{
- USHORT i;
- for ( i=0 ; i < Count() ; i++ )
- if ( GetObject( i )->IsError() )
- return TRUE;
- return FALSE;
-}
-
-struct Tag
-{
- String GetName() const { return String::CreateFromAscii( pName ); };
- const char* pName;
- TokenId nTag;
-};
-
-
-static const Tag aKnownTags[] =
-{
-/* commenting oldstyle tags
-// { "<#GROUP_FORMAT>", TAG_GROUP_FORMAT },
- { "<#BOLD>", TAG_BOLDON },
- { "<#/BOLD>", TAG_BOLDOFF },
- { "<#ITALIC>", TAG_ITALICON },
- { "<#/ITALIC>", TAG_ITALICOFF },
- { "<#UNDER>", TAG_UNDERLINEON },
- { "<#/UNDER>", TAG_UNDERLINEOFF },
-
-// { "<#GROUP_NOTALLOWED>", TAG_GROUP_NOTALLOWED },
- { "<#HELPID>", TAG_HELPID },
- { "<#MODIFY>", TAG_MODIFY },
- { "<#REFNR>", TAG_REFNR },
-
-// { "<#GROUP_STRUCTURE>", TAG_GROUP_STRUCTURE },
- { "<#NAME>", TAG_NAME },
- { "<#HREF>", TAG_HREF },
- { "<#AVIS>", TAG_AVIS },
- { "<#AHID>", TAG_AHID },
- { "<#AEND>", TAG_AEND },
-
- { "<#TITEL>", TAG_TITEL },
- { "<#KEY>", TAG_KEY },
- { "<#INDEX>", TAG_INDEX },
-
- { "<#REFSTART>", TAG_REFSTART },
-
- { "<#GRAPHIC>", TAG_GRAPHIC },
- { "<#NEXTVERSION>", TAG_NEXTVERSION },
-
- // { "<#GROUP_SYSSWITCH>", TAG_GROUP_SYSSWITCH },
- { "<#WIN>", TAG_WIN },
- { "<#UNIX>", TAG_UNIX },
- { "<#MAC>", TAG_MAC },
- { "<#OS2>", TAG_OS2 },
-
-// { "<#GROUP_PROGSWITCH>", TAG_GROUP_PROGSWITCH },
- { "<#WRITER>", TAG_WRITER },
- { "<#CALC>", TAG_CALC },
- { "<#DRAW>", TAG_DRAW },
- { "<#IMPRESS>", TAG_IMPRESS },
- { "<#SCHEDULE>", TAG_SCHEDULE },
- { "<#IMAGE>", TAG_IMAGE },
- { "<#MATH>", TAG_MATH },
- { "<#CHART>", TAG_CHART },
- { "<#OFFICE>", TAG_OFFICE },
- */
-// { "<#TAG_GROUP_META>", TAG_GROUP_META },
- { "$[officefullname]", TAG_OFFICEFULLNAME },
- { "$[officename]", TAG_OFFICENAME },
- { "$[officepath]", TAG_OFFICEPATH },
- { "$[officeversion]", TAG_OFFICEVERSION },
- { "$[portalname]", TAG_PORTALNAME },
- { "$[portalfullname]", TAG_PORTALFULLNAME },
- { "$[portalpath]", TAG_PORTALPATH },
- { "$[portalversion]", TAG_PORTALVERSION },
- { "$[portalshortname]", TAG_PORTALSHORTNAME },
-/* commenting oldstyle tags
-// { "<#TAG_GROUP_SINGLE>", TAG_GROUP_SINGLE },
- { "<#REFINSERT>", TAG_REFINSERT },
-
-// { "<#GROUP_MULTI>", TAG_GROUP_MULTI },
- { "<#END>", TAG_END },
- { "<#ELSE>", TAG_ELSE },
- { "<#VERSIONEND>", TAG_VERSIONEND },
- { "<#ENDGRAPHIC>", TAG_ENDGRAPHIC },*/
- { "<Common Tag>", TAG_COMMONSTART },
- { "</Common Tag>", TAG_COMMONEND },
-
- { "<no more tags>", TAG_NOMORETAGS },
- { "", TAG_UNKNOWN_TAG },
-};
-
-
-SimpleParser::SimpleParser()
-: nPos( 0 )
-, aNextTag( TAG_NOMORETAGS, TOK_INVALIDPOS )
-{
-}
-
-void SimpleParser::Parse( String PaSource )
-{
- aSource = PaSource;
- nPos = 0;
- aLastToken.Erase();
- aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS );
- aTokenList.Clear();
-};
-
-TokenInfo SimpleParser::GetNextToken( ParserMessageList &rErrorList )
-{
- TokenInfo aResult;
- USHORT nTokenStartPos = 0;
- if ( aNextTag.nId != TAG_NOMORETAGS )
- {
- aResult = aNextTag;
- aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS );
- }
- else
- {
- aLastToken = GetNextTokenString( rErrorList, nTokenStartPos );
- if ( aLastToken.Len() == 0 )
- return TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS );
-
- // do we have a \< ... \> style tag?
- if ( aLastToken.Copy(0,2).EqualsAscii( "\\<" ) )
- {
- // check for paired \" \"
- bool bEven = true;
- USHORT nQuotePos = 0;
- USHORT nQuotedQuotesPos = aLastToken.SearchAscii( "\\\"" );
- USHORT nQuotedBackPos = aLastToken.SearchAscii( "\\\\" ); // this is only to kick out quoted backslashes
- while ( nQuotedQuotesPos != STRING_NOTFOUND )
- {
- if ( nQuotedBackPos <= nQuotedQuotesPos )
- nQuotePos = nQuotedBackPos+2;
- else
- {
- nQuotePos = nQuotedQuotesPos+2;
- bEven = !bEven;
- }
- nQuotedQuotesPos = aLastToken.SearchAscii( "\\\"", nQuotePos );
- nQuotedBackPos = aLastToken.SearchAscii( "\\\\", nQuotePos ); // this is only to kick out quoted backslashes
- }
- if ( !bEven )
- {
- rErrorList.AddError( 24, "Missing quotes ( \\\" ) in Tag", TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken ) );
- }
-
- // check if we have an end-tag or a start-tag
- USHORT nNonBlankStartPos,nNonBlankEndPos;
- nNonBlankStartPos = 2;
- while ( aLastToken.GetChar(nNonBlankStartPos) == ' ' )
- nNonBlankStartPos++;
- if ( aLastToken.GetChar(nNonBlankStartPos) == '/' )
- aResult = TokenInfo( TAG_COMMONEND, nTokenStartPos, aLastToken, rErrorList );
- else
- {
- aResult = TokenInfo( TAG_COMMONSTART, nTokenStartPos, aLastToken, rErrorList );
- nNonBlankEndPos = aLastToken.Len() -3;
- while ( aLastToken.GetChar(nNonBlankEndPos) == ' ' )
- nNonBlankEndPos--;
- if ( aLastToken.GetChar( nNonBlankEndPos ) == '/' )
- aNextTag = TokenInfo( TAG_COMMONEND, nTokenStartPos, String::CreateFromAscii("\\</").Append(aResult.GetTagName()).AppendAscii("\\>"), rErrorList );
- }
- }
- else
- {
- USHORT i = 0;
- while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG &&
- aLastToken != aKnownTags[i].GetName() )
- i++;
- aResult = TokenInfo( aKnownTags[i].nTag, nTokenStartPos );
- }
- }
-
- if ( aResult.nId == TAG_UNKNOWN_TAG )
- aResult = TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken );
- aTokenList.Insert( aResult, LIST_APPEND );
- return aResult;
-}
-
-String SimpleParser::GetNextTokenString( ParserMessageList &rErrorList, USHORT &rTagStartPos )
-{
-// USHORT nStyle1StartPos = aSource.SearchAscii( "<#", nPos );
- USHORT nStyle2StartPos = aSource.SearchAscii( "$[", nPos );
- USHORT nStyle3StartPos = aSource.SearchAscii( "\\<", nPos );
- USHORT nStyle4StartPos = aSource.SearchAscii( "\\\\", nPos ); // this is only to kick out quoted backslashes
-
- rTagStartPos = 0;
-
-/* removing since a \<... is not likely
- // check if the tag starts with a letter to avoid things like <> <= ... >
- while ( STRING_NOTFOUND != nStyle3StartPos && !( aSource.Copy( nStyle3StartPos+2, 1 ).IsAlphaAscii() || aSource.GetChar( nStyle3StartPos+2 ) == '/' ) )
- nStyle3StartPos = aSource.SearchAscii( "\\<", nStyle3StartPos+1 );
-*/
- if ( STRING_NOTFOUND == nStyle2StartPos && STRING_NOTFOUND == nStyle3StartPos )
- return String(); // no more tokens
-
- if ( nStyle4StartPos < nStyle2StartPos && nStyle4StartPos <= nStyle3StartPos ) // <= to make sure \\ is always handled first
- { // Skip quoted Backslash
- nPos = nStyle4StartPos +2;
- return GetNextTokenString( rErrorList, rTagStartPos );
- }
-
-/* if ( nStyle1StartPos < nStyle2StartPos && nStyle1StartPos <= nStyle3StartPos ) // <= to make sure our spechial tags are recognized before all others
- { // test for <# ... > style tokens
- USHORT nEndPos = aSource.SearchAscii( ">", nStyle1StartPos );
- if ( nEndPos == STRING_NOTFOUND )
- { // Token is incomplete. Skip start and search for better ones
- nPos = nStyle1StartPos +2;
- return GetNextTokenString( rErrorList, rTagStartPos );
- }
- nPos = nEndPos;
- rTagStartPos = nStyle1StartPos;
- return aSource.Copy( nStyle1StartPos, nEndPos-nStyle1StartPos +1 ).ToUpperAscii();
- }
- else*/ if ( nStyle2StartPos < nStyle3StartPos )
- { // test for $[ ... ] style tokens
- USHORT nEndPos = aSource.SearchAscii( "]", nStyle2StartPos);
- if ( nEndPos == STRING_NOTFOUND )
- { // Token is incomplete. Skip start and search for better ones
- nPos = nStyle2StartPos +2;
- return GetNextTokenString( rErrorList, rTagStartPos );
- }
- nPos = nEndPos;
- rTagStartPos = nStyle2StartPos;
- return aSource.Copy( nStyle2StartPos, nEndPos-nStyle2StartPos +1 );
- }
- else
- { // test for \< ... \> style tokens
- USHORT nEndPos = aSource.SearchAscii( "\\>", nStyle3StartPos);
- USHORT nQuotedBackPos = aSource.SearchAscii( "\\\\", nStyle3StartPos ); // this is only to kick out quoted backslashes
- while ( nQuotedBackPos <= nEndPos && nQuotedBackPos != STRING_NOTFOUND )
- {
- nEndPos = aSource.SearchAscii( "\\>", nQuotedBackPos +2);
- nQuotedBackPos = aSource.SearchAscii( "\\\\", nQuotedBackPos +2 ); // this is only to kick out quoted backslashes
- }
- if ( nEndPos == STRING_NOTFOUND )
- { // Token is incomplete. Skip start and search for better ones
- nPos = nStyle3StartPos +2;
- ByteString sTmp( "Tag Start '\\<' without Tag End '\\>': " );
- rErrorList.AddError( 24, "Tag Start '\\<' without Tag End '\\>'", TokenInfo( TAG_UNKNOWN_TAG, nStyle3StartPos, aSource.Copy( nStyle3StartPos-10, 20 ) ) );
- return GetNextTokenString( rErrorList, rTagStartPos );
- }
- // check for paired quoted " --> \"sometext\"
-
- nPos = nEndPos;
- rTagStartPos = nStyle3StartPos;
- return aSource.Copy( nStyle3StartPos, nEndPos-nStyle3StartPos +2 );
- }
-}
-
-String SimpleParser::GetLexem( TokenInfo const &aToken )
-{
- if ( aToken.aTokenString.Len() )
- return aToken.aTokenString;
- else
- {
- USHORT i = 0;
- while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG &&
- aKnownTags[i].nTag != aToken.nId )
- i++;
-
- return aKnownTags[i].GetName();
- }
-}
-
-TokenParser::TokenParser()
-: pErrorList( NULL )
-{}
-
-void TokenParser::Parse( const String &aCode, ParserMessageList* pList )
-{
- pErrorList = pList;
-
- //Scanner initialisieren
- aParser.Parse( aCode );
-
- //erstes Symbol holen
- aTag = aParser.GetNextToken( *pErrorList );
-
- nPfCaseOptions = 0;
- nAppCaseOptions = 0;
- bPfCaseActive = FALSE;
- bAppCaseActive = FALSE;
-
- nActiveRefTypes = 0;
-
- //Ausfuehren der Start-Produktion
- Paragraph();
-
- //Es wurde nicht die ganze Kette abgearbeitet, bisher ist aber
- //kein Fehler aufgetreten
- //=> es wurde ein einleitendes Tag vergessen
- if ( aTag.nId != TAG_NOMORETAGS )
- {
- switch ( aTag.nId )
- {
- case TAG_END:
- {
- ParseError( 3, "Extra Tag <#END>. Switch or <#HREF> expected.", aTag );
- }
- break;
- case TAG_BOLDOFF:
- {
- ParseError( 4, "<#BOLD> expected before <#/BOLD>.", aTag );
- }
- break;
- case TAG_ITALICOFF:
- {
- ParseError( 5, "<#ITALIC> expected before <#/ITALIC>.", aTag );
- }
- break;
- case TAG_UNDERLINEOFF:
- {
- ParseError( 17, "<#UNDER> expected before <#/UNDER>.", aTag );
- }
- break;
-/* case TAG_MISSPARENTHESIS:
- {
- ParseError( 14, "missing closing parenthesis '>'", aTag );
- }
- break;*/
- case TAG_AEND:
- {
- ParseError( 5, "Extra Tag <#AEND>. <#AVIS> or <#AHID> expected.", aTag );
- }
- break;
- case TAG_ELSE:
- {
- ParseError( 16, "Application-tag or platform-tag expected before <#ELSE>.", aTag );
- }
- break;
- case TAG_UNKNOWN_TAG:
- {
- ParseError( 6, "unknown Tag", aTag );
- }
- break;
- default:
- {
- ParseError( 6, "unexpected Tag", aTag );
- }
- }
- }
- pErrorList = NULL;
-}
-
-void TokenParser::Paragraph()
-{
- switch ( aTag.nId )
- {
- case TAG_GRAPHIC:
- case TAG_NEXTVERSION:
- {
- TagRef();
- Paragraph();
- }
- break;
- case TAG_AVIS:
- case TAG_AHID:
- {
- TagRef();
- Paragraph();
- }
- break;
- case TAG_HELPID:
- {
- SimpleTag();
- Paragraph();
- }
- break;
- case TAG_OFFICEFULLNAME:
- case TAG_OFFICENAME:
- case TAG_OFFICEPATH:
- case TAG_OFFICEVERSION:
- case TAG_PORTALNAME:
- case TAG_PORTALFULLNAME:
- case TAG_PORTALPATH:
- case TAG_PORTALVERSION:
- case TAG_PORTALSHORTNAME:
- {
- SimpleTag();
- Paragraph();
- }
- break;
- case TAG_REFINSERT:
- {
- SimpleTag();
- Paragraph();
- }
- break;
- case TAG_BOLDON:
- case TAG_ITALICON:
- case TAG_UNDERLINEON:
- case TAG_COMMONSTART:
- {
- TagPair();
- Paragraph();
- }
- break;
- case TAG_HREF:
- case TAG_NAME:
- case TAG_KEY:
- case TAG_INDEX:
- case TAG_TITEL:
- case TAG_REFSTART:
- {
- TagRef();
- Paragraph();
- }
- break;
- case TAG_OS2:
- case TAG_WIN:
- case TAG_UNIX:
- case TAG_MAC: //...
- {
- if ( ! bPfCaseActive )
- {
- //PfCases duerfen nicht verschachtelt sein:
- bPfCaseActive = TRUE;
- PfCase();
-
- //So jetzt kann wieder ein PfCase kommen:
- bPfCaseActive = FALSE;
- Paragraph();
- }
- }
- break;
- case TAG_WRITER:
- case TAG_CALC:
- case TAG_DRAW:
- case TAG_IMPRESS:
- case TAG_SCHEDULE:
- case TAG_IMAGE:
- case TAG_MATH:
- case TAG_CHART:
- case TAG_OFFICE:
- {
- if ( !bAppCaseActive )
- {
- //AppCases duerfen nicht verschachtelt sein:
- bAppCaseActive = TRUE;
- AppCase();
-
- //jetzt koennen wieder AppCases kommen:
- bAppCaseActive = FALSE;
- Paragraph();
- }
- }
- break;
-
- //Case TAG_BOLDOFF, TAG_ITALICOFF, TAG_BUNDERLINE, TAG_END
- //nichts tun wg. epsilon-Prod.
- }
-}
-
-void TokenParser::PfCase()
-{
-
- //Produktion:
- //PfCase -> PfCaseBegin Paragraph (PfCase | PfCaseEnd)
-
- PfCaseBegin();
-
- //Jetzt ist eine PfCase-Produktion aktiv:
- Paragraph();
- switch ( aTag.nId )
- {
- case TAG_ELSE:
- case TAG_END:
- {
- CaseEnd();
- }
- break;
- case TAG_OS2:
- case TAG_WIN:
- case TAG_UNIX:
- case TAG_MAC: //First (PfBegin)
- {
- PfCase();
- }
- break;
- default:
- ParseError( 8, "<#ELSE> or <#END> or platform-tag expected.", aTag );
- }
- //Die gemerkten Tags wieder loeschen fuer naechstes PfCase:
- nPfCaseOptions = 0;
-}
-
-void TokenParser::PfCaseBegin()
-{
- switch ( aTag.nId )
- {
- case TAG_OS2:
- case TAG_WIN:
- case TAG_UNIX:
- case TAG_MAC:
- {
- //Token darf noch nicht vorgekommen sein im
- //aktuellen Plattform-Case:
- if ( !HAS_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) ) )
- {
- SET_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) );
- match( aTag, aTag );
- }
- else {
- ParseError( 9, "Tag defined twice in the same platform-case", aTag );
- }
- }
- }
-}
-
-void TokenParser::AppCase()
-{
-
- //Produktion:
- //AppCase -> AppCaseBegin Paragraph (AppCase | AppCaseEnd)
-
-
- AppCaseBegin();
-
- Paragraph();
-
- switch ( aTag.nId )
- {
- case TAG_ELSE:
- case TAG_END:
- {
- CaseEnd();
- }
- break;
- case TAG_WRITER:
- case TAG_DRAW:
- case TAG_CALC:
- case TAG_IMAGE:
- case TAG_MATH:
- case TAG_CHART:
- case TAG_OFFICE:
- case TAG_IMPRESS:
- case TAG_SCHEDULE: //First (AppBegin)
- {
- AppCase();
- }
- break;
- default:
- ParseError( 1, "<#ELSE> or <#END> or application-case-tag expected.", aTag );
- }
-
- //Die gemerkten Tags wieder loeschen fuer naechstes AppCase:
- nAppCaseOptions = 0;
-}
-
-void TokenParser::AppCaseBegin()
-{
- switch ( aTag.nId )
- {
- case TAG_WRITER:
- case TAG_DRAW:
- case TAG_CALC:
- case TAG_IMAGE:
- case TAG_MATH:
- case TAG_CHART:
- case TAG_OFFICE:
- case TAG_IMPRESS:
- case TAG_SCHEDULE:
- {
- //Token darf noch nicht vorgekommen sein im
- //aktuellen Plattform-Case:
- if ( !HAS_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) ) )
- {
- SET_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) );
- match( aTag, aTag );
- }
- else {
- ParseError( 13, "Tag defined twice in the same application-case.", aTag );
- }
- }
- }
-}
-
-void TokenParser::CaseEnd()
-{
- //Produktion:
- //CaseEnd -> <#ELSE> Paragraph <#END> | <#END>
-
- switch ( aTag.nId )
- {
- case TAG_ELSE:
- {
- match( aTag, TAG_ELSE );
- Paragraph();
- match( aTag, TAG_END );
- }
- break;
- case TAG_END:
- {
- match( aTag, TAG_END );
- }
- break;
- default:
- ParseError( 2, "<#ELSE> or <#END> expected.", aTag );
- }
-}
-
-void TokenParser::SimpleTag()
-{
-
- switch ( aTag.nId )
- {
- case TAG_HELPID:
- {
- match( aTag, TAG_HELPID );
- }
- break;
- case TAG_OFFICEFULLNAME:
- case TAG_OFFICENAME:
- case TAG_OFFICEPATH:
- case TAG_OFFICEVERSION:
- case TAG_PORTALNAME:
- case TAG_PORTALFULLNAME:
- case TAG_PORTALPATH:
- case TAG_PORTALVERSION:
- case TAG_PORTALSHORTNAME:
-
- case TAG_REFINSERT:
- {
- match( aTag, aTag );
- }
- break;
- default:
- ParseError( 15, "[<#SimpleTag>] expected.", aTag );
- }
-}
-
-void TokenParser::TagPair()
-{
- switch ( aTag.nId )
- {
- case TAG_BOLDON:
- {
- match( aTag, TAG_BOLDON );
- Paragraph();
- match( aTag, TAG_BOLDOFF );
- }
- break;
- case TAG_ITALICON:
- {
- match( aTag, TAG_ITALICON );
- Paragraph();
- match( aTag, TAG_ITALICOFF );
- }
- break;
- case TAG_UNDERLINEON:
- {
- match( aTag, TAG_UNDERLINEON );
- Paragraph();
- match( aTag, TAG_UNDERLINEOFF );
- }
- break;
- case TAG_COMMONSTART:
- {
- //remember tag so we can give the original tag in case of an error
- TokenInfo aEndTag( aTag );
- aEndTag.nId = TAG_COMMONEND;
- match( aTag, TAG_COMMONSTART );
- Paragraph();
- match( aTag, aEndTag );
- }
- break;
- default:
- ParseError( 10, "<#BOLD>, <#ITALIC>, <#UNDER> expected.", aTag );
- }
-}
-
-
-void TokenParser::TagRef()
-{
- switch ( aTag.nId )
- {
- case TAG_GRAPHIC:
- case TAG_NEXTVERSION:
- {
- if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) )
- {
- TokenId aThisToken = aTag.nId;
- SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
- match( aTag, aTag );
- Paragraph();
- if ( aThisToken == TAG_GRAPHIC )
- match( aTag, TAG_ENDGRAPHIC );
- else
- match( aTag, TAG_VERSIONEND );
- // don't reset since alowed only once per paragraph
- // RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
- }
- else
- {
- ParseError( 11, "Tags <#GRAPHIC>,<#NEXTVERSION> allowed only once per paragraph at", aTag );
- }
- }
- break;
- case TAG_AVIS:
- case TAG_AHID:
- {
- if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) )
- {
- TokenId aThisToken = aTag.nId;
- SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
- match( aTag, aTag );
- Paragraph();
- match( aTag, TAG_AEND );
- RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
- }
- else
- {
- ParseError( 11, "Nested <#AHID>,<#AVIS> not allowed.", aTag );
- }
- }
- break;
- case TAG_HREF:
- case TAG_NAME:
- {
-
- }
- // NOBREAK
- case TAG_KEY:
- case TAG_INDEX:
- case TAG_TITEL:
- case TAG_REFSTART:
- {
- if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) )
- {
- TokenId aThisToken = aTag.nId;
- match( aTag, aTag );
- if ( aThisToken != TAG_NAME )
- { // TAG_NAME has no TAG_END
- SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
- Paragraph();
- match( aTag, TAG_END );
- RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
- }
- }
- else
- {
- ParseError( 11, "Nested <#HREF>,<#NAME> or <#KEY> not allowed.", aTag );
- }
- }
- break;
- default:
- ParseError( 12, "<#HREF>,<#NAME> or <#KEY> expected.", aTag );
- }
-}
-
-BOOL TokenParser::match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken )
-{
- return match( aCurrentToken, TokenInfo( aExpectedToken, TOK_INVALIDPOS ) );
-}
-
-BOOL TokenParser::match( const TokenInfo &aCurrentToken, const TokenInfo &rExpectedToken )
-{
- TokenInfo aExpectedToken( rExpectedToken );
- if ( aCurrentToken.nId == aExpectedToken.nId )
- {
- if ( ( aCurrentToken.nId == TAG_COMMONEND
- && aCurrentToken.GetTagName().Equals( aExpectedToken.GetTagName() ) )
- || aCurrentToken.nId != TAG_COMMONEND )
- {
- aTag = aParser.GetNextToken( *pErrorList );
- return TRUE;
- }
- }
-
- if ( aExpectedToken.nId == TAG_COMMONEND )
- {
- aExpectedToken.aTokenString.Insert( String::CreateFromAscii( "Close tag for " ), 0 );
- }
-
- ByteString sTmp( "Expected Symbol" );
- if ( aCurrentToken.nId == TAG_NOMORETAGS )
- {
- ParseError( 7, sTmp, aExpectedToken );
- }
- else
- {
- sTmp += ": ";
- sTmp += ByteString( aParser.GetLexem( aExpectedToken ), RTL_TEXTENCODING_UTF8 );
- sTmp += " near ";
- ParseError( 7, sTmp, aCurrentToken );
- }
- return FALSE;
-}
-
-void TokenParser::ParseError( USHORT nErrNr, ByteString aErrMsg, const TokenInfo &rTag )
-{
- pErrorList->AddError( nErrNr, aErrMsg, rTag);
-
- // Das Fehlerhafte Tag ueberspringen
- aTag = aParser.GetNextToken( *pErrorList );
-}
-
-
-ParserMessage::ParserMessage( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag )
- : nErrorNr( PnErrorNr )
- , aErrorText( PaErrorText )
- , nTagBegin( 0 )
- , nTagLength( 0 )
-{
- String aLexem( SimpleParser::GetLexem( rTag ) );
- aErrorText.Append(": ");
- aErrorText += ByteString( aLexem, RTL_TEXTENCODING_UTF8 );
- if ( rTag.nId == TAG_NOMORETAGS )
- aErrorText.Append(" at end of line ");
- else if ( rTag.nPos != TOK_INVALIDPOS )
- {
- aErrorText.Append(" at Position ");
- aErrorText.Append( ByteString::CreateFromInt32( rTag.nPos ) );
- }
- nTagBegin = rTag.nPos;
- nTagLength = aLexem.Len();
-}
-
-ParserError::ParserError( USHORT ErrorNr, ByteString ErrorText, const TokenInfo &rTag )
-: ParserMessage( ErrorNr, ErrorText, rTag )
-{}
-
-ParserWarning::ParserWarning( USHORT ErrorNr, ByteString ErrorText, const TokenInfo &rTag )
-: ParserMessage( ErrorNr, ErrorText, rTag )
-{}
-
-BOOL LingTest::IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens )
-{
- TokenId aTokenId = aToken.nId;
- TokenId aTokenGroup = TAG_GROUP( aTokenId );
- if ( TAG_GROUP_PROGSWITCH == aTokenGroup
- || TAG_REFINSERT == aTokenId
- || TAG_REFSTART == aTokenId
- || TAG_NAME == aTokenId
- || TAG_HREF == aTokenId
- || TAG_AVIS == aTokenId
- || TAG_AHID == aTokenId
- || TAG_GRAPHIC == aTokenId
- || TAG_NEXTVERSION == aTokenId
- || ( TAG_GROUP_META == aTokenGroup && (aMetaTokens & aTokenId) == aTokenId ) )
- {
- if ( TAG_GROUP_META == aTokenGroup )
- aMetaTokens |= aTokenId;
- return TRUE;
- }
- else if ( TAG_COMMONSTART == aTokenId
- || TAG_COMMONEND == aTokenId )
- {
- String aTagName = aToken.GetTagName();
- return !(aTagName.EqualsIgnoreCaseAscii( "comment" )
- || aTagName.EqualsIgnoreCaseAscii( "bookmark_value" )
- || aTagName.EqualsIgnoreCaseAscii( "emph" )
- || aTagName.EqualsIgnoreCaseAscii( "item" )
- || aTagName.EqualsIgnoreCaseAscii( "br" ) );
- }
- return FALSE;
-}
-
-void LingTest::CheckTags( TokenList &aReference, TokenList &aTestee, BOOL bFixTags )
-{
- ULONG i=0,j=0;
- // Clean old Warnings
- while ( aCompareWarningList.Count() )
- {
- delete aCompareWarningList.GetCurObject();
- aCompareWarningList.Remove();
- }
-
- /* in xml tags, do not require the following tags
- comment
- bookmark_value
- emph
- item
- br
- */
-
- // filter uninteresting Tags
- TokenId aMetaTokens = 0;
- for ( i=0 ; i < aReference.Count() ; i++ )
- {
- if ( !IsTagMandatory( aReference.GetObject( i ), aMetaTokens ) )
- aReference.GetObject( i ).SetDone();
- }
-
- aMetaTokens = 0;
- for ( i=0 ; i < aTestee.Count() ; i++ )
- {
- if ( !IsTagMandatory( aTestee.GetObject( i ), aMetaTokens ) )
- aTestee.GetObject( i ).SetDone();
- }
-
- // remove all matching tags
- for ( i=0 ; i < aReference.Count() ; i++ )
- {
- if ( aReference.GetObject( i ).IsDone() )
- continue;
-
- BOOL bTagFound = FALSE;
- for ( j=0 ; j < aTestee.Count() && !bTagFound ; j++ )
- {
- if ( aTestee.GetObject( j ).IsDone() )
- continue;
-
- if ( aReference.GetObject( i ).MatchesTranslation( aTestee.GetObject( j ), FALSE, aCompareWarningList ) )
- {
- aReference.GetObject( i ).SetDone();
- aTestee.GetObject( j ).SetDone();
- bTagFound = TRUE;
- }
- }
- }
-
- BOOL bCanFix = TRUE;
-
- if ( bFixTags )
- {
- // we fix only if its a really simple case
- USHORT nTagCount = 0;
- for ( i=0 ; i < aReference.Count() ; i++ )
- if ( !aReference.GetObject( i ).IsDone() )
- nTagCount++;
- if ( nTagCount > 1 )
- bCanFix = FALSE;
-
- nTagCount = 0;
- for ( i=0 ; i < aTestee.Count() ; i++ )
- if ( !aTestee.GetObject( i ).IsDone() )
- nTagCount++;
- if ( nTagCount > 1 )
- bCanFix = FALSE;
- }
-
- // generate errors for tags that have differing attributes
- for ( i=0 ; i < aReference.Count() ; i++ )
- {
- if ( aReference.GetObject( i ).IsDone() )
- continue;
-
- BOOL bTagFound = FALSE;
- for ( j=0 ; j < aTestee.Count() && !bTagFound ; j++ )
- {
- if ( aTestee.GetObject( j ).IsDone() )
- continue;
-
- if ( aReference.GetObject( i ).MatchesTranslation( aTestee.GetObject( j ), TRUE, aCompareWarningList, bCanFix && bFixTags ) )
- {
- aReference.GetObject( i ).SetDone();
- aTestee.GetObject( j ).SetDone();
- bTagFound = TRUE;
- }
- }
- }
-
- // list remaining tags as errors
- for ( i=0 ; i < aReference.Count() ; i++ )
- {
- if ( aReference.GetObject( i ).IsDone() )
- continue;
-
- aCompareWarningList.AddError( 20, "Missing Tag in Translation", aReference.GetObject( i ) );
- }
- for ( i=0 ; i < aTestee.Count() ; i++ )
- {
- if ( aTestee.GetObject( i ).IsDone() )
- continue;
-
- aCompareWarningList.AddError( 21, "Extra Tag in Translation", aTestee.GetObject( i ) );
- }
-
- for ( i=0 ; i < aReference.Count() ; i++ )
- aReference.GetObject( i ).SetDone( FALSE );
-
- for ( i=0 ; i < aTestee.Count() ; i++ )
- aTestee.GetObject( i ).SetDone( FALSE );
-}
-
-void LingTest::CheckReference( GSILine *aReference )
-{
- aReferenceParser.Parse( aReference->GetUText(), aReference->GetMessageList() );
-}
-
-void LingTest::CheckTestee( GSILine *aTestee, BOOL bHasSourceLine, BOOL bFixTags )
-{
- aFixedTestee = aTestee->GetUText();
- aTesteeParser.Parse( aFixedTestee, aTestee->GetMessageList() );
-
- if ( bHasSourceLine )
- CheckTags( aReferenceParser.GetTokenList(), aTesteeParser.GetTokenList(), bFixTags );
-
- if ( bFixTags )
- {
- TokenList& aTesteeTokens = aTesteeParser.GetTokenList();
- BOOL bFixesDone = FALSE;
- // count backwards to allow replacing from right to left
- int i;
- for ( i=aTesteeTokens.Count()-1 ; i>=0 ; i-- )
- {
- if ( aTesteeTokens.GetObject( i ).HasBeenFixed() )
- {
- bFixesDone = TRUE;
- aFixedTestee.Replace( aTesteeTokens.GetObject( i ).nPos, aTesteeTokens.GetObject( i ).aTokenString.Len(), aTesteeTokens.GetObject( i ).MakeTag() );
- }
- }
- if ( bFixesDone )
- {
- aTestee->SetUText( aFixedTestee );
- aTestee->SetFixed();
- }
- }
-}
-