xref: /trunk/main/l10ntools/inc/tagtest.hxx (revision 0fea4d9e)
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 don't want 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