xref: /AOO41X/main/l10ntools/inc/tagtest.hxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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