Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef _TAGTEST_HXX_
30 : : #define _TAGTEST_HXX_
31 : :
32 : : #include <boost/unordered_map.hpp>
33 : : #include <vector>
34 : :
35 : : class GSILine;
36 : :
37 : : typedef sal_Int32 TokenId;
38 : :
39 : : #define TOK_INVALIDPOS (-1)
40 : :
41 : : class ParserMessage;
42 : : typedef ::std::vector< ParserMessage* > Impl_ParserMessageList;
43 : :
44 : : class ParserMessageList;
45 : :
46 : : typedef boost::unordered_map<rtl::OString, rtl::OUString, rtl::OStringHash> StringHashMap;
47 : :
48 : 0 : class TokenInfo
49 : : {
50 : : private:
51 : : void SplitTag( ParserMessageList &rErrorList );
52 : :
53 : : rtl::OUString aTagName;
54 : : StringHashMap aProperties;
55 : : sal_Bool bClosed; // tag is closed <sdnf/>
56 : : sal_Bool bCloseTag; // tag is close Tag </sdnf>
57 : :
58 : :
59 : : sal_Bool bIsBroken;
60 : : sal_Bool bHasBeenFixed;
61 : : sal_Bool bDone;
62 : :
63 : : public:
64 : :
65 : : rtl::OUString aTokenString;
66 : : TokenId nId;
67 : : sal_Int32 nPos; // Position in String
68 : :
69 : 0 : TokenInfo():bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),nId( 0 ){;}
70 : 0 : explicit TokenInfo( TokenId pnId, sal_Int32 nP ):bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),nId( pnId ),nPos(nP){;}
71 : 0 : explicit TokenInfo( TokenId pnId, sal_Int32 nP, rtl::OUString const & paStr ):bClosed(sal_False),bCloseTag(sal_False),bIsBroken(sal_False),bHasBeenFixed(sal_False),bDone(sal_False),aTokenString( paStr ),nId( pnId ),nPos(nP) {;}
72 : : explicit TokenInfo( TokenId pnId, sal_Int32 nP, rtl::OUString const & paStr, ParserMessageList &rErrorList );
73 : :
74 : : rtl::OUString GetTagName() const;
75 : :
76 : : rtl::OUString MakeTag() const;
77 : :
78 : : /**
79 : : Is the property to be ignored or does it have the default value anyways
80 : : **/
81 : : sal_Bool IsPropertyRelevant( const rtl::OString &rName, const rtl::OUString &rValue ) const;
82 : : sal_Bool IsPropertyValueValid( const rtl::OString &rName, const rtl::OUString &rValue ) const;
83 : : /**
84 : : Does the property contain the same value for all languages
85 : : e.g.: the href in a link tag
86 : : **/
87 : : sal_Bool IsPropertyInvariant( const rtl::OString &rName, const rtl::OUString &rValue ) const;
88 : : /**
89 : : a subset of IsPropertyInvariant but containing only those that are fixable
90 : : we dont wat to fix e.g.: ahelp :: visibility
91 : : **/
92 : : sal_Bool IsPropertyFixable( const rtl::OString &rName ) const;
93 : : sal_Bool MatchesTranslation( TokenInfo& rInfo, sal_Bool bGenErrors, ParserMessageList &rErrorList, sal_Bool bFixTags = sal_False ) const;
94 : :
95 : 0 : sal_Bool IsDone() const { return bDone; }
96 : 0 : void SetDone( sal_Bool bNew = sal_True ) { bDone = bNew; }
97 : :
98 : 0 : sal_Bool HasBeenFixed() const { return bHasBeenFixed; }
99 : 0 : void SetHasBeenFixed( sal_Bool bNew = sal_True ) { bHasBeenFixed = bNew; }
100 : : };
101 : :
102 : :
103 : 0 : class ParserMessageList
104 : : {
105 : : private:
106 : : Impl_ParserMessageList maList;
107 : :
108 : : public:
109 : 0 : ~ParserMessageList() { clear(); }
110 : : void AddError( sal_Int32 nErrorNr, const rtl::OString& rErrorText, const TokenInfo &rTag );
111 : : void AddWarning( sal_Int32 nErrorNr, const rtl::OString& rErrorText, const TokenInfo &rTag );
112 : :
113 : : sal_Bool HasErrors();
114 : 0 : bool empty() const { return maList.empty(); }
115 : 0 : size_t size() const { return maList.size(); }
116 : 0 : ParserMessage* operator [] ( size_t i ) { return ( i < maList.size() ) ? maList[ i ] : NULL; }
117 : : void clear();
118 : : };
119 : :
120 : :
121 : : #define TAG_GROUPMASK 0xF000
122 : : #define TAG_GROUPSHIFT 12
123 : :
124 : : #define TAG_GROUP( nTag ) (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT )
125 : : #define TAG_NOGROUP( nTag ) ( nTag & ~TAG_GROUPMASK ) // ~ = Bitweises NOT
126 : :
127 : : #define TAG_NOMORETAGS 0x0
128 : :
129 : : #define TAG_GROUP_FORMAT 0x1
130 : : #define TAG_ON 0x100
131 : : #define TAG_BOLDON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 )
132 : : #define TAG_BOLDOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x001 )
133 : : #define TAG_ITALICON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 )
134 : : #define TAG_ITALICOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x002 )
135 : : #define TAG_UNDERLINEON ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 )
136 : : #define TAG_UNDERLINEOFF ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | 0x004 )
137 : :
138 : : #define TAG_GROUP_NOTALLOWED 0x2
139 : : #define TAG_HELPID ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 )
140 : : #define TAG_MODIFY ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 )
141 : : #define TAG_REFNR ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 )
142 : :
143 : : #define TAG_GROUP_STRUCTURE 0x3
144 : : #define TAG_NAME ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 )
145 : : #define TAG_HREF ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 )
146 : : #define TAG_AVIS ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 )
147 : : #define TAG_AHID ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 )
148 : :
149 : : #define TAG_TITEL ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 )
150 : : #define TAG_KEY ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 )
151 : : #define TAG_INDEX ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 )
152 : :
153 : : #define TAG_REFSTART ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 )
154 : :
155 : : #define TAG_GRAPHIC ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 )
156 : : #define TAG_NEXTVERSION ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 )
157 : :
158 : : #define TAG_GROUP_SYSSWITCH 0x4
159 : : #define TAG_WIN ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 )
160 : : #define TAG_UNIX ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 )
161 : : #define TAG_MAC ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 )
162 : : #define TAG_OS2 ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 )
163 : :
164 : : #define TAG_GROUP_PROGSWITCH 0x5
165 : : #define TAG_WRITER ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 )
166 : : #define TAG_CALC ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 )
167 : : #define TAG_DRAW ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 )
168 : : #define TAG_IMPRESS ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 )
169 : : #define TAG_SCHEDULE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 )
170 : : #define TAG_IMAGE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 )
171 : : #define TAG_MATH ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 )
172 : : #define TAG_CHART ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 )
173 : : #define TAG_OFFICE ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 )
174 : :
175 : :
176 : : #define TAG_GROUP_META 0x6
177 : : #define TAG_OFFICEFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 )
178 : : #define TAG_OFFICENAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 )
179 : : #define TAG_OFFICEPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 )
180 : : #define TAG_OFFICEVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 )
181 : : #define TAG_PORTALNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 )
182 : : #define TAG_PORTALFULLNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 )
183 : : #define TAG_PORTALPATH ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 )
184 : : #define TAG_PORTALVERSION ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 )
185 : : #define TAG_PORTALSHORTNAME ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 )
186 : :
187 : :
188 : : #define TAG_GROUP_SINGLE 0x7
189 : : #define TAG_REFINSERT ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 )
190 : :
191 : :
192 : : #define TAG_GROUP_MULTI 0x8
193 : : #define TAG_END ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 )
194 : : #define TAG_ELSE ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 )
195 : : #define TAG_AEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 )
196 : : #define TAG_VERSIONEND ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 )
197 : : #define TAG_ENDGRAPHIC ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 )
198 : :
199 : : #define TAG_GROUP_MISC 0x9
200 : : #define TAG_COMMONSTART ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 )
201 : : #define TAG_COMMONEND ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 )
202 : :
203 : : #define TAG_UNKNOWN_TAG ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 )
204 : :
205 : : typedef ::std::vector< TokenInfo* > TokenListImpl;
206 : :
207 : : class TokenList
208 : : {
209 : : private:
210 : : TokenListImpl maList;
211 : : TokenList& operator =( const TokenList& rList );
212 : :
213 : : public:
214 : 0 : TokenList() {}
215 : 0 : ~TokenList(){ clear(); }
216 : :
217 : 0 : size_t size() const { return maList.size(); }
218 : 0 : void clear()
219 : : {
220 : 0 : for ( size_t i = 0 ; i < maList.size() ; i++ )
221 : 0 : delete maList[ i ];
222 : 0 : maList.clear();
223 : 0 : }
224 : :
225 : 0 : void insert( TokenInfo p, size_t nIndex = size_t(-1) )
226 : : {
227 : 0 : if ( nIndex < maList.size() ) {
228 : 0 : TokenListImpl::iterator it = maList.begin();
229 : 0 : ::std::advance( it, nIndex );
230 : 0 : maList.insert( it, new TokenInfo(p) );
231 : : } else {
232 : 0 : maList.push_back( new TokenInfo(p) );
233 : : }
234 : 0 : }
235 : 0 : TokenInfo& operator [] ( size_t nIndex ) const
236 : : {
237 : 0 : return *maList[ nIndex ];
238 : : }
239 : :
240 : : TokenList( const TokenList& rList );
241 : : };
242 : :
243 : : class ParserMessage
244 : : {
245 : : sal_Int32 nErrorNr;
246 : : rtl::OString aErrorText;
247 : : sal_Int32 nTagBegin,nTagLength;
248 : :
249 : : protected:
250 : : ParserMessage( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag );
251 : : public:
252 : :
253 : : sal_Int32 GetErrorNr() { return nErrorNr; }
254 : 0 : rtl::OString GetErrorText() { return aErrorText; }
255 : :
256 : 0 : sal_Int32 GetTagBegin() { return nTagBegin; }
257 : : sal_Int32 GetTagLength() { return nTagLength; }
258 : :
259 : 0 : virtual ~ParserMessage() {}
260 : : virtual sal_Bool IsError() =0;
261 : : virtual rtl::OString Prefix() =0;
262 : : };
263 : :
264 : 0 : class ParserError : public ParserMessage
265 : : {
266 : : public:
267 : : ParserError( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag );
268 : :
269 : 0 : virtual sal_Bool IsError() {return sal_True;}
270 : 0 : virtual rtl::OString Prefix() {return rtl::OString(RTL_CONSTASCII_STRINGPARAM("Error:")); }
271 : : };
272 : :
273 : 0 : class ParserWarning : public ParserMessage
274 : : {
275 : : public:
276 : : ParserWarning( sal_Int32 PnErrorNr, const rtl::OString &rPaErrorText, const TokenInfo &rTag );
277 : :
278 : 0 : virtual sal_Bool IsError() {return sal_False;}
279 : 0 : virtual rtl::OString Prefix() {return rtl::OString(RTL_CONSTASCII_STRINGPARAM("Warning:")); }
280 : : };
281 : :
282 : 0 : class SimpleParser
283 : : {
284 : : private:
285 : : sal_Int32 nPos;
286 : : rtl::OUString aSource;
287 : : rtl::OUString aLastToken;
288 : : TokenList aTokenList;
289 : :
290 : : TokenInfo aNextTag; // to store closetag in case of combined tags like <br/>
291 : :
292 : : rtl::OUString GetNextTokenString( ParserMessageList &rErrorList, sal_Int32 &rTokeStartPos );
293 : :
294 : : public:
295 : : SimpleParser();
296 : : void Parse( rtl::OUString const & PaSource );
297 : : TokenInfo GetNextToken( ParserMessageList &rErrorList );
298 : : static rtl::OUString GetLexem( TokenInfo const &aToken );
299 : 0 : TokenList& GetTokenList(){ return aTokenList; }
300 : : };
301 : :
302 : 0 : class TokenParser
303 : : {
304 : : sal_Bool match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken );
305 : : sal_Bool match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken );
306 : : void ParseError( sal_Int32 nErrNr, const rtl::OString &rErrMsg, const TokenInfo &rTag );
307 : : void Paragraph();
308 : : void PfCase();
309 : : void PfCaseBegin();
310 : : void AppCase();
311 : : void AppCaseBegin();
312 : : void CaseEnd();
313 : : void SimpleTag();
314 : : void TagPair();
315 : : void TagRef();
316 : :
317 : : SimpleParser aParser;
318 : : TokenInfo aTag;
319 : :
320 : : TokenId nPfCaseOptions;
321 : : TokenId nAppCaseOptions;
322 : : sal_Bool bPfCaseActive ,bAppCaseActive;
323 : :
324 : : TokenId nActiveRefTypes;
325 : :
326 : : ParserMessageList *pErrorList;
327 : :
328 : : public:
329 : : TokenParser();
330 : : void Parse( const rtl::OUString &aCode, ParserMessageList* pList );
331 : 0 : TokenList& GetTokenList(){ return aParser.GetTokenList(); }
332 : : };
333 : :
334 : 0 : class LingTest
335 : : {
336 : : private:
337 : : TokenParser aReferenceParser;
338 : : TokenParser aTesteeParser;
339 : : ParserMessageList aCompareWarningList;
340 : : void CheckTags( TokenList &aReference, TokenList &aTestee, sal_Bool bFixTags );
341 : : sal_Bool IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens );
342 : : rtl::OUString aFixedTestee;
343 : : public:
344 : : void CheckReference( GSILine *aReference );
345 : : void CheckTestee( GSILine *aTestee, sal_Bool bHasSourceLine, sal_Bool bFixTags );
346 : :
347 : 0 : ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; }
348 : 0 : sal_Bool HasCompareWarnings(){ return ( !aCompareWarningList.empty() ); }
349 : :
350 : : rtl::OUString GetFixedTestee(){ return aFixedTestee; }
351 : : };
352 : :
353 : : #endif
354 : :
355 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|