1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef _TAGTEST_HXX_
25 #define _TAGTEST_HXX_
26
27 #include <tools/string.hxx>
28 #include <tools/list.hxx>
29 #include <hash_map> /* std::hashmap*/
30 #include <rtl/string.h>
31
32 class GSILine;
33
34 typedef sal_uInt16 TokenId;
35
36 #define TOK_INVALIDPOS sal_uInt16( 0xFFFF )
37
38 class ParserMessage;
39
40 DECLARE_LIST( Impl_ParserMessageList, ParserMessage* )
41 class ParserMessageList;
42
43
44 struct equalByteString{
operator ()equalByteString45 bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const {
46 return rKey1.CompareTo( rKey2 )==COMPARE_EQUAL;
47 }
48 };
49 struct lessByteString{
operator ()lessByteString50 bool operator()( const ByteString& rKey1, const ByteString& rKey2 ) const {
51 return rKey1.CompareTo( rKey2 )==COMPARE_LESS;
52 }
53 };
54
55 struct hashByteString{
operator ()hashByteString56 size_t operator()( const ByteString& rName ) const{
57 return rtl_str_hashCode_WithLength( rName.GetBuffer(), rName.Len());
58 }
59 };
60
61
62
63 typedef std::hash_map<ByteString , String , hashByteString,equalByteString>
64 StringHashMap;
65
66 class TokenInfo
67 {
68 private:
69 void SplitTag( ParserMessageList &rErrorList );
70
71 String aTagName;
72 StringHashMap aProperties;
73 sal_Bool bClosed; // tag is closed <sdnf/>
74 sal_Bool bCloseTag; // tag is close Tag </sdnf>
75
76
77 sal_Bool bIsBroken;
78 sal_Bool bHasBeenFixed;
79 sal_Bool bDone;
80
81 public:
82
83 String aTokenString;
84 TokenId nId;
85 sal_uInt16 nPos; // Position in String
86
TokenInfo()87 TokenInfo():bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),nId( 0 ){;}
TokenInfo(TokenId pnId,sal_uInt16 nP)88 explicit TokenInfo( TokenId pnId, sal_uInt16 nP ):bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),nId( pnId ),nPos(nP){;}
TokenInfo(TokenId pnId,sal_uInt16 nP,String paStr)89 explicit TokenInfo( TokenId pnId, sal_uInt16 nP, String paStr ):bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),aTokenString( paStr ),nId( pnId ),nPos(nP) {;}
90 explicit TokenInfo( TokenId pnId, sal_uInt16 nP, String paStr, ParserMessageList &rErrorList );
91
92 String GetTagName() const;
93
94 String MakeTag() const;
95
96 /**
97 Is the property to be ignored or does it have the default value anyways
98 **/
99 sal_Bool IsPropertyRelevant( const ByteString &aName, const String &aValue ) const;
100 sal_Bool IsPropertyValueValid( const ByteString &aName, const String &aValue ) const;
101 /**
102 Does the property contain the same value for all languages
103 e.g.: the href in a link tag
104 **/
105 sal_Bool IsPropertyInvariant( const ByteString &aName, const String &aValue ) const;
106 /**
107 a subset of IsPropertyInvariant but containing only those that are fixable
108 we dont wat to fix e.g.: ahelp :: visibility
109 **/
110 sal_Bool IsPropertyFixable( const ByteString &aName ) const;
111 sal_Bool MatchesTranslation( TokenInfo& rInfo, sal_Bool bGenErrors, ParserMessageList &rErrorList, sal_Bool bFixTags = sal_False ) const;
112
IsDone() const113 sal_Bool IsDone() const { return bDone; }
SetDone(sal_Bool bNew=sal_True)114 void SetDone( sal_Bool bNew = sal_True ) { bDone = bNew; }
115
HasBeenFixed() const116 sal_Bool HasBeenFixed() const { return bHasBeenFixed; }
SetHasBeenFixed(sal_Bool bNew=sal_True)117 void SetHasBeenFixed( sal_Bool bNew = sal_True ) { bHasBeenFixed = bNew; }
118 };
119
120
121 class ParserMessageList : public Impl_ParserMessageList
122 {
123 public:
124 void AddError( sal_uInt16 nErrorNr, ByteString aErrorText, const TokenInfo &rTag );
125 void AddWarning( sal_uInt16 nErrorNr, ByteString aErrorText, const TokenInfo &rTag );
126
127 sal_Bool HasErrors();
128 };
129
130
131 #define TAG_GROUPMASK 0xF000
132 #define TAG_GROUPSHIFT 12
133
134 #define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT )
135 #define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT
136
137 #define TAG_NOMORETAGS 0x0
138
139 #define TAG_GROUP_FORMAT 0x1
140 #define TAG_ON 0x100
141 #define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 )
142 #define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 )
143 #define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 )
144 #define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 )
145 #define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 )
146 #define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 )
147
148 #define TAG_GROUP_NOTALLOWED 0x2
149 #define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 )
150 #define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 )
151 #define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 )
152
153 #define TAG_GROUP_STRUCTURE 0x3
154 #define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 )
155 #define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 )
156 #define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 )
157 #define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 )
158
159 #define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 )
160 #define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 )
161 #define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 )
162
163 #define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 )
164
165 #define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 )
166 #define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 )
167
168 #define TAG_GROUP_SYSSWITCH 0x4
169 #define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 )
170 #define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 )
171 #define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 )
172 #define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 )
173
174 #define TAG_GROUP_PROGSWITCH 0x5
175 #define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 )
176 #define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 )
177 #define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 )
178 #define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 )
179 #define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 )
180 #define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 )
181 #define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 )
182 #define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 )
183 #define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 )
184
185
186 #define TAG_GROUP_META 0x6
187 #define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 )
188 #define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 )
189 #define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 )
190 #define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 )
191 #define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 )
192 #define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 )
193 #define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 )
194 #define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 )
195 #define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 )
196
197
198 #define TAG_GROUP_SINGLE 0x7
199 #define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 )
200
201
202 #define TAG_GROUP_MULTI 0x8
203 #define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 )
204 #define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 )
205 #define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 )
206 #define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 )
207 #define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 )
208
209 #define TAG_GROUP_MISC 0x9
210 #define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 )
211 #define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 )
212
213 #define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 )
214
215 DECLARE_LIST( TokenListImpl, TokenInfo* )
216
217 class TokenList : private TokenListImpl
218 {
219 private:
220
221 TokenList& operator =( const TokenList& rList );
222 // { TokenListImpl::operator =( rList ); return *this; }
223
224
225 public:
226 using TokenListImpl::Count;
227
228
TokenList()229 TokenList() : TokenListImpl(){};
~TokenList()230 ~TokenList(){ Clear(); };
231
Clear()232 void Clear()
233 {
234 for ( sal_uLong i = 0 ; i < Count() ; i++ )
235 delete TokenListImpl::GetObject( i );
236 TokenListImpl::Clear();
237 }
Insert(TokenInfo p,sal_uLong nIndex=LIST_APPEND)238 void Insert( TokenInfo p, sal_uLong nIndex = LIST_APPEND )
239 { TokenListImpl::Insert( new TokenInfo(p), nIndex ); }
240 /* TokenInfo Remove( sal_uLong nIndex )
241 {
242 TokenInfo aT = GetObject( nIndex );
243 delete TokenListImpl::GetObject( nIndex );
244 TokenListImpl::Remove( nIndex );
245 return aT;
246 }*/
247 // TokenInfo Remove( TokenInfo p ){ return Remove( GetPos( p ) ); }
248 // TokenInfo GetCurObject() const { return *TokenListImpl::GetCurObject(); }
GetObject(sal_uLong nIndex) const249 TokenInfo& GetObject( sal_uLong nIndex ) const
250 {
251 // if ( TokenListImpl::GetObject(nIndex) )
252 return *TokenListImpl::GetObject(nIndex);
253 // else
254 // return TokenInfo();
255 }
256 /* sal_uLong GetPos( const TokenInfo p ) const
257 {
258 for ( sal_uLong i = 0 ; i < Count() ; i++ )
259 if ( p == GetObject( i ) )
260 return i;
261 return LIST_ENTRY_NOTFOUND;
262 }*/
263
264 TokenList( const TokenList& rList );
265 /* {
266 for ( sal_uLong i = 0 ; i < rList.Count() ; i++ )
267 {
268 Insert( rList.GetObject( i ), LIST_APPEND );
269 }
270 }*/
271 };
272
273 class ParserMessage
274 {
275 sal_uInt16 nErrorNr;
276 ByteString aErrorText;
277 sal_uInt16 nTagBegin,nTagLength;
278
279 protected:
280 ParserMessage( sal_uInt16 PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag );
281 public:
282
GetErrorNr()283 sal_uInt16 GetErrorNr() { return nErrorNr; }
GetErrorText()284 ByteString GetErrorText() { return aErrorText; }
285
GetTagBegin()286 sal_uInt16 GetTagBegin() { return nTagBegin; }
GetTagLength()287 sal_uInt16 GetTagLength() { return nTagLength; }
288
~ParserMessage()289 virtual ~ParserMessage() {}
290 virtual sal_Bool IsError() =0;
291 virtual ByteString Prefix() =0;
292 };
293
294 class ParserError : public ParserMessage
295 {
296 public:
297 ParserError( sal_uInt16 PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag );
298
IsError()299 virtual sal_Bool IsError() {return sal_True;};
Prefix()300 virtual ByteString Prefix() {return "Error:"; };
301 };
302
303 class ParserWarning : public ParserMessage
304 {
305 public:
306 ParserWarning( sal_uInt16 PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag );
307
IsError()308 virtual sal_Bool IsError() {return sal_False;};
Prefix()309 virtual ByteString Prefix() {return "Warning:"; };
310 };
311
312 class SimpleParser
313 {
314 private:
315 sal_uInt16 nPos;
316 String aSource;
317 String aLastToken;
318 TokenList aTokenList;
319
320 TokenInfo aNextTag; // to store closetag in case of combined tags like <br/>
321
322 String GetNextTokenString( ParserMessageList &rErrorList, sal_uInt16 &rTokeStartPos );
323
324 public:
325 SimpleParser();
326 void Parse( String PaSource );
327 TokenInfo GetNextToken( ParserMessageList &rErrorList );
328 static String GetLexem( TokenInfo const &aToken );
GetTokenList()329 TokenList& GetTokenList(){ return aTokenList; }
330 };
331
332 class TokenParser
333 {
334 sal_Bool match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken );
335 sal_Bool match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken );
336 void ParseError( sal_uInt16 nErrNr, ByteString aErrMsg, const TokenInfo &rTag );
337 void Paragraph();
338 void PfCase();
339 void PfCaseBegin();
340 void AppCase();
341 void AppCaseBegin();
342 void CaseEnd();
343 void SimpleTag();
344 void TagPair();
345 void TagRef();
346
347 SimpleParser aParser;
348 TokenInfo aTag;
349
350 TokenId nPfCaseOptions;
351 TokenId nAppCaseOptions;
352 sal_Bool bPfCaseActive ,bAppCaseActive;
353
354 TokenId nActiveRefTypes;
355
356 ParserMessageList *pErrorList;
357
358 public:
359 TokenParser();
360 void Parse( const String &aCode, ParserMessageList* pList );
361 // ParserMessageList& GetErrors(){ return aErrorList; }
362 // sal_Bool HasErrors(){ return ( aErrorList.Count() > 0 ); }
GetTokenList()363 TokenList& GetTokenList(){ return aParser.GetTokenList(); }
364 };
365
366 class LingTest
367 {
368 private:
369 TokenParser aReferenceParser;
370 TokenParser aTesteeParser;
371 ParserMessageList aCompareWarningList;
372 void CheckTags( TokenList &aReference, TokenList &aTestee, sal_Bool bFixTags );
373 sal_Bool IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens );
374 String aFixedTestee;
375 public:
376 void CheckReference( GSILine *aReference );
377 void CheckTestee( GSILine *aTestee, sal_Bool bHasSourceLine, sal_Bool bFixTags );
378
379 // ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); }
380 // sal_Bool HasReferenceErrors(){ return aReferenceParser.HasErrors(); }
381
382 // ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); }
383 // sal_Bool HasTesteeErrors(){ return aTesteeParser.HasErrors(); }
384
GetCompareWarnings()385 ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; }
HasCompareWarnings()386 sal_Bool HasCompareWarnings(){ return ( aCompareWarningList.Count() > 0 ); }
387
GetFixedTestee()388 String GetFixedTestee(){ return aFixedTestee; }
389 };
390
391 #endif
392
393