/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: tagtest.hxx,v $ * * $Revision: 1.9 $ * * last change: $Author: kz $ $Date: 2005-10-06 12:43:27 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ #ifndef _TAGTEST_HXX_ #define _TAGTEST_HXX_ #ifndef _STRING_HXX #include #endif #ifndef _LIST_HXX #include #endif #include /* std::hashmap*/ class GSILine; typedef USHORT TokenId; #define TOK_INVALIDPOS USHORT( 0xFFFF ) class ParserMessage; DECLARE_LIST( Impl_ParserMessageList, ParserMessage* ); class ParserMessageList; struct equalByteString{ bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL; } }; struct lessByteString{ bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const { return rKey1.CompareTo( rKey2 )==COMPARE_LESS; } }; struct hashByteString{ size_t operator()( const ByteString& rName ) const{ std::hash< const char* > myHash; return myHash( rName.GetBuffer() ); } }; typedef std::hash_map StringHashMap; class TokenInfo { private: void SplitTag( ParserMessageList &rErrorList ); String aTagName; StringHashMap aProperties; BOOL bClosed; // tag is closed BOOL bCloseTag; // tag is close Tag BOOL bIsBroken; BOOL bHasBeenFixed; BOOL bDone; public: String aTokenString; TokenId nId; USHORT nPos; // Position in String TokenInfo():nId( 0 ),bIsBroken(FALSE),bHasBeenFixed(FALSE),bDone(FALSE),bClosed(FALSE),bCloseTag(FALSE){;} explicit TokenInfo( TokenId pnId, USHORT nP ):nId( pnId ),nPos(nP),bIsBroken(FALSE),bHasBeenFixed(FALSE),bDone(FALSE),bClosed(FALSE),bCloseTag(FALSE){;} explicit TokenInfo( TokenId pnId, USHORT nP, String paStr ):nId( pnId ), nPos(nP), aTokenString( paStr ),bIsBroken(FALSE),bHasBeenFixed(FALSE),bDone(FALSE),bClosed(FALSE),bCloseTag(FALSE){;} explicit TokenInfo( TokenId pnId, USHORT nP, String paStr, ParserMessageList &rErrorList ); String GetTagName() const; String MakeTag() const; /** Is the property to be ignored or does it have the default value anyways **/ BOOL IsPropertyRelevant( const ByteString &aName, const String &aValue ) const; BOOL IsPropertyValueValid( const ByteString &aName, const String &aValue ) const; /** Does the property contain the same value for all languages e.g.: the href in a link tag **/ BOOL IsPropertyInvariant( const ByteString &aName ) const; /** a subset of IsPropertyInvariant but containing only those that are fixable we dont wat to fix e.g.: ahelp :: visibility **/ BOOL IsPropertyFixable( const ByteString &aName ) const; BOOL MatchesTranslation( TokenInfo& rInfo, BOOL bGenErrors, ParserMessageList &rErrorList, BOOL bFixTags = FALSE ) const; BOOL IsDone() const { return bDone; } void SetDone( BOOL bNew = TRUE ) { bDone = bNew; } BOOL HasBeenFixed() const { return bHasBeenFixed; } void SetHasBeenFixed( BOOL bNew = TRUE ) { bHasBeenFixed = bNew; } }; class ParserMessageList : public Impl_ParserMessageList { public: void AddError( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag ); void AddWarning( USHORT nErrorNr, ByteString aErrorText, const TokenInfo &rTag ); BOOL HasErrors(); }; #define TAG_GROUPMASK 0xF000 #define TAG_GROUPSHIFT 12 #define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT ) #define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT #define TAG_NOMORETAGS 0x0 #define TAG_GROUP_FORMAT 0x1 #define TAG_ON 0x100 #define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 ) #define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 ) #define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 ) #define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 ) #define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 ) #define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 ) #define TAG_GROUP_NOTALLOWED 0x2 #define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 ) #define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 ) #define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 ) #define TAG_GROUP_STRUCTURE 0x3 #define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 ) #define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 ) #define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 ) #define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 ) #define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 ) #define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 ) #define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 ) #define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 ) #define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 ) #define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 ) #define TAG_GROUP_SYSSWITCH 0x4 #define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 ) #define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 ) #define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 ) #define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 ) #define TAG_GROUP_PROGSWITCH 0x5 #define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 ) #define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 ) #define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 ) #define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 ) #define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 ) #define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 ) #define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 ) #define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 ) #define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 ) #define TAG_GROUP_META 0x6 #define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 ) #define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 ) #define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 ) #define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 ) #define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 ) #define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 ) #define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 ) #define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 ) #define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 ) #define TAG_GROUP_SINGLE 0x7 #define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 ) #define TAG_GROUP_MULTI 0x8 #define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 ) #define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 ) #define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 ) #define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 ) #define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 ) #define TAG_GROUP_MISC 0x9 #define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 ) #define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 ) #define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 ) DECLARE_LIST( TokenListImpl, TokenInfo* ); class TokenList : private TokenListImpl { private: TokenList& operator =( const TokenList& rList ); // { TokenListImpl::operator =( rList ); return *this; } public: TokenListImpl::Count; TokenList() : TokenListImpl(){}; ~TokenList(){ Clear(); }; void Clear() { for ( ULONG i = 0 ; i < Count() ; i++ ) delete TokenListImpl::GetObject( i ); TokenListImpl::Clear(); } void Insert( TokenInfo p, ULONG nIndex = LIST_APPEND ) { TokenListImpl::Insert( new TokenInfo(p), nIndex ); } /* TokenInfo Remove( ULONG nIndex ) { TokenInfo aT = GetObject( nIndex ); delete TokenListImpl::GetObject( nIndex ); TokenListImpl::Remove( nIndex ); return aT; }*/ // TokenInfo Remove( TokenInfo p ){ return Remove( GetPos( p ) ); } // TokenInfo GetCurObject() const { return *TokenListImpl::GetCurObject(); } TokenInfo& GetObject( ULONG nIndex ) const { // if ( TokenListImpl::GetObject(nIndex) ) return *TokenListImpl::GetObject(nIndex); // else // return TokenInfo(); } /* ULONG GetPos( const TokenInfo p ) const { for ( ULONG i = 0 ; i < Count() ; i++ ) if ( p == GetObject( i ) ) return i; return LIST_ENTRY_NOTFOUND; }*/ TokenList( const TokenList& rList ); /* { for ( ULONG i = 0 ; i < rList.Count() ; i++ ) { Insert( rList.GetObject( i ), LIST_APPEND ); } }*/ }; class ParserMessage { USHORT nErrorNr; ByteString aErrorText; USHORT nTagBegin,nTagLength; protected: ParserMessage( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ); public: USHORT GetErrorNr() { return nErrorNr; } ByteString GetErrorText() { return aErrorText; } USHORT GetTagBegin() { return nTagBegin; } USHORT GetTagLength() { return nTagLength; } virtual BOOL IsError() =0; virtual ByteString Prefix() =0; }; class ParserError : public ParserMessage { public: ParserError( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ); virtual BOOL IsError() {return TRUE;}; virtual ByteString Prefix() {return "Error:"; }; }; class ParserWarning : public ParserMessage { public: ParserWarning( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag ); virtual BOOL IsError() {return FALSE;}; virtual ByteString Prefix() {return "Warning:"; }; }; class SimpleParser { private: USHORT nPos; String aSource; String aLastToken; TokenList aTokenList; TokenInfo aNextTag; // to store closetag in case of combined tags like
String GetNextTokenString( ParserMessageList &rErrorList, USHORT &rTokeStartPos ); public: SimpleParser(); void Parse( String PaSource ); TokenInfo GetNextToken( ParserMessageList &rErrorList ); static String GetLexem( TokenInfo const &aToken ); TokenList& GetTokenList(){ return aTokenList; } }; class TokenParser { BOOL match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken ); BOOL match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken ); void ParseError( USHORT nErrNr, ByteString aErrMsg, const TokenInfo &rTag ); void Paragraph(); void PfCase(); void PfCaseBegin(); void AppCase(); void AppCaseBegin(); void CaseEnd(); void SimpleTag(); void TagPair(); void TagRef(); SimpleParser aParser; TokenInfo aTag; TokenId nPfCaseOptions; TokenId nAppCaseOptions; BOOL bPfCaseActive ,bAppCaseActive; TokenId nActiveRefTypes; ParserMessageList *pErrorList; public: TokenParser(); void Parse( const String &aCode, ParserMessageList* pList ); // ParserMessageList& GetErrors(){ return aErrorList; } // BOOL HasErrors(){ return ( aErrorList.Count() > 0 ); } TokenList& GetTokenList(){ return aParser.GetTokenList(); } }; class LingTest { private: TokenParser aReferenceParser; TokenParser aTesteeParser; ParserMessageList aCompareWarningList; void CheckTags( TokenList &aReference, TokenList &aTestee, BOOL bFixTags ); BOOL IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens ); String aFixedTestee; public: void CheckReference( GSILine *aReference ); void CheckTestee( GSILine *aTestee, BOOL bHasSourceLine, BOOL bFixTags ); // ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); } // BOOL HasReferenceErrors(){ return aReferenceParser.HasErrors(); } // ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); } // BOOL HasTesteeErrors(){ return aTesteeParser.HasErrors(); } ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; } BOOL HasCompareWarnings(){ return ( aCompareWarningList.Count() > 0 ); } String GetFixedTestee(){ return aFixedTestee; } }; #endif