1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
31 #include <tools/string.hxx>
32 #include <tools/list.hxx>
33 #include <hash_map> /* std::hashmap*/
37 typedef USHORT TokenId
;
39 #define TOK_INVALIDPOS USHORT( 0xFFFF )
43 DECLARE_LIST( Impl_ParserMessageList
, ParserMessage
* )
44 class ParserMessageList
;
47 struct equalByteString
{
48 bool operator()( const ByteString
& rKey1
, const ByteString
& rKey2
) const {
49 return rKey1
.CompareTo( rKey2
)==COMPARE_EQUAL
;
52 struct lessByteString
{
53 bool operator()( const ByteString
& rKey1
, const ByteString
& rKey2
) const {
54 return rKey1
.CompareTo( rKey2
)==COMPARE_LESS
;
58 struct hashByteString
{
59 size_t operator()( const ByteString
& rName
) const{
60 std::hash
< const char* > myHash
;
61 return myHash( rName
.GetBuffer() );
67 typedef std::hash_map
<ByteString
, String
, hashByteString
,equalByteString
>
73 void SplitTag( ParserMessageList
&rErrorList
);
76 StringHashMap aProperties
;
77 BOOL bClosed
; // tag is closed <sdnf/>
78 BOOL bCloseTag
; // tag is close Tag </sdnf>
89 USHORT nPos
; // Position in String
91 TokenInfo():bClosed(FALSE
),bCloseTag(FALSE
),bIsBroken(FALSE
),bHasBeenFixed(FALSE
),bDone(FALSE
),nId( 0 ){;}
92 explicit TokenInfo( TokenId pnId
, USHORT nP
):bClosed(FALSE
),bCloseTag(FALSE
),bIsBroken(FALSE
),bHasBeenFixed(FALSE
),bDone(FALSE
),nId( pnId
),nPos(nP
){;}
93 explicit TokenInfo( TokenId pnId
, USHORT nP
, String paStr
):bClosed(FALSE
),bCloseTag(FALSE
),bIsBroken(FALSE
),bHasBeenFixed(FALSE
),bDone(FALSE
),aTokenString( paStr
),nId( pnId
),nPos(nP
) {;}
94 explicit TokenInfo( TokenId pnId
, USHORT nP
, String paStr
, ParserMessageList
&rErrorList
);
96 String
GetTagName() const;
98 String
MakeTag() const;
101 Is the property to be ignored or does it have the default value anyways
103 BOOL
IsPropertyRelevant( const ByteString
&aName
, const String
&aValue
) const;
104 BOOL
IsPropertyValueValid( const ByteString
&aName
, const String
&aValue
) const;
106 Does the property contain the same value for all languages
107 e.g.: the href in a link tag
109 BOOL
IsPropertyInvariant( const ByteString
&aName
, const String
&aValue
) const;
111 a subset of IsPropertyInvariant but containing only those that are fixable
112 we dont wat to fix e.g.: ahelp :: visibility
114 BOOL
IsPropertyFixable( const ByteString
&aName
) const;
115 BOOL
MatchesTranslation( TokenInfo
& rInfo
, BOOL bGenErrors
, ParserMessageList
&rErrorList
, BOOL bFixTags
= FALSE
) const;
117 BOOL
IsDone() const { return bDone
; }
118 void SetDone( BOOL bNew
= TRUE
) { bDone
= bNew
; }
120 BOOL
HasBeenFixed() const { return bHasBeenFixed
; }
121 void SetHasBeenFixed( BOOL bNew
= TRUE
) { bHasBeenFixed
= bNew
; }
125 class ParserMessageList
: public Impl_ParserMessageList
128 void AddError( USHORT nErrorNr
, ByteString aErrorText
, const TokenInfo
&rTag
);
129 void AddWarning( USHORT nErrorNr
, ByteString aErrorText
, const TokenInfo
&rTag
);
135 #define TAG_GROUPMASK 0xF000
136 #define TAG_GROUPSHIFT 12
138 #define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT )
139 #define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT
141 #define TAG_NOMORETAGS 0x0
143 #define TAG_GROUP_FORMAT 0x1
145 #define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 )
146 #define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 )
147 #define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 )
148 #define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 )
149 #define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 )
150 #define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 )
152 #define TAG_GROUP_NOTALLOWED 0x2
153 #define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 )
154 #define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 )
155 #define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 )
157 #define TAG_GROUP_STRUCTURE 0x3
158 #define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 )
159 #define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 )
160 #define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 )
161 #define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 )
163 #define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 )
164 #define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 )
165 #define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 )
167 #define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 )
169 #define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 )
170 #define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 )
172 #define TAG_GROUP_SYSSWITCH 0x4
173 #define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 )
174 #define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 )
175 #define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 )
176 #define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 )
178 #define TAG_GROUP_PROGSWITCH 0x5
179 #define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 )
180 #define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 )
181 #define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 )
182 #define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 )
183 #define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 )
184 #define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 )
185 #define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 )
186 #define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 )
187 #define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 )
190 #define TAG_GROUP_META 0x6
191 #define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 )
192 #define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 )
193 #define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 )
194 #define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 )
195 #define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 )
196 #define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 )
197 #define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 )
198 #define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 )
199 #define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 )
202 #define TAG_GROUP_SINGLE 0x7
203 #define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 )
206 #define TAG_GROUP_MULTI 0x8
207 #define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 )
208 #define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 )
209 #define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 )
210 #define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 )
211 #define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 )
213 #define TAG_GROUP_MISC 0x9
214 #define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 )
215 #define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 )
217 #define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 )
219 DECLARE_LIST( TokenListImpl
, TokenInfo
* )
221 class TokenList
: private TokenListImpl
225 TokenList
& operator =( const TokenList
& rList
);
226 // { TokenListImpl::operator =( rList ); return *this; }
230 using TokenListImpl::Count
;
233 TokenList() : TokenListImpl(){};
234 ~TokenList(){ Clear(); };
238 for ( ULONG i
= 0 ; i
< Count() ; i
++ )
239 delete TokenListImpl::GetObject( i
);
240 TokenListImpl::Clear();
242 void Insert( TokenInfo p
, ULONG nIndex
= LIST_APPEND
)
243 { TokenListImpl::Insert( new TokenInfo(p
), nIndex
); }
244 /* TokenInfo Remove( ULONG nIndex )
246 TokenInfo aT = GetObject( nIndex );
247 delete TokenListImpl::GetObject( nIndex );
248 TokenListImpl::Remove( nIndex );
251 // TokenInfo Remove( TokenInfo p ){ return Remove( GetPos( p ) ); }
252 // TokenInfo GetCurObject() const { return *TokenListImpl::GetCurObject(); }
253 TokenInfo
& GetObject( ULONG nIndex
) const
255 // if ( TokenListImpl::GetObject(nIndex) )
256 return *TokenListImpl::GetObject(nIndex
);
258 // return TokenInfo();
260 /* ULONG GetPos( const TokenInfo p ) const
262 for ( ULONG i = 0 ; i < Count() ; i++ )
263 if ( p == GetObject( i ) )
265 return LIST_ENTRY_NOTFOUND;
268 TokenList( const TokenList
& rList
);
270 for ( ULONG i = 0 ; i < rList.Count() ; i++ )
272 Insert( rList.GetObject( i ), LIST_APPEND );
280 ByteString aErrorText
;
281 USHORT nTagBegin
,nTagLength
;
284 ParserMessage( USHORT PnErrorNr
, ByteString PaErrorText
, const TokenInfo
&rTag
);
287 USHORT
GetErrorNr() { return nErrorNr
; }
288 ByteString
GetErrorText() { return aErrorText
; }
290 USHORT
GetTagBegin() { return nTagBegin
; }
291 USHORT
GetTagLength() { return nTagLength
; }
293 virtual ~ParserMessage() {}
294 virtual BOOL
IsError() =0;
295 virtual ByteString
Prefix() =0;
298 class ParserError
: public ParserMessage
301 ParserError( USHORT PnErrorNr
, ByteString PaErrorText
, const TokenInfo
&rTag
);
303 virtual BOOL
IsError() {return TRUE
;};
304 virtual ByteString
Prefix() {return "Error:"; };
307 class ParserWarning
: public ParserMessage
310 ParserWarning( USHORT PnErrorNr
, ByteString PaErrorText
, const TokenInfo
&rTag
);
312 virtual BOOL
IsError() {return FALSE
;};
313 virtual ByteString
Prefix() {return "Warning:"; };
322 TokenList aTokenList
;
324 TokenInfo aNextTag
; // to store closetag in case of combined tags like <br/>
326 String
GetNextTokenString( ParserMessageList
&rErrorList
, USHORT
&rTokeStartPos
);
330 void Parse( String PaSource
);
331 TokenInfo
GetNextToken( ParserMessageList
&rErrorList
);
332 static String
GetLexem( TokenInfo
const &aToken
);
333 TokenList
& GetTokenList(){ return aTokenList
; }
338 BOOL
match( const TokenInfo
&aCurrentToken
, const TokenId
&aExpectedToken
);
339 BOOL
match( const TokenInfo
&aCurrentToken
, const TokenInfo
&aExpectedToken
);
340 void ParseError( USHORT nErrNr
, ByteString aErrMsg
, const TokenInfo
&rTag
);
351 SimpleParser aParser
;
354 TokenId nPfCaseOptions
;
355 TokenId nAppCaseOptions
;
356 BOOL bPfCaseActive
,bAppCaseActive
;
358 TokenId nActiveRefTypes
;
360 ParserMessageList
*pErrorList
;
364 void Parse( const String
&aCode
, ParserMessageList
* pList
);
365 // ParserMessageList& GetErrors(){ return aErrorList; }
366 // BOOL HasErrors(){ return ( aErrorList.Count() > 0 ); }
367 TokenList
& GetTokenList(){ return aParser
.GetTokenList(); }
373 TokenParser aReferenceParser
;
374 TokenParser aTesteeParser
;
375 ParserMessageList aCompareWarningList
;
376 void CheckTags( TokenList
&aReference
, TokenList
&aTestee
, BOOL bFixTags
);
377 BOOL
IsTagMandatory( TokenInfo
const &aToken
, TokenId
&aMetaTokens
);
380 void CheckReference( GSILine
*aReference
);
381 void CheckTestee( GSILine
*aTestee
, BOOL bHasSourceLine
, BOOL bFixTags
);
383 // ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); }
384 // BOOL HasReferenceErrors(){ return aReferenceParser.HasErrors(); }
386 // ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); }
387 // BOOL HasTesteeErrors(){ return aTesteeParser.HasErrors(); }
389 ParserMessageList
& GetCompareWarnings(){ return aCompareWarningList
; }
390 BOOL
HasCompareWarnings(){ return ( aCompareWarningList
.Count() > 0 ); }
392 String
GetFixedTestee(){ return aFixedTestee
; }