1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tagtest.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <tools/string.hxx>
35 #include <tools/list.hxx>
36 #include <hash_map> /* std::hashmap*/
40 typedef USHORT TokenId
;
42 #define TOK_INVALIDPOS USHORT( 0xFFFF )
46 DECLARE_LIST( Impl_ParserMessageList
, ParserMessage
* )
47 class ParserMessageList
;
50 struct equalByteString
{
51 bool operator()( const ByteString
& rKey1
, const ByteString
& rKey2
) const {
52 return rKey1
.CompareTo( rKey2
)==COMPARE_EQUAL
;
55 struct lessByteString
{
56 bool operator()( const ByteString
& rKey1
, const ByteString
& rKey2
) const {
57 return rKey1
.CompareTo( rKey2
)==COMPARE_LESS
;
61 struct hashByteString
{
62 size_t operator()( const ByteString
& rName
) const{
63 std::hash
< const char* > myHash
;
64 return myHash( rName
.GetBuffer() );
70 typedef std::hash_map
<ByteString
, String
, hashByteString
,equalByteString
>
76 void SplitTag( ParserMessageList
&rErrorList
);
79 StringHashMap aProperties
;
80 BOOL bClosed
; // tag is closed <sdnf/>
81 BOOL bCloseTag
; // tag is close Tag </sdnf>
92 USHORT nPos
; // Position in String
94 TokenInfo():bClosed(FALSE
),bCloseTag(FALSE
),bIsBroken(FALSE
),bHasBeenFixed(FALSE
),bDone(FALSE
),nId( 0 ){;}
95 explicit TokenInfo( TokenId pnId
, USHORT nP
):bClosed(FALSE
),bCloseTag(FALSE
),bIsBroken(FALSE
),bHasBeenFixed(FALSE
),bDone(FALSE
),nId( pnId
),nPos(nP
){;}
96 explicit TokenInfo( TokenId pnId
, USHORT nP
, String paStr
):bClosed(FALSE
),bCloseTag(FALSE
),bIsBroken(FALSE
),bHasBeenFixed(FALSE
),bDone(FALSE
),aTokenString( paStr
),nId( pnId
),nPos(nP
) {;}
97 explicit TokenInfo( TokenId pnId
, USHORT nP
, String paStr
, ParserMessageList
&rErrorList
);
99 String
GetTagName() const;
101 String
MakeTag() const;
104 Is the property to be ignored or does it have the default value anyways
106 BOOL
IsPropertyRelevant( const ByteString
&aName
, const String
&aValue
) const;
107 BOOL
IsPropertyValueValid( const ByteString
&aName
, const String
&aValue
) const;
109 Does the property contain the same value for all languages
110 e.g.: the href in a link tag
112 BOOL
IsPropertyInvariant( const ByteString
&aName
, const String
&aValue
) const;
114 a subset of IsPropertyInvariant but containing only those that are fixable
115 we dont wat to fix e.g.: ahelp :: visibility
117 BOOL
IsPropertyFixable( const ByteString
&aName
) const;
118 BOOL
MatchesTranslation( TokenInfo
& rInfo
, BOOL bGenErrors
, ParserMessageList
&rErrorList
, BOOL bFixTags
= FALSE
) const;
120 BOOL
IsDone() const { return bDone
; }
121 void SetDone( BOOL bNew
= TRUE
) { bDone
= bNew
; }
123 BOOL
HasBeenFixed() const { return bHasBeenFixed
; }
124 void SetHasBeenFixed( BOOL bNew
= TRUE
) { bHasBeenFixed
= bNew
; }
128 class ParserMessageList
: public Impl_ParserMessageList
131 void AddError( USHORT nErrorNr
, ByteString aErrorText
, const TokenInfo
&rTag
);
132 void AddWarning( USHORT nErrorNr
, ByteString aErrorText
, const TokenInfo
&rTag
);
138 #define TAG_GROUPMASK 0xF000
139 #define TAG_GROUPSHIFT 12
141 #define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT )
142 #define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT
144 #define TAG_NOMORETAGS 0x0
146 #define TAG_GROUP_FORMAT 0x1
148 #define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 )
149 #define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 )
150 #define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 )
151 #define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 )
152 #define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 )
153 #define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 )
155 #define TAG_GROUP_NOTALLOWED 0x2
156 #define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 )
157 #define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 )
158 #define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 )
160 #define TAG_GROUP_STRUCTURE 0x3
161 #define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 )
162 #define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 )
163 #define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 )
164 #define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 )
166 #define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 )
167 #define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 )
168 #define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 )
170 #define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 )
172 #define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 )
173 #define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 )
175 #define TAG_GROUP_SYSSWITCH 0x4
176 #define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 )
177 #define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 )
178 #define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 )
179 #define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 )
181 #define TAG_GROUP_PROGSWITCH 0x5
182 #define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 )
183 #define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 )
184 #define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 )
185 #define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 )
186 #define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 )
187 #define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 )
188 #define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 )
189 #define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 )
190 #define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 )
193 #define TAG_GROUP_META 0x6
194 #define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 )
195 #define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 )
196 #define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 )
197 #define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 )
198 #define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 )
199 #define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 )
200 #define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 )
201 #define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 )
202 #define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 )
205 #define TAG_GROUP_SINGLE 0x7
206 #define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 )
209 #define TAG_GROUP_MULTI 0x8
210 #define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 )
211 #define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 )
212 #define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 )
213 #define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 )
214 #define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 )
216 #define TAG_GROUP_MISC 0x9
217 #define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 )
218 #define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 )
220 #define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 )
222 DECLARE_LIST( TokenListImpl
, TokenInfo
* )
224 class TokenList
: private TokenListImpl
228 TokenList
& operator =( const TokenList
& rList
);
229 // { TokenListImpl::operator =( rList ); return *this; }
233 using TokenListImpl::Count
;
236 TokenList() : TokenListImpl(){};
237 ~TokenList(){ Clear(); };
241 for ( ULONG i
= 0 ; i
< Count() ; i
++ )
242 delete TokenListImpl::GetObject( i
);
243 TokenListImpl::Clear();
245 void Insert( TokenInfo p
, ULONG nIndex
= LIST_APPEND
)
246 { TokenListImpl::Insert( new TokenInfo(p
), nIndex
); }
247 /* TokenInfo Remove( ULONG nIndex )
249 TokenInfo aT = GetObject( nIndex );
250 delete TokenListImpl::GetObject( nIndex );
251 TokenListImpl::Remove( nIndex );
254 // TokenInfo Remove( TokenInfo p ){ return Remove( GetPos( p ) ); }
255 // TokenInfo GetCurObject() const { return *TokenListImpl::GetCurObject(); }
256 TokenInfo
& GetObject( ULONG nIndex
) const
258 // if ( TokenListImpl::GetObject(nIndex) )
259 return *TokenListImpl::GetObject(nIndex
);
261 // return TokenInfo();
263 /* ULONG GetPos( const TokenInfo p ) const
265 for ( ULONG i = 0 ; i < Count() ; i++ )
266 if ( p == GetObject( i ) )
268 return LIST_ENTRY_NOTFOUND;
271 TokenList( const TokenList
& rList
);
273 for ( ULONG i = 0 ; i < rList.Count() ; i++ )
275 Insert( rList.GetObject( i ), LIST_APPEND );
283 ByteString aErrorText
;
284 USHORT nTagBegin
,nTagLength
;
287 ParserMessage( USHORT PnErrorNr
, ByteString PaErrorText
, const TokenInfo
&rTag
);
290 USHORT
GetErrorNr() { return nErrorNr
; }
291 ByteString
GetErrorText() { return aErrorText
; }
293 USHORT
GetTagBegin() { return nTagBegin
; }
294 USHORT
GetTagLength() { return nTagLength
; }
296 virtual ~ParserMessage() {}
297 virtual BOOL
IsError() =0;
298 virtual ByteString
Prefix() =0;
301 class ParserError
: public ParserMessage
304 ParserError( USHORT PnErrorNr
, ByteString PaErrorText
, const TokenInfo
&rTag
);
306 virtual BOOL
IsError() {return TRUE
;};
307 virtual ByteString
Prefix() {return "Error:"; };
310 class ParserWarning
: public ParserMessage
313 ParserWarning( USHORT PnErrorNr
, ByteString PaErrorText
, const TokenInfo
&rTag
);
315 virtual BOOL
IsError() {return FALSE
;};
316 virtual ByteString
Prefix() {return "Warning:"; };
325 TokenList aTokenList
;
327 TokenInfo aNextTag
; // to store closetag in case of combined tags like <br/>
329 String
GetNextTokenString( ParserMessageList
&rErrorList
, USHORT
&rTokeStartPos
);
333 void Parse( String PaSource
);
334 TokenInfo
GetNextToken( ParserMessageList
&rErrorList
);
335 static String
GetLexem( TokenInfo
const &aToken
);
336 TokenList
& GetTokenList(){ return aTokenList
; }
341 BOOL
match( const TokenInfo
&aCurrentToken
, const TokenId
&aExpectedToken
);
342 BOOL
match( const TokenInfo
&aCurrentToken
, const TokenInfo
&aExpectedToken
);
343 void ParseError( USHORT nErrNr
, ByteString aErrMsg
, const TokenInfo
&rTag
);
354 SimpleParser aParser
;
357 TokenId nPfCaseOptions
;
358 TokenId nAppCaseOptions
;
359 BOOL bPfCaseActive
,bAppCaseActive
;
361 TokenId nActiveRefTypes
;
363 ParserMessageList
*pErrorList
;
367 void Parse( const String
&aCode
, ParserMessageList
* pList
);
368 // ParserMessageList& GetErrors(){ return aErrorList; }
369 // BOOL HasErrors(){ return ( aErrorList.Count() > 0 ); }
370 TokenList
& GetTokenList(){ return aParser
.GetTokenList(); }
376 TokenParser aReferenceParser
;
377 TokenParser aTesteeParser
;
378 ParserMessageList aCompareWarningList
;
379 void CheckTags( TokenList
&aReference
, TokenList
&aTestee
, BOOL bFixTags
);
380 BOOL
IsTagMandatory( TokenInfo
const &aToken
, TokenId
&aMetaTokens
);
383 void CheckReference( GSILine
*aReference
);
384 void CheckTestee( GSILine
*aTestee
, BOOL bHasSourceLine
, BOOL bFixTags
);
386 // ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); }
387 // BOOL HasReferenceErrors(){ return aReferenceParser.HasErrors(); }
389 // ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); }
390 // BOOL HasTesteeErrors(){ return aTesteeParser.HasErrors(); }
392 ParserMessageList
& GetCompareWarnings(){ return aCompareWarningList
; }
393 BOOL
HasCompareWarnings(){ return ( aCompareWarningList
.Count() > 0 ); }
395 String
GetFixedTestee(){ return aFixedTestee
; }