diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2010-01-25 17:20:55 +0100 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2010-01-25 17:20:55 +0100 |
commit | 282d42b81a5ae3f9f7be1a70218ae8df91d256a3 (patch) | |
tree | 675ac0d589e9a6696fa7ceb6281695a586aeb798 /transex3/source/tagtest.cxx | |
parent | 60e367c8168aa3193df0ba4d64a803e909c18f11 (diff) |
l10ntools: #i108657# rename transex3 to l10ntools
Diffstat (limited to 'transex3/source/tagtest.cxx')
-rw-r--r-- | transex3/source/tagtest.cxx | 1577 |
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(); - } - } -} - |