1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_l10ntools.hxx"
26*b1cdbd2cSJim Jagielski #include <tools/string.hxx>
27*b1cdbd2cSJim Jagielski #include "tagtest.hxx"
28*b1cdbd2cSJim Jagielski
29*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
30*b1cdbd2cSJim Jagielski #include <stdio.h>
31*b1cdbd2cSJim Jagielski #endif
32*b1cdbd2cSJim Jagielski
33*b1cdbd2cSJim Jagielski #include "gsicheck.hxx"
34*b1cdbd2cSJim Jagielski
35*b1cdbd2cSJim Jagielski #define HAS_FLAG( nFlags, nFlag ) ( ( nFlags & nFlag ) != 0 )
36*b1cdbd2cSJim Jagielski #define SET_FLAG( nFlags, nFlag ) ( nFlags |= nFlag )
37*b1cdbd2cSJim Jagielski #define RESET_FLAG( nFlags, nFlag ) ( nFlags &= ~nFlag ) // ~ = Bitweises NOT
38*b1cdbd2cSJim Jagielski
39*b1cdbd2cSJim Jagielski
40*b1cdbd2cSJim Jagielski
TokenInfo(TokenId pnId,sal_uInt16 nP,String paStr,ParserMessageList & rErrorList)41*b1cdbd2cSJim Jagielski TokenInfo::TokenInfo( TokenId pnId, sal_uInt16 nP, String paStr, ParserMessageList &rErrorList )
42*b1cdbd2cSJim Jagielski : bClosed(sal_False)
43*b1cdbd2cSJim Jagielski , bCloseTag(sal_False)
44*b1cdbd2cSJim Jagielski , bIsBroken(sal_False)
45*b1cdbd2cSJim Jagielski , bHasBeenFixed(sal_False)
46*b1cdbd2cSJim Jagielski , bDone(sal_False)
47*b1cdbd2cSJim Jagielski , aTokenString( paStr )
48*b1cdbd2cSJim Jagielski , nId( pnId )
49*b1cdbd2cSJim Jagielski , nPos(nP)
50*b1cdbd2cSJim Jagielski {
51*b1cdbd2cSJim Jagielski if ( nId == TAG_COMMONSTART || nId == TAG_COMMONEND )
52*b1cdbd2cSJim Jagielski SplitTag( rErrorList );
53*b1cdbd2cSJim Jagielski }
54*b1cdbd2cSJim Jagielski
55*b1cdbd2cSJim Jagielski enum tagcheck { TC_START, TC_HAS_TAG_NAME, TC_HAS_PROP_NAME_EQ, TC_HAS_PROP_NAME_EQ_SP, TC_HAS_PROP_NAME_SP, TC_INSIDE_STRING, TC_PROP_FINISHED, TC_CLOSED, TC_CLOSED_SPACE, TC_CLOSETAG, TC_CLOSETAG_HAS_TAG_NAME, TC_FINISHED, TC_ERROR };
56*b1cdbd2cSJim Jagielski
57*b1cdbd2cSJim Jagielski /*
58*b1cdbd2cSJim Jagielski \< link href = \"text\" name = \"C\" \>
59*b1cdbd2cSJim Jagielski START ' ' -> HAS_TAG_NAME
60*b1cdbd2cSJim Jagielski START '/' -> CLOSED
61*b1cdbd2cSJim Jagielski START '/' -> CLOSETAG - no Portion (starting with /)
62*b1cdbd2cSJim Jagielski START '>' -> FINISHED
63*b1cdbd2cSJim Jagielski HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ
64*b1cdbd2cSJim Jagielski HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP
65*b1cdbd2cSJim Jagielski HAS_TAG_NAME '/' -> CLOSED
66*b1cdbd2cSJim Jagielski HAS_TAG_NAME '>' -> FINISHED
67*b1cdbd2cSJim Jagielski HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ
68*b1cdbd2cSJim Jagielski HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP
69*b1cdbd2cSJim Jagielski HAS_PROP_NAME_EQ '"' -> INSIDE_STRING
70*b1cdbd2cSJim Jagielski HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING
71*b1cdbd2cSJim Jagielski INSIDE_STRING ' ' -> INSIDE_STRING
72*b1cdbd2cSJim Jagielski INSIDE_STRING '=' -> INSIDE_STRING
73*b1cdbd2cSJim Jagielski INSIDE_STRING '>' -> INSIDE_STRING
74*b1cdbd2cSJim Jagielski INSIDE_STRING '"' -> PROP_FINISHED
75*b1cdbd2cSJim Jagielski PROP_FINISHED ' ' -> HAS_TAG_NAME
76*b1cdbd2cSJim Jagielski PROP_FINISHED '/' -> CLOSED
77*b1cdbd2cSJim Jagielski PROP_FINISHED '>' -> FINISHED
78*b1cdbd2cSJim Jagielski CLOSED ' ' -> CLOSED_SPACE
79*b1cdbd2cSJim Jagielski CLOSED '>' -> FINISHED
80*b1cdbd2cSJim Jagielski CLOSED_SPACE '>' -> FINISHED
81*b1cdbd2cSJim Jagielski
82*b1cdbd2cSJim Jagielski CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME
83*b1cdbd2cSJim Jagielski CLOSETAG '>' -> FINISHED
84*b1cdbd2cSJim Jagielski CLOSETAG_HAS_TAG_NAME '>' -> FINISHED
85*b1cdbd2cSJim Jagielski
86*b1cdbd2cSJim Jagielski */
SplitTag(ParserMessageList & rErrorList)87*b1cdbd2cSJim Jagielski void TokenInfo::SplitTag( ParserMessageList &rErrorList )
88*b1cdbd2cSJim Jagielski {
89*b1cdbd2cSJim Jagielski sal_uInt16 nLastPos = 2; // skip initial \<
90*b1cdbd2cSJim Jagielski sal_uInt16 nCheckPos = nLastPos;
91*b1cdbd2cSJim Jagielski String aDelims( String::CreateFromAscii( " \\=>/" ) );
92*b1cdbd2cSJim Jagielski String aPortion;
93*b1cdbd2cSJim Jagielski String aValue; // store the value of a property
94*b1cdbd2cSJim Jagielski ByteString aName; // store the name of a property/tag
95*b1cdbd2cSJim Jagielski sal_Bool bCheckName = sal_False;
96*b1cdbd2cSJim Jagielski sal_Bool bCheckEmpty = sal_False;
97*b1cdbd2cSJim Jagielski sal_Unicode cDelim;
98*b1cdbd2cSJim Jagielski tagcheck aState = TC_START;
99*b1cdbd2cSJim Jagielski
100*b1cdbd2cSJim Jagielski // skip blanks
101*b1cdbd2cSJim Jagielski while ( nLastPos < aTokenString.Len() && aTokenString.GetChar( nLastPos ) == ' ')
102*b1cdbd2cSJim Jagielski nLastPos++;
103*b1cdbd2cSJim Jagielski
104*b1cdbd2cSJim Jagielski nCheckPos = aTokenString.SearchChar( aDelims.GetBuffer(), nLastPos );
105*b1cdbd2cSJim Jagielski while ( nCheckPos != STRING_NOTFOUND && !( aState == TC_FINISHED || aState == TC_ERROR ) )
106*b1cdbd2cSJim Jagielski {
107*b1cdbd2cSJim Jagielski aPortion = aTokenString.Copy( nLastPos, nCheckPos-nLastPos );
108*b1cdbd2cSJim Jagielski
109*b1cdbd2cSJim Jagielski if ( aTokenString.GetChar( nCheckPos ) == '\\' )
110*b1cdbd2cSJim Jagielski nCheckPos++;
111*b1cdbd2cSJim Jagielski
112*b1cdbd2cSJim Jagielski cDelim = aTokenString.GetChar( nCheckPos );
113*b1cdbd2cSJim Jagielski nCheckPos++;
114*b1cdbd2cSJim Jagielski
115*b1cdbd2cSJim Jagielski switch ( aState )
116*b1cdbd2cSJim Jagielski {
117*b1cdbd2cSJim Jagielski // START ' ' -> HAS_TAG_NAME
118*b1cdbd2cSJim Jagielski // START '/' -> CLOSED
119*b1cdbd2cSJim Jagielski // START '>' -> FINISHED
120*b1cdbd2cSJim Jagielski case TC_START:
121*b1cdbd2cSJim Jagielski aTagName = aPortion;
122*b1cdbd2cSJim Jagielski switch ( cDelim )
123*b1cdbd2cSJim Jagielski {
124*b1cdbd2cSJim Jagielski case ' ': aState = TC_HAS_TAG_NAME;
125*b1cdbd2cSJim Jagielski bCheckName = sal_True;
126*b1cdbd2cSJim Jagielski break;
127*b1cdbd2cSJim Jagielski case '/':
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski if ( aPortion.Len() == 0 )
130*b1cdbd2cSJim Jagielski {
131*b1cdbd2cSJim Jagielski aState = TC_CLOSETAG;
132*b1cdbd2cSJim Jagielski }
133*b1cdbd2cSJim Jagielski else
134*b1cdbd2cSJim Jagielski {
135*b1cdbd2cSJim Jagielski aState = TC_CLOSED;
136*b1cdbd2cSJim Jagielski bCheckName = sal_True;
137*b1cdbd2cSJim Jagielski }
138*b1cdbd2cSJim Jagielski }
139*b1cdbd2cSJim Jagielski break;
140*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
141*b1cdbd2cSJim Jagielski bCheckName = sal_True;
142*b1cdbd2cSJim Jagielski break;
143*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
144*b1cdbd2cSJim Jagielski }
145*b1cdbd2cSJim Jagielski break;
146*b1cdbd2cSJim Jagielski
147*b1cdbd2cSJim Jagielski // HAS_TAG_NAME '=' -> HAS_PROP_NAME_EQ
148*b1cdbd2cSJim Jagielski // HAS_TAG_NAME ' ' -> HAS_PROP_NAME_SP
149*b1cdbd2cSJim Jagielski // HAS_TAG_NAME '/' -> CLOSED
150*b1cdbd2cSJim Jagielski // HAS_TAG_NAME '>' -> FINISHED
151*b1cdbd2cSJim Jagielski case TC_HAS_TAG_NAME:
152*b1cdbd2cSJim Jagielski switch ( cDelim )
153*b1cdbd2cSJim Jagielski {
154*b1cdbd2cSJim Jagielski case '=': aState = TC_HAS_PROP_NAME_EQ;
155*b1cdbd2cSJim Jagielski bCheckName = sal_True;
156*b1cdbd2cSJim Jagielski break;
157*b1cdbd2cSJim Jagielski case ' ': aState = TC_HAS_PROP_NAME_SP;
158*b1cdbd2cSJim Jagielski bCheckName = sal_True;
159*b1cdbd2cSJim Jagielski break;
160*b1cdbd2cSJim Jagielski case '/': aState = TC_CLOSED;
161*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
162*b1cdbd2cSJim Jagielski break;
163*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
164*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
165*b1cdbd2cSJim Jagielski break;
166*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
167*b1cdbd2cSJim Jagielski }
168*b1cdbd2cSJim Jagielski break;
169*b1cdbd2cSJim Jagielski
170*b1cdbd2cSJim Jagielski // HAS_PROP_NAME_SP '=' -> HAS_PROP_NAME_EQ
171*b1cdbd2cSJim Jagielski case TC_HAS_PROP_NAME_SP:
172*b1cdbd2cSJim Jagielski switch ( cDelim )
173*b1cdbd2cSJim Jagielski {
174*b1cdbd2cSJim Jagielski case '=': aState = TC_HAS_PROP_NAME_EQ;
175*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
176*b1cdbd2cSJim Jagielski break;
177*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
178*b1cdbd2cSJim Jagielski }
179*b1cdbd2cSJim Jagielski break;
180*b1cdbd2cSJim Jagielski
181*b1cdbd2cSJim Jagielski // HAS_PROP_NAME_EQ ' ' -> HAS_PROP_NAME_EQ_SP
182*b1cdbd2cSJim Jagielski // HAS_PROP_NAME_EQ '"' -> INSIDE_STRING
183*b1cdbd2cSJim Jagielski case TC_HAS_PROP_NAME_EQ:
184*b1cdbd2cSJim Jagielski switch ( cDelim )
185*b1cdbd2cSJim Jagielski {
186*b1cdbd2cSJim Jagielski case ' ': aState = TC_HAS_PROP_NAME_EQ_SP;
187*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
188*b1cdbd2cSJim Jagielski break;
189*b1cdbd2cSJim Jagielski case '\"': aState = TC_INSIDE_STRING;
190*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
191*b1cdbd2cSJim Jagielski aValue.Erase();
192*b1cdbd2cSJim Jagielski break;
193*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
194*b1cdbd2cSJim Jagielski }
195*b1cdbd2cSJim Jagielski break;
196*b1cdbd2cSJim Jagielski
197*b1cdbd2cSJim Jagielski // HAS_PROP_NAME_EQ_SP '"' -> INSIDE_STRING
198*b1cdbd2cSJim Jagielski case TC_HAS_PROP_NAME_EQ_SP:
199*b1cdbd2cSJim Jagielski switch ( cDelim )
200*b1cdbd2cSJim Jagielski {
201*b1cdbd2cSJim Jagielski case '\"': aState = TC_INSIDE_STRING;
202*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
203*b1cdbd2cSJim Jagielski aValue.Erase();
204*b1cdbd2cSJim Jagielski break;
205*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
206*b1cdbd2cSJim Jagielski }
207*b1cdbd2cSJim Jagielski break;
208*b1cdbd2cSJim Jagielski
209*b1cdbd2cSJim Jagielski // INSIDE_STRING * -> INSIDE_STRING
210*b1cdbd2cSJim Jagielski // INSIDE_STRING '"' -> PROP_FINISHED
211*b1cdbd2cSJim Jagielski case TC_INSIDE_STRING:
212*b1cdbd2cSJim Jagielski switch ( cDelim )
213*b1cdbd2cSJim Jagielski {
214*b1cdbd2cSJim Jagielski case '\"':
215*b1cdbd2cSJim Jagielski {
216*b1cdbd2cSJim Jagielski aState = TC_PROP_FINISHED;
217*b1cdbd2cSJim Jagielski aValue += aPortion;
218*b1cdbd2cSJim Jagielski if ( aProperties.find( aName ) == aProperties.end() )
219*b1cdbd2cSJim Jagielski {
220*b1cdbd2cSJim Jagielski if ( !IsPropertyValueValid( aName, aValue ) )
221*b1cdbd2cSJim Jagielski {
222*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, ByteString("Property '").Append(aName).Append("' has invalid value '").Append(ByteString( aValue, RTL_TEXTENCODING_UTF8 )).Append("' "), *this );
223*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
224*b1cdbd2cSJim Jagielski }
225*b1cdbd2cSJim Jagielski aProperties[ aName ] = aValue;
226*b1cdbd2cSJim Jagielski }
227*b1cdbd2cSJim Jagielski else
228*b1cdbd2cSJim Jagielski {
229*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, ByteString("Property '").Append(aName).Append("' defined twice "), *this );
230*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
231*b1cdbd2cSJim Jagielski }
232*b1cdbd2cSJim Jagielski }
233*b1cdbd2cSJim Jagielski break;
234*b1cdbd2cSJim Jagielski default:
235*b1cdbd2cSJim Jagielski {
236*b1cdbd2cSJim Jagielski aState = TC_INSIDE_STRING;
237*b1cdbd2cSJim Jagielski aValue += aPortion;
238*b1cdbd2cSJim Jagielski aValue += cDelim;
239*b1cdbd2cSJim Jagielski }
240*b1cdbd2cSJim Jagielski }
241*b1cdbd2cSJim Jagielski break;
242*b1cdbd2cSJim Jagielski
243*b1cdbd2cSJim Jagielski // PROP_FINISHED ' ' -> HAS_TAG_NAME
244*b1cdbd2cSJim Jagielski // PROP_FINISHED '/' -> CLOSED
245*b1cdbd2cSJim Jagielski // PROP_FINISHED '>' -> FINISHED
246*b1cdbd2cSJim Jagielski case TC_PROP_FINISHED:
247*b1cdbd2cSJim Jagielski switch ( cDelim )
248*b1cdbd2cSJim Jagielski {
249*b1cdbd2cSJim Jagielski case ' ': aState = TC_HAS_TAG_NAME;
250*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
251*b1cdbd2cSJim Jagielski break;
252*b1cdbd2cSJim Jagielski case '/': aState = TC_CLOSED;
253*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
254*b1cdbd2cSJim Jagielski break;
255*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
256*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
257*b1cdbd2cSJim Jagielski break;
258*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
259*b1cdbd2cSJim Jagielski }
260*b1cdbd2cSJim Jagielski break;
261*b1cdbd2cSJim Jagielski
262*b1cdbd2cSJim Jagielski // CLOSED ' ' -> CLOSED_SPACE
263*b1cdbd2cSJim Jagielski // CLOSED '>' -> FINISHED
264*b1cdbd2cSJim Jagielski case TC_CLOSED:
265*b1cdbd2cSJim Jagielski switch ( cDelim )
266*b1cdbd2cSJim Jagielski {
267*b1cdbd2cSJim Jagielski case ' ': aState = TC_CLOSED_SPACE;
268*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
269*b1cdbd2cSJim Jagielski bClosed = sal_True;
270*b1cdbd2cSJim Jagielski break;
271*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
272*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
273*b1cdbd2cSJim Jagielski break;
274*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
275*b1cdbd2cSJim Jagielski }
276*b1cdbd2cSJim Jagielski break;
277*b1cdbd2cSJim Jagielski
278*b1cdbd2cSJim Jagielski // CLOSED_SPACE '>' -> FINISHED
279*b1cdbd2cSJim Jagielski case TC_CLOSED_SPACE:
280*b1cdbd2cSJim Jagielski switch ( cDelim )
281*b1cdbd2cSJim Jagielski {
282*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
283*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
284*b1cdbd2cSJim Jagielski break;
285*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
286*b1cdbd2cSJim Jagielski }
287*b1cdbd2cSJim Jagielski break;
288*b1cdbd2cSJim Jagielski
289*b1cdbd2cSJim Jagielski // CLOSETAG ' ' -> CLOSETAG_HAS_TAG_NAME
290*b1cdbd2cSJim Jagielski // CLOSETAG '>' -> FINISHED
291*b1cdbd2cSJim Jagielski case TC_CLOSETAG:
292*b1cdbd2cSJim Jagielski bCloseTag = sal_True;
293*b1cdbd2cSJim Jagielski switch ( cDelim )
294*b1cdbd2cSJim Jagielski {
295*b1cdbd2cSJim Jagielski case ' ': aState = TC_CLOSETAG_HAS_TAG_NAME;
296*b1cdbd2cSJim Jagielski aTagName = aPortion;
297*b1cdbd2cSJim Jagielski bCheckName = sal_True;
298*b1cdbd2cSJim Jagielski break;
299*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
300*b1cdbd2cSJim Jagielski aTagName = aPortion;
301*b1cdbd2cSJim Jagielski bCheckName = sal_True;
302*b1cdbd2cSJim Jagielski break;
303*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
304*b1cdbd2cSJim Jagielski }
305*b1cdbd2cSJim Jagielski break;
306*b1cdbd2cSJim Jagielski
307*b1cdbd2cSJim Jagielski // CLOSETAG_HAS_TAG_NAME '>' -> FINISHED
308*b1cdbd2cSJim Jagielski case TC_CLOSETAG_HAS_TAG_NAME:
309*b1cdbd2cSJim Jagielski switch ( cDelim )
310*b1cdbd2cSJim Jagielski {
311*b1cdbd2cSJim Jagielski case '>': aState = TC_FINISHED;
312*b1cdbd2cSJim Jagielski bCheckEmpty = sal_True;
313*b1cdbd2cSJim Jagielski break;
314*b1cdbd2cSJim Jagielski default: aState = TC_ERROR;
315*b1cdbd2cSJim Jagielski }
316*b1cdbd2cSJim Jagielski break;
317*b1cdbd2cSJim Jagielski
318*b1cdbd2cSJim Jagielski
319*b1cdbd2cSJim Jagielski default: rErrorList.AddError( 99, "Internal error Parsing Tag ", *this );
320*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
321*b1cdbd2cSJim Jagielski
322*b1cdbd2cSJim Jagielski }
323*b1cdbd2cSJim Jagielski
324*b1cdbd2cSJim Jagielski if ( bCheckName )
325*b1cdbd2cSJim Jagielski {
326*b1cdbd2cSJim Jagielski if ( aPortion.Len() == 0 )
327*b1cdbd2cSJim Jagielski {
328*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, "Tag/Property name missing ", *this );
329*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
330*b1cdbd2cSJim Jagielski }
331*b1cdbd2cSJim Jagielski else
332*b1cdbd2cSJim Jagielski {
333*b1cdbd2cSJim Jagielski aName = ByteString( aPortion, RTL_TEXTENCODING_UTF8 );
334*b1cdbd2cSJim Jagielski // "a-zA-Z_-.0-9"
335*b1cdbd2cSJim Jagielski xub_StrLen nCount;
336*b1cdbd2cSJim Jagielski sal_Bool bBroken = sal_False;
337*b1cdbd2cSJim Jagielski const sal_Char* aBuf = aName.GetBuffer();
338*b1cdbd2cSJim Jagielski for ( nCount = 0 ; !bBroken && nCount < aName.Len() ; nCount++ )
339*b1cdbd2cSJim Jagielski {
340*b1cdbd2cSJim Jagielski bBroken = ! ( ( aBuf[nCount] >= 'a' && aBuf[nCount] <= 'z' )
341*b1cdbd2cSJim Jagielski ||( aBuf[nCount] >= 'A' && aBuf[nCount] <= 'Z' )
342*b1cdbd2cSJim Jagielski ||( aBuf[nCount] >= '0' && aBuf[nCount] <= '9' )
343*b1cdbd2cSJim Jagielski ||( aBuf[nCount] == '_' )
344*b1cdbd2cSJim Jagielski ||( aBuf[nCount] == '-' )
345*b1cdbd2cSJim Jagielski ||( aBuf[nCount] == '.' )
346*b1cdbd2cSJim Jagielski );
347*b1cdbd2cSJim Jagielski }
348*b1cdbd2cSJim Jagielski
349*b1cdbd2cSJim Jagielski if ( bBroken )
350*b1cdbd2cSJim Jagielski {
351*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, "Found illegal character in Tag/Property name ", *this );
352*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
353*b1cdbd2cSJim Jagielski }
354*b1cdbd2cSJim Jagielski }
355*b1cdbd2cSJim Jagielski
356*b1cdbd2cSJim Jagielski bCheckName = sal_False;
357*b1cdbd2cSJim Jagielski }
358*b1cdbd2cSJim Jagielski
359*b1cdbd2cSJim Jagielski if ( bCheckEmpty )
360*b1cdbd2cSJim Jagielski {
361*b1cdbd2cSJim Jagielski if ( aPortion.Len() )
362*b1cdbd2cSJim Jagielski {
363*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, ByteString("Found displaced characters '").Append(ByteString( aPortion, RTL_TEXTENCODING_UTF8 )).Append("' in Tag "), *this );
364*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
365*b1cdbd2cSJim Jagielski }
366*b1cdbd2cSJim Jagielski bCheckEmpty = sal_False;
367*b1cdbd2cSJim Jagielski }
368*b1cdbd2cSJim Jagielski
369*b1cdbd2cSJim Jagielski
370*b1cdbd2cSJim Jagielski nLastPos = nCheckPos;
371*b1cdbd2cSJim Jagielski
372*b1cdbd2cSJim Jagielski // skip further blanks
373*b1cdbd2cSJim Jagielski if ( cDelim == ' ' && aState != TC_INSIDE_STRING )
374*b1cdbd2cSJim Jagielski while ( nLastPos < aTokenString.Len() && aTokenString.GetChar( nLastPos ) == ' ')
375*b1cdbd2cSJim Jagielski nLastPos++;
376*b1cdbd2cSJim Jagielski
377*b1cdbd2cSJim Jagielski nCheckPos = aTokenString.SearchChar( aDelims.GetBuffer(), nLastPos );
378*b1cdbd2cSJim Jagielski }
379*b1cdbd2cSJim Jagielski if ( aState != TC_FINISHED )
380*b1cdbd2cSJim Jagielski {
381*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, "Parsing error in Tag ", *this );
382*b1cdbd2cSJim Jagielski bIsBroken = sal_True;
383*b1cdbd2cSJim Jagielski }
384*b1cdbd2cSJim Jagielski }
385*b1cdbd2cSJim Jagielski
IsPropertyRelevant(const ByteString & aName,const String & aValue) const386*b1cdbd2cSJim Jagielski sal_Bool TokenInfo::IsPropertyRelevant( const ByteString &aName, const String &aValue ) const
387*b1cdbd2cSJim Jagielski {
388*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "alt" ) && aName.Equals( "xml-lang" ) )
389*b1cdbd2cSJim Jagielski return sal_False;
390*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "ahelp" ) && aName.Equals( "visibility" ) && aValue.EqualsAscii("visible") )
391*b1cdbd2cSJim Jagielski return sal_False;
392*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "image" ) && (aName.Equals( "width" ) || aName.Equals( "height" )) )
393*b1cdbd2cSJim Jagielski return sal_False;
394*b1cdbd2cSJim Jagielski
395*b1cdbd2cSJim Jagielski return sal_True;
396*b1cdbd2cSJim Jagielski }
397*b1cdbd2cSJim Jagielski
IsPropertyValueValid(const ByteString & aName,const String & aValue) const398*b1cdbd2cSJim Jagielski sal_Bool TokenInfo::IsPropertyValueValid( const ByteString &aName, const String &aValue ) const
399*b1cdbd2cSJim Jagielski {
400*b1cdbd2cSJim Jagielski /* removed due to i56740
401*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "switchinline" ) && aName.Equals( "select" ) )
402*b1cdbd2cSJim Jagielski {
403*b1cdbd2cSJim Jagielski return aValue.EqualsAscii("sys") ||
404*b1cdbd2cSJim Jagielski aValue.EqualsAscii("appl") ||
405*b1cdbd2cSJim Jagielski aValue.EqualsAscii("distrib");
406*b1cdbd2cSJim Jagielski } */
407*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "caseinline" ) && aName.Equals( "select" ) )
408*b1cdbd2cSJim Jagielski {
409*b1cdbd2cSJim Jagielski return /*!aValue.EqualsAscii("OS2") && removed due to i56740 */
410*b1cdbd2cSJim Jagielski !aValue.EqualsAscii("");
411*b1cdbd2cSJim Jagielski }
412*b1cdbd2cSJim Jagielski
413*b1cdbd2cSJim Jagielski // we don't know any better so we assume it to be OK
414*b1cdbd2cSJim Jagielski return sal_True;
415*b1cdbd2cSJim Jagielski }
416*b1cdbd2cSJim Jagielski
IsPropertyInvariant(const ByteString & aName,const String & aValue) const417*b1cdbd2cSJim Jagielski sal_Bool TokenInfo::IsPropertyInvariant( const ByteString &aName, const String &aValue ) const
418*b1cdbd2cSJim Jagielski {
419*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "link" ) && aName.Equals( "name" ) )
420*b1cdbd2cSJim Jagielski return sal_False;
421*b1cdbd2cSJim Jagielski if ( aTagName.EqualsAscii( "link" ) && aName.Equals( "href" ) )
422*b1cdbd2cSJim Jagielski { // check for external reference
423*b1cdbd2cSJim Jagielski if ( aValue.Copy( 0, 5 ).EqualsIgnoreCaseAscii( "http:" )
424*b1cdbd2cSJim Jagielski || aValue.Copy( 0, 6 ).EqualsIgnoreCaseAscii( "https:" )
425*b1cdbd2cSJim Jagielski || aValue.Copy( 0, 4 ).EqualsIgnoreCaseAscii( "ftp:" ) )
426*b1cdbd2cSJim Jagielski return sal_False;
427*b1cdbd2cSJim Jagielski else
428*b1cdbd2cSJim Jagielski return sal_True;
429*b1cdbd2cSJim Jagielski }
430*b1cdbd2cSJim Jagielski return sal_True;
431*b1cdbd2cSJim Jagielski }
432*b1cdbd2cSJim Jagielski
IsPropertyFixable(const ByteString & aName) const433*b1cdbd2cSJim Jagielski sal_Bool TokenInfo::IsPropertyFixable( const ByteString &aName ) const
434*b1cdbd2cSJim Jagielski {
435*b1cdbd2cSJim Jagielski // name everything that is allowed to be fixed automatically here
436*b1cdbd2cSJim Jagielski if ( (aTagName.EqualsAscii( "ahelp" ) && aName.Equals( "hid" ))
437*b1cdbd2cSJim Jagielski || (aTagName.EqualsAscii( "link" ) && aName.Equals( "href" ))
438*b1cdbd2cSJim Jagielski || (aTagName.EqualsAscii( "alt" ) && aName.Equals( "id" ))
439*b1cdbd2cSJim Jagielski || (aTagName.EqualsAscii( "variable" ) && aName.Equals( "id" ))
440*b1cdbd2cSJim Jagielski || (aTagName.EqualsAscii( "image" ) && aName.Equals( "src" ))
441*b1cdbd2cSJim Jagielski || (aTagName.EqualsAscii( "image" ) && aName.Equals( "id" ) ))
442*b1cdbd2cSJim Jagielski return sal_True;
443*b1cdbd2cSJim Jagielski return sal_False;
444*b1cdbd2cSJim Jagielski }
445*b1cdbd2cSJim Jagielski
MatchesTranslation(TokenInfo & rInfo,sal_Bool bGenErrors,ParserMessageList & rErrorList,sal_Bool bFixTags) const446*b1cdbd2cSJim Jagielski sal_Bool TokenInfo::MatchesTranslation( TokenInfo& rInfo, sal_Bool bGenErrors, ParserMessageList &rErrorList, sal_Bool bFixTags ) const
447*b1cdbd2cSJim Jagielski {
448*b1cdbd2cSJim Jagielski // check if tags are equal
449*b1cdbd2cSJim Jagielski // check if all existing properties are in the translation as well and
450*b1cdbd2cSJim Jagielski // wether they have a matching content (the same in most cases)
451*b1cdbd2cSJim Jagielski
452*b1cdbd2cSJim Jagielski if ( nId != rInfo.nId )
453*b1cdbd2cSJim Jagielski return sal_False;
454*b1cdbd2cSJim Jagielski
455*b1cdbd2cSJim Jagielski if ( !aTagName.Equals( rInfo.aTagName ) )
456*b1cdbd2cSJim Jagielski return sal_False;
457*b1cdbd2cSJim Jagielski
458*b1cdbd2cSJim Jagielski // If one of the tags has formating errors already it does make no sense to check here, so return right away
459*b1cdbd2cSJim Jagielski if ( bGenErrors && ( bIsBroken || rInfo.bIsBroken ) )
460*b1cdbd2cSJim Jagielski return sal_True;
461*b1cdbd2cSJim Jagielski
462*b1cdbd2cSJim Jagielski StringHashMap::const_iterator iProp;
463*b1cdbd2cSJim Jagielski for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp )
464*b1cdbd2cSJim Jagielski {
465*b1cdbd2cSJim Jagielski if ( rInfo.aProperties.find( iProp->first ) != rInfo.aProperties.end() )
466*b1cdbd2cSJim Jagielski {
467*b1cdbd2cSJim Jagielski if ( IsPropertyRelevant( iProp->first, iProp->second ) || IsPropertyRelevant( iProp->first, rInfo.aProperties.find( iProp->first )->second ) )
468*b1cdbd2cSJim Jagielski {
469*b1cdbd2cSJim Jagielski if ( IsPropertyInvariant( iProp->first, iProp->second ) )
470*b1cdbd2cSJim Jagielski {
471*b1cdbd2cSJim Jagielski if ( !rInfo.aProperties.find( iProp->first )->second.Equals( iProp->second ) )
472*b1cdbd2cSJim Jagielski {
473*b1cdbd2cSJim Jagielski if ( bGenErrors )
474*b1cdbd2cSJim Jagielski {
475*b1cdbd2cSJim Jagielski if ( bFixTags && IsPropertyFixable( iProp->first ) )
476*b1cdbd2cSJim Jagielski {
477*b1cdbd2cSJim Jagielski rInfo.aProperties.find( iProp->first )->second = iProp->second;
478*b1cdbd2cSJim Jagielski rInfo.SetHasBeenFixed();
479*b1cdbd2cSJim Jagielski rErrorList.AddWarning( 25, ByteString("Property '").Append(iProp->first).Append("': FIXED different value in Translation "), *this );
480*b1cdbd2cSJim Jagielski }
481*b1cdbd2cSJim Jagielski else
482*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, ByteString("Property '").Append(iProp->first).Append("': value different in Translation "), *this );
483*b1cdbd2cSJim Jagielski }
484*b1cdbd2cSJim Jagielski else return sal_False;
485*b1cdbd2cSJim Jagielski }
486*b1cdbd2cSJim Jagielski }
487*b1cdbd2cSJim Jagielski }
488*b1cdbd2cSJim Jagielski }
489*b1cdbd2cSJim Jagielski else
490*b1cdbd2cSJim Jagielski {
491*b1cdbd2cSJim Jagielski if ( IsPropertyRelevant( iProp->first, iProp->second ) )
492*b1cdbd2cSJim Jagielski {
493*b1cdbd2cSJim Jagielski if ( bGenErrors )
494*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, ByteString("Property '").Append(iProp->first).Append("' missing in Translation "), *this );
495*b1cdbd2cSJim Jagielski else return sal_False;
496*b1cdbd2cSJim Jagielski }
497*b1cdbd2cSJim Jagielski }
498*b1cdbd2cSJim Jagielski }
499*b1cdbd2cSJim Jagielski for( iProp = rInfo.aProperties.begin() ; iProp != rInfo.aProperties.end(); ++iProp )
500*b1cdbd2cSJim Jagielski {
501*b1cdbd2cSJim Jagielski if ( aProperties.find( iProp->first ) == aProperties.end() )
502*b1cdbd2cSJim Jagielski {
503*b1cdbd2cSJim Jagielski if ( IsPropertyRelevant( iProp->first, iProp->second ) )
504*b1cdbd2cSJim Jagielski {
505*b1cdbd2cSJim Jagielski if ( bGenErrors )
506*b1cdbd2cSJim Jagielski rErrorList.AddError( 25, ByteString("Extra Property '").Append(iProp->first).Append("' in Translation "), rInfo );
507*b1cdbd2cSJim Jagielski else return sal_False;
508*b1cdbd2cSJim Jagielski }
509*b1cdbd2cSJim Jagielski }
510*b1cdbd2cSJim Jagielski }
511*b1cdbd2cSJim Jagielski
512*b1cdbd2cSJim Jagielski // if we reach here eather
513*b1cdbd2cSJim Jagielski // the tags match completely or
514*b1cdbd2cSJim Jagielski // the tags match but not the properties and we generated errors for that
515*b1cdbd2cSJim Jagielski return sal_True;
516*b1cdbd2cSJim Jagielski }
517*b1cdbd2cSJim Jagielski
GetTagName() const518*b1cdbd2cSJim Jagielski String TokenInfo::GetTagName() const
519*b1cdbd2cSJim Jagielski {
520*b1cdbd2cSJim Jagielski return aTagName;
521*b1cdbd2cSJim Jagielski }
522*b1cdbd2cSJim Jagielski
MakeTag() const523*b1cdbd2cSJim Jagielski String TokenInfo::MakeTag() const
524*b1cdbd2cSJim Jagielski {
525*b1cdbd2cSJim Jagielski String aRet;
526*b1cdbd2cSJim Jagielski aRet.AppendAscii("\\<");
527*b1cdbd2cSJim Jagielski if ( bCloseTag )
528*b1cdbd2cSJim Jagielski aRet.AppendAscii("/");
529*b1cdbd2cSJim Jagielski aRet.Append( GetTagName() );
530*b1cdbd2cSJim Jagielski StringHashMap::const_iterator iProp;
531*b1cdbd2cSJim Jagielski
532*b1cdbd2cSJim Jagielski for( iProp = aProperties.begin() ; iProp != aProperties.end(); ++iProp )
533*b1cdbd2cSJim Jagielski {
534*b1cdbd2cSJim Jagielski aRet.AppendAscii(" ");
535*b1cdbd2cSJim Jagielski aRet.Append( String( iProp->first, RTL_TEXTENCODING_UTF8 ) );
536*b1cdbd2cSJim Jagielski aRet.AppendAscii("=\\\"");
537*b1cdbd2cSJim Jagielski aRet.Append( iProp->second );
538*b1cdbd2cSJim Jagielski aRet.AppendAscii("\\\"");
539*b1cdbd2cSJim Jagielski }
540*b1cdbd2cSJim Jagielski if ( bClosed )
541*b1cdbd2cSJim Jagielski aRet.AppendAscii("/");
542*b1cdbd2cSJim Jagielski aRet.AppendAscii("\\>");
543*b1cdbd2cSJim Jagielski return aRet;
544*b1cdbd2cSJim Jagielski }
545*b1cdbd2cSJim Jagielski
546*b1cdbd2cSJim Jagielski
AddError(sal_uInt16 nErrorNr,ByteString aErrorText,const TokenInfo & rTag)547*b1cdbd2cSJim Jagielski void ParserMessageList::AddError( sal_uInt16 nErrorNr, ByteString aErrorText, const TokenInfo &rTag )
548*b1cdbd2cSJim Jagielski {
549*b1cdbd2cSJim Jagielski Insert( new ParserError( nErrorNr, aErrorText, rTag ), LIST_APPEND );
550*b1cdbd2cSJim Jagielski }
551*b1cdbd2cSJim Jagielski
AddWarning(sal_uInt16 nErrorNr,ByteString aErrorText,const TokenInfo & rTag)552*b1cdbd2cSJim Jagielski void ParserMessageList::AddWarning( sal_uInt16 nErrorNr, ByteString aErrorText, const TokenInfo &rTag )
553*b1cdbd2cSJim Jagielski {
554*b1cdbd2cSJim Jagielski Insert( new ParserWarning( nErrorNr, aErrorText, rTag ), LIST_APPEND );
555*b1cdbd2cSJim Jagielski }
556*b1cdbd2cSJim Jagielski
HasErrors()557*b1cdbd2cSJim Jagielski sal_Bool ParserMessageList::HasErrors()
558*b1cdbd2cSJim Jagielski {
559*b1cdbd2cSJim Jagielski sal_uInt16 i;
560*b1cdbd2cSJim Jagielski for ( i=0 ; i < Count() ; i++ )
561*b1cdbd2cSJim Jagielski if ( GetObject( i )->IsError() )
562*b1cdbd2cSJim Jagielski return sal_True;
563*b1cdbd2cSJim Jagielski return sal_False;
564*b1cdbd2cSJim Jagielski }
565*b1cdbd2cSJim Jagielski
566*b1cdbd2cSJim Jagielski struct Tag
567*b1cdbd2cSJim Jagielski {
GetNameTag568*b1cdbd2cSJim Jagielski String GetName() const { return String::CreateFromAscii( pName ); };
569*b1cdbd2cSJim Jagielski const char* pName;
570*b1cdbd2cSJim Jagielski TokenId nTag;
571*b1cdbd2cSJim Jagielski };
572*b1cdbd2cSJim Jagielski
573*b1cdbd2cSJim Jagielski
574*b1cdbd2cSJim Jagielski static const Tag aKnownTags[] =
575*b1cdbd2cSJim Jagielski {
576*b1cdbd2cSJim Jagielski /* commenting oldstyle tags
577*b1cdbd2cSJim Jagielski // { "<#GROUP_FORMAT>", TAG_GROUP_FORMAT },
578*b1cdbd2cSJim Jagielski { "<#BOLD>", TAG_BOLDON },
579*b1cdbd2cSJim Jagielski { "<#/BOLD>", TAG_BOLDOFF },
580*b1cdbd2cSJim Jagielski { "<#ITALIC>", TAG_ITALICON },
581*b1cdbd2cSJim Jagielski { "<#/ITALIC>", TAG_ITALICOFF },
582*b1cdbd2cSJim Jagielski { "<#UNDER>", TAG_UNDERLINEON },
583*b1cdbd2cSJim Jagielski { "<#/UNDER>", TAG_UNDERLINEOFF },
584*b1cdbd2cSJim Jagielski
585*b1cdbd2cSJim Jagielski // { "<#GROUP_NOTALLOWED>", TAG_GROUP_NOTALLOWED },
586*b1cdbd2cSJim Jagielski { "<#HELPID>", TAG_HELPID },
587*b1cdbd2cSJim Jagielski { "<#MODIFY>", TAG_MODIFY },
588*b1cdbd2cSJim Jagielski { "<#REFNR>", TAG_REFNR },
589*b1cdbd2cSJim Jagielski
590*b1cdbd2cSJim Jagielski // { "<#GROUP_STRUCTURE>", TAG_GROUP_STRUCTURE },
591*b1cdbd2cSJim Jagielski { "<#NAME>", TAG_NAME },
592*b1cdbd2cSJim Jagielski { "<#HREF>", TAG_HREF },
593*b1cdbd2cSJim Jagielski { "<#AVIS>", TAG_AVIS },
594*b1cdbd2cSJim Jagielski { "<#AHID>", TAG_AHID },
595*b1cdbd2cSJim Jagielski { "<#AEND>", TAG_AEND },
596*b1cdbd2cSJim Jagielski
597*b1cdbd2cSJim Jagielski { "<#TITEL>", TAG_TITEL },
598*b1cdbd2cSJim Jagielski { "<#KEY>", TAG_KEY },
599*b1cdbd2cSJim Jagielski { "<#INDEX>", TAG_INDEX },
600*b1cdbd2cSJim Jagielski
601*b1cdbd2cSJim Jagielski { "<#REFSTART>", TAG_REFSTART },
602*b1cdbd2cSJim Jagielski
603*b1cdbd2cSJim Jagielski { "<#GRAPHIC>", TAG_GRAPHIC },
604*b1cdbd2cSJim Jagielski { "<#NEXTVERSION>", TAG_NEXTVERSION },
605*b1cdbd2cSJim Jagielski
606*b1cdbd2cSJim Jagielski // { "<#GROUP_SYSSWITCH>", TAG_GROUP_SYSSWITCH },
607*b1cdbd2cSJim Jagielski { "<#WIN>", TAG_WIN },
608*b1cdbd2cSJim Jagielski { "<#UNIX>", TAG_UNIX },
609*b1cdbd2cSJim Jagielski { "<#MAC>", TAG_MAC },
610*b1cdbd2cSJim Jagielski { "<#OS2>", TAG_OS2 },
611*b1cdbd2cSJim Jagielski
612*b1cdbd2cSJim Jagielski // { "<#GROUP_PROGSWITCH>", TAG_GROUP_PROGSWITCH },
613*b1cdbd2cSJim Jagielski { "<#WRITER>", TAG_WRITER },
614*b1cdbd2cSJim Jagielski { "<#CALC>", TAG_CALC },
615*b1cdbd2cSJim Jagielski { "<#DRAW>", TAG_DRAW },
616*b1cdbd2cSJim Jagielski { "<#IMPRESS>", TAG_IMPRESS },
617*b1cdbd2cSJim Jagielski { "<#SCHEDULE>", TAG_SCHEDULE },
618*b1cdbd2cSJim Jagielski { "<#IMAGE>", TAG_IMAGE },
619*b1cdbd2cSJim Jagielski { "<#MATH>", TAG_MATH },
620*b1cdbd2cSJim Jagielski { "<#CHART>", TAG_CHART },
621*b1cdbd2cSJim Jagielski { "<#OFFICE>", TAG_OFFICE },
622*b1cdbd2cSJim Jagielski */
623*b1cdbd2cSJim Jagielski // { "<#TAG_GROUP_META>", TAG_GROUP_META },
624*b1cdbd2cSJim Jagielski { "$[officefullname]", TAG_OFFICEFULLNAME },
625*b1cdbd2cSJim Jagielski { "$[officename]", TAG_OFFICENAME },
626*b1cdbd2cSJim Jagielski { "$[officepath]", TAG_OFFICEPATH },
627*b1cdbd2cSJim Jagielski { "$[officeversion]", TAG_OFFICEVERSION },
628*b1cdbd2cSJim Jagielski { "$[portalname]", TAG_PORTALNAME },
629*b1cdbd2cSJim Jagielski { "$[portalfullname]", TAG_PORTALFULLNAME },
630*b1cdbd2cSJim Jagielski { "$[portalpath]", TAG_PORTALPATH },
631*b1cdbd2cSJim Jagielski { "$[portalversion]", TAG_PORTALVERSION },
632*b1cdbd2cSJim Jagielski { "$[portalshortname]", TAG_PORTALSHORTNAME },
633*b1cdbd2cSJim Jagielski /* commenting oldstyle tags
634*b1cdbd2cSJim Jagielski // { "<#TAG_GROUP_SINGLE>", TAG_GROUP_SINGLE },
635*b1cdbd2cSJim Jagielski { "<#REFINSERT>", TAG_REFINSERT },
636*b1cdbd2cSJim Jagielski
637*b1cdbd2cSJim Jagielski // { "<#GROUP_MULTI>", TAG_GROUP_MULTI },
638*b1cdbd2cSJim Jagielski { "<#END>", TAG_END },
639*b1cdbd2cSJim Jagielski { "<#ELSE>", TAG_ELSE },
640*b1cdbd2cSJim Jagielski { "<#VERSIONEND>", TAG_VERSIONEND },
641*b1cdbd2cSJim Jagielski { "<#ENDGRAPHIC>", TAG_ENDGRAPHIC },*/
642*b1cdbd2cSJim Jagielski { "<Common Tag>", TAG_COMMONSTART },
643*b1cdbd2cSJim Jagielski { "</Common Tag>", TAG_COMMONEND },
644*b1cdbd2cSJim Jagielski
645*b1cdbd2cSJim Jagielski { "<no more tags>", TAG_NOMORETAGS },
646*b1cdbd2cSJim Jagielski { "", TAG_UNKNOWN_TAG },
647*b1cdbd2cSJim Jagielski };
648*b1cdbd2cSJim Jagielski
649*b1cdbd2cSJim Jagielski
SimpleParser()650*b1cdbd2cSJim Jagielski SimpleParser::SimpleParser()
651*b1cdbd2cSJim Jagielski : nPos( 0 )
652*b1cdbd2cSJim Jagielski , aNextTag( TAG_NOMORETAGS, TOK_INVALIDPOS )
653*b1cdbd2cSJim Jagielski {
654*b1cdbd2cSJim Jagielski }
655*b1cdbd2cSJim Jagielski
Parse(String PaSource)656*b1cdbd2cSJim Jagielski void SimpleParser::Parse( String PaSource )
657*b1cdbd2cSJim Jagielski {
658*b1cdbd2cSJim Jagielski aSource = PaSource;
659*b1cdbd2cSJim Jagielski nPos = 0;
660*b1cdbd2cSJim Jagielski aLastToken.Erase();
661*b1cdbd2cSJim Jagielski aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS );
662*b1cdbd2cSJim Jagielski aTokenList.Clear();
663*b1cdbd2cSJim Jagielski };
664*b1cdbd2cSJim Jagielski
GetNextToken(ParserMessageList & rErrorList)665*b1cdbd2cSJim Jagielski TokenInfo SimpleParser::GetNextToken( ParserMessageList &rErrorList )
666*b1cdbd2cSJim Jagielski {
667*b1cdbd2cSJim Jagielski TokenInfo aResult;
668*b1cdbd2cSJim Jagielski sal_uInt16 nTokenStartPos = 0;
669*b1cdbd2cSJim Jagielski if ( aNextTag.nId != TAG_NOMORETAGS )
670*b1cdbd2cSJim Jagielski {
671*b1cdbd2cSJim Jagielski aResult = aNextTag;
672*b1cdbd2cSJim Jagielski aNextTag = TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS );
673*b1cdbd2cSJim Jagielski }
674*b1cdbd2cSJim Jagielski else
675*b1cdbd2cSJim Jagielski {
676*b1cdbd2cSJim Jagielski aLastToken = GetNextTokenString( rErrorList, nTokenStartPos );
677*b1cdbd2cSJim Jagielski if ( aLastToken.Len() == 0 )
678*b1cdbd2cSJim Jagielski return TokenInfo( TAG_NOMORETAGS, TOK_INVALIDPOS );
679*b1cdbd2cSJim Jagielski
680*b1cdbd2cSJim Jagielski // do we have a \< ... \> style tag?
681*b1cdbd2cSJim Jagielski if ( aLastToken.Copy(0,2).EqualsAscii( "\\<" ) )
682*b1cdbd2cSJim Jagielski {
683*b1cdbd2cSJim Jagielski // check for paired \" \"
684*b1cdbd2cSJim Jagielski bool bEven = true;
685*b1cdbd2cSJim Jagielski sal_uInt16 nQuotePos = 0;
686*b1cdbd2cSJim Jagielski sal_uInt16 nQuotedQuotesPos = aLastToken.SearchAscii( "\\\"" );
687*b1cdbd2cSJim Jagielski sal_uInt16 nQuotedBackPos = aLastToken.SearchAscii( "\\\\" ); // this is only to kick out quoted backslashes
688*b1cdbd2cSJim Jagielski while ( nQuotedQuotesPos != STRING_NOTFOUND )
689*b1cdbd2cSJim Jagielski {
690*b1cdbd2cSJim Jagielski if ( nQuotedBackPos <= nQuotedQuotesPos )
691*b1cdbd2cSJim Jagielski nQuotePos = nQuotedBackPos+2;
692*b1cdbd2cSJim Jagielski else
693*b1cdbd2cSJim Jagielski {
694*b1cdbd2cSJim Jagielski nQuotePos = nQuotedQuotesPos+2;
695*b1cdbd2cSJim Jagielski bEven = !bEven;
696*b1cdbd2cSJim Jagielski }
697*b1cdbd2cSJim Jagielski nQuotedQuotesPos = aLastToken.SearchAscii( "\\\"", nQuotePos );
698*b1cdbd2cSJim Jagielski nQuotedBackPos = aLastToken.SearchAscii( "\\\\", nQuotePos ); // this is only to kick out quoted backslashes
699*b1cdbd2cSJim Jagielski }
700*b1cdbd2cSJim Jagielski if ( !bEven )
701*b1cdbd2cSJim Jagielski {
702*b1cdbd2cSJim Jagielski rErrorList.AddError( 24, "Missing quotes ( \\\" ) in Tag", TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken ) );
703*b1cdbd2cSJim Jagielski }
704*b1cdbd2cSJim Jagielski
705*b1cdbd2cSJim Jagielski // check if we have an end-tag or a start-tag
706*b1cdbd2cSJim Jagielski sal_uInt16 nNonBlankStartPos,nNonBlankEndPos;
707*b1cdbd2cSJim Jagielski nNonBlankStartPos = 2;
708*b1cdbd2cSJim Jagielski while ( aLastToken.GetChar(nNonBlankStartPos) == ' ' )
709*b1cdbd2cSJim Jagielski nNonBlankStartPos++;
710*b1cdbd2cSJim Jagielski if ( aLastToken.GetChar(nNonBlankStartPos) == '/' )
711*b1cdbd2cSJim Jagielski aResult = TokenInfo( TAG_COMMONEND, nTokenStartPos, aLastToken, rErrorList );
712*b1cdbd2cSJim Jagielski else
713*b1cdbd2cSJim Jagielski {
714*b1cdbd2cSJim Jagielski aResult = TokenInfo( TAG_COMMONSTART, nTokenStartPos, aLastToken, rErrorList );
715*b1cdbd2cSJim Jagielski nNonBlankEndPos = aLastToken.Len() -3;
716*b1cdbd2cSJim Jagielski while ( aLastToken.GetChar(nNonBlankEndPos) == ' ' )
717*b1cdbd2cSJim Jagielski nNonBlankEndPos--;
718*b1cdbd2cSJim Jagielski if ( aLastToken.GetChar( nNonBlankEndPos ) == '/' )
719*b1cdbd2cSJim Jagielski aNextTag = TokenInfo( TAG_COMMONEND, nTokenStartPos, String::CreateFromAscii("\\</").Append(aResult.GetTagName()).AppendAscii("\\>"), rErrorList );
720*b1cdbd2cSJim Jagielski }
721*b1cdbd2cSJim Jagielski }
722*b1cdbd2cSJim Jagielski else
723*b1cdbd2cSJim Jagielski {
724*b1cdbd2cSJim Jagielski sal_uInt16 i = 0;
725*b1cdbd2cSJim Jagielski while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG &&
726*b1cdbd2cSJim Jagielski aLastToken != aKnownTags[i].GetName() )
727*b1cdbd2cSJim Jagielski i++;
728*b1cdbd2cSJim Jagielski aResult = TokenInfo( aKnownTags[i].nTag, nTokenStartPos );
729*b1cdbd2cSJim Jagielski }
730*b1cdbd2cSJim Jagielski }
731*b1cdbd2cSJim Jagielski
732*b1cdbd2cSJim Jagielski if ( aResult.nId == TAG_UNKNOWN_TAG )
733*b1cdbd2cSJim Jagielski aResult = TokenInfo( TAG_UNKNOWN_TAG, nTokenStartPos, aLastToken );
734*b1cdbd2cSJim Jagielski aTokenList.Insert( aResult, LIST_APPEND );
735*b1cdbd2cSJim Jagielski return aResult;
736*b1cdbd2cSJim Jagielski }
737*b1cdbd2cSJim Jagielski
GetNextTokenString(ParserMessageList & rErrorList,sal_uInt16 & rTagStartPos)738*b1cdbd2cSJim Jagielski String SimpleParser::GetNextTokenString( ParserMessageList &rErrorList, sal_uInt16 &rTagStartPos )
739*b1cdbd2cSJim Jagielski {
740*b1cdbd2cSJim Jagielski // sal_uInt16 nStyle1StartPos = aSource.SearchAscii( "<#", nPos );
741*b1cdbd2cSJim Jagielski sal_uInt16 nStyle2StartPos = aSource.SearchAscii( "$[", nPos );
742*b1cdbd2cSJim Jagielski sal_uInt16 nStyle3StartPos = aSource.SearchAscii( "\\<", nPos );
743*b1cdbd2cSJim Jagielski sal_uInt16 nStyle4StartPos = aSource.SearchAscii( "\\\\", nPos ); // this is only to kick out quoted backslashes
744*b1cdbd2cSJim Jagielski
745*b1cdbd2cSJim Jagielski rTagStartPos = 0;
746*b1cdbd2cSJim Jagielski
747*b1cdbd2cSJim Jagielski /* removing since a \<... is not likely
748*b1cdbd2cSJim Jagielski // check if the tag starts with a letter to avoid things like <> <= ... >
749*b1cdbd2cSJim Jagielski while ( STRING_NOTFOUND != nStyle3StartPos && !( aSource.Copy( nStyle3StartPos+2, 1 ).IsAlphaAscii() || aSource.GetChar( nStyle3StartPos+2 ) == '/' ) )
750*b1cdbd2cSJim Jagielski nStyle3StartPos = aSource.SearchAscii( "\\<", nStyle3StartPos+1 );
751*b1cdbd2cSJim Jagielski */
752*b1cdbd2cSJim Jagielski if ( STRING_NOTFOUND == nStyle2StartPos && STRING_NOTFOUND == nStyle3StartPos )
753*b1cdbd2cSJim Jagielski return String(); // no more tokens
754*b1cdbd2cSJim Jagielski
755*b1cdbd2cSJim Jagielski if ( nStyle4StartPos < nStyle2StartPos && nStyle4StartPos <= nStyle3StartPos ) // <= to make sure \\ is always handled first
756*b1cdbd2cSJim Jagielski { // Skip quoted Backslash
757*b1cdbd2cSJim Jagielski nPos = nStyle4StartPos +2;
758*b1cdbd2cSJim Jagielski return GetNextTokenString( rErrorList, rTagStartPos );
759*b1cdbd2cSJim Jagielski }
760*b1cdbd2cSJim Jagielski
761*b1cdbd2cSJim Jagielski /* if ( nStyle1StartPos < nStyle2StartPos && nStyle1StartPos <= nStyle3StartPos ) // <= to make sure our spechial tags are recognized before all others
762*b1cdbd2cSJim Jagielski { // test for <# ... > style tokens
763*b1cdbd2cSJim Jagielski sal_uInt16 nEndPos = aSource.SearchAscii( ">", nStyle1StartPos );
764*b1cdbd2cSJim Jagielski if ( nEndPos == STRING_NOTFOUND )
765*b1cdbd2cSJim Jagielski { // Token is incomplete. Skip start and search for better ones
766*b1cdbd2cSJim Jagielski nPos = nStyle1StartPos +2;
767*b1cdbd2cSJim Jagielski return GetNextTokenString( rErrorList, rTagStartPos );
768*b1cdbd2cSJim Jagielski }
769*b1cdbd2cSJim Jagielski nPos = nEndPos;
770*b1cdbd2cSJim Jagielski rTagStartPos = nStyle1StartPos;
771*b1cdbd2cSJim Jagielski return aSource.Copy( nStyle1StartPos, nEndPos-nStyle1StartPos +1 ).ToUpperAscii();
772*b1cdbd2cSJim Jagielski }
773*b1cdbd2cSJim Jagielski else*/ if ( nStyle2StartPos < nStyle3StartPos )
774*b1cdbd2cSJim Jagielski { // test for $[ ... ] style tokens
775*b1cdbd2cSJim Jagielski sal_uInt16 nEndPos = aSource.SearchAscii( "]", nStyle2StartPos);
776*b1cdbd2cSJim Jagielski if ( nEndPos == STRING_NOTFOUND )
777*b1cdbd2cSJim Jagielski { // Token is incomplete. Skip start and search for better ones
778*b1cdbd2cSJim Jagielski nPos = nStyle2StartPos +2;
779*b1cdbd2cSJim Jagielski return GetNextTokenString( rErrorList, rTagStartPos );
780*b1cdbd2cSJim Jagielski }
781*b1cdbd2cSJim Jagielski nPos = nEndPos;
782*b1cdbd2cSJim Jagielski rTagStartPos = nStyle2StartPos;
783*b1cdbd2cSJim Jagielski return aSource.Copy( nStyle2StartPos, nEndPos-nStyle2StartPos +1 );
784*b1cdbd2cSJim Jagielski }
785*b1cdbd2cSJim Jagielski else
786*b1cdbd2cSJim Jagielski { // test for \< ... \> style tokens
787*b1cdbd2cSJim Jagielski sal_uInt16 nEndPos = aSource.SearchAscii( "\\>", nStyle3StartPos);
788*b1cdbd2cSJim Jagielski sal_uInt16 nQuotedBackPos = aSource.SearchAscii( "\\\\", nStyle3StartPos ); // this is only to kick out quoted backslashes
789*b1cdbd2cSJim Jagielski while ( nQuotedBackPos <= nEndPos && nQuotedBackPos != STRING_NOTFOUND )
790*b1cdbd2cSJim Jagielski {
791*b1cdbd2cSJim Jagielski nEndPos = aSource.SearchAscii( "\\>", nQuotedBackPos +2);
792*b1cdbd2cSJim Jagielski nQuotedBackPos = aSource.SearchAscii( "\\\\", nQuotedBackPos +2 ); // this is only to kick out quoted backslashes
793*b1cdbd2cSJim Jagielski }
794*b1cdbd2cSJim Jagielski if ( nEndPos == STRING_NOTFOUND )
795*b1cdbd2cSJim Jagielski { // Token is incomplete. Skip start and search for better ones
796*b1cdbd2cSJim Jagielski nPos = nStyle3StartPos +2;
797*b1cdbd2cSJim Jagielski ByteString sTmp( "Tag Start '\\<' without Tag End '\\>': " );
798*b1cdbd2cSJim Jagielski rErrorList.AddError( 24, "Tag Start '\\<' without Tag End '\\>'", TokenInfo( TAG_UNKNOWN_TAG, nStyle3StartPos, aSource.Copy( nStyle3StartPos-10, 20 ) ) );
799*b1cdbd2cSJim Jagielski return GetNextTokenString( rErrorList, rTagStartPos );
800*b1cdbd2cSJim Jagielski }
801*b1cdbd2cSJim Jagielski // check for paired quoted " --> \"sometext\"
802*b1cdbd2cSJim Jagielski
803*b1cdbd2cSJim Jagielski nPos = nEndPos;
804*b1cdbd2cSJim Jagielski rTagStartPos = nStyle3StartPos;
805*b1cdbd2cSJim Jagielski return aSource.Copy( nStyle3StartPos, nEndPos-nStyle3StartPos +2 );
806*b1cdbd2cSJim Jagielski }
807*b1cdbd2cSJim Jagielski }
808*b1cdbd2cSJim Jagielski
GetLexem(TokenInfo const & aToken)809*b1cdbd2cSJim Jagielski String SimpleParser::GetLexem( TokenInfo const &aToken )
810*b1cdbd2cSJim Jagielski {
811*b1cdbd2cSJim Jagielski if ( aToken.aTokenString.Len() )
812*b1cdbd2cSJim Jagielski return aToken.aTokenString;
813*b1cdbd2cSJim Jagielski else
814*b1cdbd2cSJim Jagielski {
815*b1cdbd2cSJim Jagielski sal_uInt16 i = 0;
816*b1cdbd2cSJim Jagielski while ( aKnownTags[i].nTag != TAG_UNKNOWN_TAG &&
817*b1cdbd2cSJim Jagielski aKnownTags[i].nTag != aToken.nId )
818*b1cdbd2cSJim Jagielski i++;
819*b1cdbd2cSJim Jagielski
820*b1cdbd2cSJim Jagielski return aKnownTags[i].GetName();
821*b1cdbd2cSJim Jagielski }
822*b1cdbd2cSJim Jagielski }
823*b1cdbd2cSJim Jagielski
TokenParser()824*b1cdbd2cSJim Jagielski TokenParser::TokenParser()
825*b1cdbd2cSJim Jagielski : pErrorList( NULL )
826*b1cdbd2cSJim Jagielski {}
827*b1cdbd2cSJim Jagielski
Parse(const String & aCode,ParserMessageList * pList)828*b1cdbd2cSJim Jagielski void TokenParser::Parse( const String &aCode, ParserMessageList* pList )
829*b1cdbd2cSJim Jagielski {
830*b1cdbd2cSJim Jagielski pErrorList = pList;
831*b1cdbd2cSJim Jagielski
832*b1cdbd2cSJim Jagielski //Scanner initialisieren
833*b1cdbd2cSJim Jagielski aParser.Parse( aCode );
834*b1cdbd2cSJim Jagielski
835*b1cdbd2cSJim Jagielski //erstes Symbol holen
836*b1cdbd2cSJim Jagielski aTag = aParser.GetNextToken( *pErrorList );
837*b1cdbd2cSJim Jagielski
838*b1cdbd2cSJim Jagielski nPfCaseOptions = 0;
839*b1cdbd2cSJim Jagielski nAppCaseOptions = 0;
840*b1cdbd2cSJim Jagielski bPfCaseActive = sal_False;
841*b1cdbd2cSJim Jagielski bAppCaseActive = sal_False;
842*b1cdbd2cSJim Jagielski
843*b1cdbd2cSJim Jagielski nActiveRefTypes = 0;
844*b1cdbd2cSJim Jagielski
845*b1cdbd2cSJim Jagielski //Ausfuehren der Start-Produktion
846*b1cdbd2cSJim Jagielski Paragraph();
847*b1cdbd2cSJim Jagielski
848*b1cdbd2cSJim Jagielski //Es wurde nicht die ganze Kette abgearbeitet, bisher ist aber
849*b1cdbd2cSJim Jagielski //kein Fehler aufgetreten
850*b1cdbd2cSJim Jagielski //=> es wurde ein einleitendes Tag vergessen
851*b1cdbd2cSJim Jagielski if ( aTag.nId != TAG_NOMORETAGS )
852*b1cdbd2cSJim Jagielski {
853*b1cdbd2cSJim Jagielski switch ( aTag.nId )
854*b1cdbd2cSJim Jagielski {
855*b1cdbd2cSJim Jagielski case TAG_END:
856*b1cdbd2cSJim Jagielski {
857*b1cdbd2cSJim Jagielski ParseError( 3, "Extra Tag <#END>. Switch or <#HREF> expected.", aTag );
858*b1cdbd2cSJim Jagielski }
859*b1cdbd2cSJim Jagielski break;
860*b1cdbd2cSJim Jagielski case TAG_BOLDOFF:
861*b1cdbd2cSJim Jagielski {
862*b1cdbd2cSJim Jagielski ParseError( 4, "<#BOLD> expected before <#/BOLD>.", aTag );
863*b1cdbd2cSJim Jagielski }
864*b1cdbd2cSJim Jagielski break;
865*b1cdbd2cSJim Jagielski case TAG_ITALICOFF:
866*b1cdbd2cSJim Jagielski {
867*b1cdbd2cSJim Jagielski ParseError( 5, "<#ITALIC> expected before <#/ITALIC>.", aTag );
868*b1cdbd2cSJim Jagielski }
869*b1cdbd2cSJim Jagielski break;
870*b1cdbd2cSJim Jagielski case TAG_UNDERLINEOFF:
871*b1cdbd2cSJim Jagielski {
872*b1cdbd2cSJim Jagielski ParseError( 17, "<#UNDER> expected before <#/UNDER>.", aTag );
873*b1cdbd2cSJim Jagielski }
874*b1cdbd2cSJim Jagielski break;
875*b1cdbd2cSJim Jagielski /* case TAG_MISSPARENTHESIS:
876*b1cdbd2cSJim Jagielski {
877*b1cdbd2cSJim Jagielski ParseError( 14, "missing closing parenthesis '>'", aTag );
878*b1cdbd2cSJim Jagielski }
879*b1cdbd2cSJim Jagielski break;*/
880*b1cdbd2cSJim Jagielski case TAG_AEND:
881*b1cdbd2cSJim Jagielski {
882*b1cdbd2cSJim Jagielski ParseError( 5, "Extra Tag <#AEND>. <#AVIS> or <#AHID> expected.", aTag );
883*b1cdbd2cSJim Jagielski }
884*b1cdbd2cSJim Jagielski break;
885*b1cdbd2cSJim Jagielski case TAG_ELSE:
886*b1cdbd2cSJim Jagielski {
887*b1cdbd2cSJim Jagielski ParseError( 16, "Application-tag or platform-tag expected before <#ELSE>.", aTag );
888*b1cdbd2cSJim Jagielski }
889*b1cdbd2cSJim Jagielski break;
890*b1cdbd2cSJim Jagielski case TAG_UNKNOWN_TAG:
891*b1cdbd2cSJim Jagielski {
892*b1cdbd2cSJim Jagielski ParseError( 6, "unknown Tag", aTag );
893*b1cdbd2cSJim Jagielski }
894*b1cdbd2cSJim Jagielski break;
895*b1cdbd2cSJim Jagielski default:
896*b1cdbd2cSJim Jagielski {
897*b1cdbd2cSJim Jagielski ParseError( 6, "unexpected Tag", aTag );
898*b1cdbd2cSJim Jagielski }
899*b1cdbd2cSJim Jagielski }
900*b1cdbd2cSJim Jagielski }
901*b1cdbd2cSJim Jagielski pErrorList = NULL;
902*b1cdbd2cSJim Jagielski }
903*b1cdbd2cSJim Jagielski
Paragraph()904*b1cdbd2cSJim Jagielski void TokenParser::Paragraph()
905*b1cdbd2cSJim Jagielski {
906*b1cdbd2cSJim Jagielski switch ( aTag.nId )
907*b1cdbd2cSJim Jagielski {
908*b1cdbd2cSJim Jagielski case TAG_GRAPHIC:
909*b1cdbd2cSJim Jagielski case TAG_NEXTVERSION:
910*b1cdbd2cSJim Jagielski {
911*b1cdbd2cSJim Jagielski TagRef();
912*b1cdbd2cSJim Jagielski Paragraph();
913*b1cdbd2cSJim Jagielski }
914*b1cdbd2cSJim Jagielski break;
915*b1cdbd2cSJim Jagielski case TAG_AVIS:
916*b1cdbd2cSJim Jagielski case TAG_AHID:
917*b1cdbd2cSJim Jagielski {
918*b1cdbd2cSJim Jagielski TagRef();
919*b1cdbd2cSJim Jagielski Paragraph();
920*b1cdbd2cSJim Jagielski }
921*b1cdbd2cSJim Jagielski break;
922*b1cdbd2cSJim Jagielski case TAG_HELPID:
923*b1cdbd2cSJim Jagielski {
924*b1cdbd2cSJim Jagielski SimpleTag();
925*b1cdbd2cSJim Jagielski Paragraph();
926*b1cdbd2cSJim Jagielski }
927*b1cdbd2cSJim Jagielski break;
928*b1cdbd2cSJim Jagielski case TAG_OFFICEFULLNAME:
929*b1cdbd2cSJim Jagielski case TAG_OFFICENAME:
930*b1cdbd2cSJim Jagielski case TAG_OFFICEPATH:
931*b1cdbd2cSJim Jagielski case TAG_OFFICEVERSION:
932*b1cdbd2cSJim Jagielski case TAG_PORTALNAME:
933*b1cdbd2cSJim Jagielski case TAG_PORTALFULLNAME:
934*b1cdbd2cSJim Jagielski case TAG_PORTALPATH:
935*b1cdbd2cSJim Jagielski case TAG_PORTALVERSION:
936*b1cdbd2cSJim Jagielski case TAG_PORTALSHORTNAME:
937*b1cdbd2cSJim Jagielski {
938*b1cdbd2cSJim Jagielski SimpleTag();
939*b1cdbd2cSJim Jagielski Paragraph();
940*b1cdbd2cSJim Jagielski }
941*b1cdbd2cSJim Jagielski break;
942*b1cdbd2cSJim Jagielski case TAG_REFINSERT:
943*b1cdbd2cSJim Jagielski {
944*b1cdbd2cSJim Jagielski SimpleTag();
945*b1cdbd2cSJim Jagielski Paragraph();
946*b1cdbd2cSJim Jagielski }
947*b1cdbd2cSJim Jagielski break;
948*b1cdbd2cSJim Jagielski case TAG_BOLDON:
949*b1cdbd2cSJim Jagielski case TAG_ITALICON:
950*b1cdbd2cSJim Jagielski case TAG_UNDERLINEON:
951*b1cdbd2cSJim Jagielski case TAG_COMMONSTART:
952*b1cdbd2cSJim Jagielski {
953*b1cdbd2cSJim Jagielski TagPair();
954*b1cdbd2cSJim Jagielski Paragraph();
955*b1cdbd2cSJim Jagielski }
956*b1cdbd2cSJim Jagielski break;
957*b1cdbd2cSJim Jagielski case TAG_HREF:
958*b1cdbd2cSJim Jagielski case TAG_NAME:
959*b1cdbd2cSJim Jagielski case TAG_KEY:
960*b1cdbd2cSJim Jagielski case TAG_INDEX:
961*b1cdbd2cSJim Jagielski case TAG_TITEL:
962*b1cdbd2cSJim Jagielski case TAG_REFSTART:
963*b1cdbd2cSJim Jagielski {
964*b1cdbd2cSJim Jagielski TagRef();
965*b1cdbd2cSJim Jagielski Paragraph();
966*b1cdbd2cSJim Jagielski }
967*b1cdbd2cSJim Jagielski break;
968*b1cdbd2cSJim Jagielski case TAG_OS2:
969*b1cdbd2cSJim Jagielski case TAG_WIN:
970*b1cdbd2cSJim Jagielski case TAG_UNIX:
971*b1cdbd2cSJim Jagielski case TAG_MAC: //...
972*b1cdbd2cSJim Jagielski {
973*b1cdbd2cSJim Jagielski if ( ! bPfCaseActive )
974*b1cdbd2cSJim Jagielski {
975*b1cdbd2cSJim Jagielski //PfCases duerfen nicht verschachtelt sein:
976*b1cdbd2cSJim Jagielski bPfCaseActive = sal_True;
977*b1cdbd2cSJim Jagielski PfCase();
978*b1cdbd2cSJim Jagielski
979*b1cdbd2cSJim Jagielski //So jetzt kann wieder ein PfCase kommen:
980*b1cdbd2cSJim Jagielski bPfCaseActive = sal_False;
981*b1cdbd2cSJim Jagielski Paragraph();
982*b1cdbd2cSJim Jagielski }
983*b1cdbd2cSJim Jagielski }
984*b1cdbd2cSJim Jagielski break;
985*b1cdbd2cSJim Jagielski case TAG_WRITER:
986*b1cdbd2cSJim Jagielski case TAG_CALC:
987*b1cdbd2cSJim Jagielski case TAG_DRAW:
988*b1cdbd2cSJim Jagielski case TAG_IMPRESS:
989*b1cdbd2cSJim Jagielski case TAG_SCHEDULE:
990*b1cdbd2cSJim Jagielski case TAG_IMAGE:
991*b1cdbd2cSJim Jagielski case TAG_MATH:
992*b1cdbd2cSJim Jagielski case TAG_CHART:
993*b1cdbd2cSJim Jagielski case TAG_OFFICE:
994*b1cdbd2cSJim Jagielski {
995*b1cdbd2cSJim Jagielski if ( !bAppCaseActive )
996*b1cdbd2cSJim Jagielski {
997*b1cdbd2cSJim Jagielski //AppCases duerfen nicht verschachtelt sein:
998*b1cdbd2cSJim Jagielski bAppCaseActive = sal_True;
999*b1cdbd2cSJim Jagielski AppCase();
1000*b1cdbd2cSJim Jagielski
1001*b1cdbd2cSJim Jagielski //jetzt koennen wieder AppCases kommen:
1002*b1cdbd2cSJim Jagielski bAppCaseActive = sal_False;
1003*b1cdbd2cSJim Jagielski Paragraph();
1004*b1cdbd2cSJim Jagielski }
1005*b1cdbd2cSJim Jagielski }
1006*b1cdbd2cSJim Jagielski break;
1007*b1cdbd2cSJim Jagielski
1008*b1cdbd2cSJim Jagielski //Case TAG_BOLDOFF, TAG_ITALICOFF, TAG_BUNDERLINE, TAG_END
1009*b1cdbd2cSJim Jagielski //nichts tun wg. epsilon-Prod.
1010*b1cdbd2cSJim Jagielski }
1011*b1cdbd2cSJim Jagielski }
1012*b1cdbd2cSJim Jagielski
PfCase()1013*b1cdbd2cSJim Jagielski void TokenParser::PfCase()
1014*b1cdbd2cSJim Jagielski {
1015*b1cdbd2cSJim Jagielski
1016*b1cdbd2cSJim Jagielski //Produktion:
1017*b1cdbd2cSJim Jagielski //PfCase -> PfCaseBegin Paragraph (PfCase | PfCaseEnd)
1018*b1cdbd2cSJim Jagielski
1019*b1cdbd2cSJim Jagielski PfCaseBegin();
1020*b1cdbd2cSJim Jagielski
1021*b1cdbd2cSJim Jagielski //Jetzt ist eine PfCase-Produktion aktiv:
1022*b1cdbd2cSJim Jagielski Paragraph();
1023*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1024*b1cdbd2cSJim Jagielski {
1025*b1cdbd2cSJim Jagielski case TAG_ELSE:
1026*b1cdbd2cSJim Jagielski case TAG_END:
1027*b1cdbd2cSJim Jagielski {
1028*b1cdbd2cSJim Jagielski CaseEnd();
1029*b1cdbd2cSJim Jagielski }
1030*b1cdbd2cSJim Jagielski break;
1031*b1cdbd2cSJim Jagielski case TAG_OS2:
1032*b1cdbd2cSJim Jagielski case TAG_WIN:
1033*b1cdbd2cSJim Jagielski case TAG_UNIX:
1034*b1cdbd2cSJim Jagielski case TAG_MAC: //First (PfBegin)
1035*b1cdbd2cSJim Jagielski {
1036*b1cdbd2cSJim Jagielski PfCase();
1037*b1cdbd2cSJim Jagielski }
1038*b1cdbd2cSJim Jagielski break;
1039*b1cdbd2cSJim Jagielski default:
1040*b1cdbd2cSJim Jagielski ParseError( 8, "<#ELSE> or <#END> or platform-tag expected.", aTag );
1041*b1cdbd2cSJim Jagielski }
1042*b1cdbd2cSJim Jagielski //Die gemerkten Tags wieder loeschen fuer naechstes PfCase:
1043*b1cdbd2cSJim Jagielski nPfCaseOptions = 0;
1044*b1cdbd2cSJim Jagielski }
1045*b1cdbd2cSJim Jagielski
PfCaseBegin()1046*b1cdbd2cSJim Jagielski void TokenParser::PfCaseBegin()
1047*b1cdbd2cSJim Jagielski {
1048*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1049*b1cdbd2cSJim Jagielski {
1050*b1cdbd2cSJim Jagielski case TAG_OS2:
1051*b1cdbd2cSJim Jagielski case TAG_WIN:
1052*b1cdbd2cSJim Jagielski case TAG_UNIX:
1053*b1cdbd2cSJim Jagielski case TAG_MAC:
1054*b1cdbd2cSJim Jagielski {
1055*b1cdbd2cSJim Jagielski //Token darf noch nicht vorgekommen sein im
1056*b1cdbd2cSJim Jagielski //aktuellen Plattform-Case:
1057*b1cdbd2cSJim Jagielski if ( !HAS_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) ) )
1058*b1cdbd2cSJim Jagielski {
1059*b1cdbd2cSJim Jagielski SET_FLAG( nPfCaseOptions, TAG_NOGROUP( aTag.nId ) );
1060*b1cdbd2cSJim Jagielski match( aTag, aTag );
1061*b1cdbd2cSJim Jagielski }
1062*b1cdbd2cSJim Jagielski else {
1063*b1cdbd2cSJim Jagielski ParseError( 9, "Tag defined twice in the same platform-case", aTag );
1064*b1cdbd2cSJim Jagielski }
1065*b1cdbd2cSJim Jagielski }
1066*b1cdbd2cSJim Jagielski }
1067*b1cdbd2cSJim Jagielski }
1068*b1cdbd2cSJim Jagielski
AppCase()1069*b1cdbd2cSJim Jagielski void TokenParser::AppCase()
1070*b1cdbd2cSJim Jagielski {
1071*b1cdbd2cSJim Jagielski
1072*b1cdbd2cSJim Jagielski //Produktion:
1073*b1cdbd2cSJim Jagielski //AppCase -> AppCaseBegin Paragraph (AppCase | AppCaseEnd)
1074*b1cdbd2cSJim Jagielski
1075*b1cdbd2cSJim Jagielski
1076*b1cdbd2cSJim Jagielski AppCaseBegin();
1077*b1cdbd2cSJim Jagielski
1078*b1cdbd2cSJim Jagielski Paragraph();
1079*b1cdbd2cSJim Jagielski
1080*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1081*b1cdbd2cSJim Jagielski {
1082*b1cdbd2cSJim Jagielski case TAG_ELSE:
1083*b1cdbd2cSJim Jagielski case TAG_END:
1084*b1cdbd2cSJim Jagielski {
1085*b1cdbd2cSJim Jagielski CaseEnd();
1086*b1cdbd2cSJim Jagielski }
1087*b1cdbd2cSJim Jagielski break;
1088*b1cdbd2cSJim Jagielski case TAG_WRITER:
1089*b1cdbd2cSJim Jagielski case TAG_DRAW:
1090*b1cdbd2cSJim Jagielski case TAG_CALC:
1091*b1cdbd2cSJim Jagielski case TAG_IMAGE:
1092*b1cdbd2cSJim Jagielski case TAG_MATH:
1093*b1cdbd2cSJim Jagielski case TAG_CHART:
1094*b1cdbd2cSJim Jagielski case TAG_OFFICE:
1095*b1cdbd2cSJim Jagielski case TAG_IMPRESS:
1096*b1cdbd2cSJim Jagielski case TAG_SCHEDULE: //First (AppBegin)
1097*b1cdbd2cSJim Jagielski {
1098*b1cdbd2cSJim Jagielski AppCase();
1099*b1cdbd2cSJim Jagielski }
1100*b1cdbd2cSJim Jagielski break;
1101*b1cdbd2cSJim Jagielski default:
1102*b1cdbd2cSJim Jagielski ParseError( 1, "<#ELSE> or <#END> or application-case-tag expected.", aTag );
1103*b1cdbd2cSJim Jagielski }
1104*b1cdbd2cSJim Jagielski
1105*b1cdbd2cSJim Jagielski //Die gemerkten Tags wieder loeschen fuer naechstes AppCase:
1106*b1cdbd2cSJim Jagielski nAppCaseOptions = 0;
1107*b1cdbd2cSJim Jagielski }
1108*b1cdbd2cSJim Jagielski
AppCaseBegin()1109*b1cdbd2cSJim Jagielski void TokenParser::AppCaseBegin()
1110*b1cdbd2cSJim Jagielski {
1111*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1112*b1cdbd2cSJim Jagielski {
1113*b1cdbd2cSJim Jagielski case TAG_WRITER:
1114*b1cdbd2cSJim Jagielski case TAG_DRAW:
1115*b1cdbd2cSJim Jagielski case TAG_CALC:
1116*b1cdbd2cSJim Jagielski case TAG_IMAGE:
1117*b1cdbd2cSJim Jagielski case TAG_MATH:
1118*b1cdbd2cSJim Jagielski case TAG_CHART:
1119*b1cdbd2cSJim Jagielski case TAG_OFFICE:
1120*b1cdbd2cSJim Jagielski case TAG_IMPRESS:
1121*b1cdbd2cSJim Jagielski case TAG_SCHEDULE:
1122*b1cdbd2cSJim Jagielski {
1123*b1cdbd2cSJim Jagielski //Token darf noch nicht vorgekommen sein im
1124*b1cdbd2cSJim Jagielski //aktuellen Plattform-Case:
1125*b1cdbd2cSJim Jagielski if ( !HAS_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) ) )
1126*b1cdbd2cSJim Jagielski {
1127*b1cdbd2cSJim Jagielski SET_FLAG( nAppCaseOptions, TAG_NOGROUP( aTag.nId ) );
1128*b1cdbd2cSJim Jagielski match( aTag, aTag );
1129*b1cdbd2cSJim Jagielski }
1130*b1cdbd2cSJim Jagielski else {
1131*b1cdbd2cSJim Jagielski ParseError( 13, "Tag defined twice in the same application-case.", aTag );
1132*b1cdbd2cSJim Jagielski }
1133*b1cdbd2cSJim Jagielski }
1134*b1cdbd2cSJim Jagielski }
1135*b1cdbd2cSJim Jagielski }
1136*b1cdbd2cSJim Jagielski
CaseEnd()1137*b1cdbd2cSJim Jagielski void TokenParser::CaseEnd()
1138*b1cdbd2cSJim Jagielski {
1139*b1cdbd2cSJim Jagielski //Produktion:
1140*b1cdbd2cSJim Jagielski //CaseEnd -> <#ELSE> Paragraph <#END> | <#END>
1141*b1cdbd2cSJim Jagielski
1142*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1143*b1cdbd2cSJim Jagielski {
1144*b1cdbd2cSJim Jagielski case TAG_ELSE:
1145*b1cdbd2cSJim Jagielski {
1146*b1cdbd2cSJim Jagielski match( aTag, TAG_ELSE );
1147*b1cdbd2cSJim Jagielski Paragraph();
1148*b1cdbd2cSJim Jagielski match( aTag, TAG_END );
1149*b1cdbd2cSJim Jagielski }
1150*b1cdbd2cSJim Jagielski break;
1151*b1cdbd2cSJim Jagielski case TAG_END:
1152*b1cdbd2cSJim Jagielski {
1153*b1cdbd2cSJim Jagielski match( aTag, TAG_END );
1154*b1cdbd2cSJim Jagielski }
1155*b1cdbd2cSJim Jagielski break;
1156*b1cdbd2cSJim Jagielski default:
1157*b1cdbd2cSJim Jagielski ParseError( 2, "<#ELSE> or <#END> expected.", aTag );
1158*b1cdbd2cSJim Jagielski }
1159*b1cdbd2cSJim Jagielski }
1160*b1cdbd2cSJim Jagielski
SimpleTag()1161*b1cdbd2cSJim Jagielski void TokenParser::SimpleTag()
1162*b1cdbd2cSJim Jagielski {
1163*b1cdbd2cSJim Jagielski
1164*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1165*b1cdbd2cSJim Jagielski {
1166*b1cdbd2cSJim Jagielski case TAG_HELPID:
1167*b1cdbd2cSJim Jagielski {
1168*b1cdbd2cSJim Jagielski match( aTag, TAG_HELPID );
1169*b1cdbd2cSJim Jagielski }
1170*b1cdbd2cSJim Jagielski break;
1171*b1cdbd2cSJim Jagielski case TAG_OFFICEFULLNAME:
1172*b1cdbd2cSJim Jagielski case TAG_OFFICENAME:
1173*b1cdbd2cSJim Jagielski case TAG_OFFICEPATH:
1174*b1cdbd2cSJim Jagielski case TAG_OFFICEVERSION:
1175*b1cdbd2cSJim Jagielski case TAG_PORTALNAME:
1176*b1cdbd2cSJim Jagielski case TAG_PORTALFULLNAME:
1177*b1cdbd2cSJim Jagielski case TAG_PORTALPATH:
1178*b1cdbd2cSJim Jagielski case TAG_PORTALVERSION:
1179*b1cdbd2cSJim Jagielski case TAG_PORTALSHORTNAME:
1180*b1cdbd2cSJim Jagielski
1181*b1cdbd2cSJim Jagielski case TAG_REFINSERT:
1182*b1cdbd2cSJim Jagielski {
1183*b1cdbd2cSJim Jagielski match( aTag, aTag );
1184*b1cdbd2cSJim Jagielski }
1185*b1cdbd2cSJim Jagielski break;
1186*b1cdbd2cSJim Jagielski default:
1187*b1cdbd2cSJim Jagielski ParseError( 15, "[<#SimpleTag>] expected.", aTag );
1188*b1cdbd2cSJim Jagielski }
1189*b1cdbd2cSJim Jagielski }
1190*b1cdbd2cSJim Jagielski
TagPair()1191*b1cdbd2cSJim Jagielski void TokenParser::TagPair()
1192*b1cdbd2cSJim Jagielski {
1193*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1194*b1cdbd2cSJim Jagielski {
1195*b1cdbd2cSJim Jagielski case TAG_BOLDON:
1196*b1cdbd2cSJim Jagielski {
1197*b1cdbd2cSJim Jagielski match( aTag, TAG_BOLDON );
1198*b1cdbd2cSJim Jagielski Paragraph();
1199*b1cdbd2cSJim Jagielski match( aTag, TAG_BOLDOFF );
1200*b1cdbd2cSJim Jagielski }
1201*b1cdbd2cSJim Jagielski break;
1202*b1cdbd2cSJim Jagielski case TAG_ITALICON:
1203*b1cdbd2cSJim Jagielski {
1204*b1cdbd2cSJim Jagielski match( aTag, TAG_ITALICON );
1205*b1cdbd2cSJim Jagielski Paragraph();
1206*b1cdbd2cSJim Jagielski match( aTag, TAG_ITALICOFF );
1207*b1cdbd2cSJim Jagielski }
1208*b1cdbd2cSJim Jagielski break;
1209*b1cdbd2cSJim Jagielski case TAG_UNDERLINEON:
1210*b1cdbd2cSJim Jagielski {
1211*b1cdbd2cSJim Jagielski match( aTag, TAG_UNDERLINEON );
1212*b1cdbd2cSJim Jagielski Paragraph();
1213*b1cdbd2cSJim Jagielski match( aTag, TAG_UNDERLINEOFF );
1214*b1cdbd2cSJim Jagielski }
1215*b1cdbd2cSJim Jagielski break;
1216*b1cdbd2cSJim Jagielski case TAG_COMMONSTART:
1217*b1cdbd2cSJim Jagielski {
1218*b1cdbd2cSJim Jagielski //remember tag so we can give the original tag in case of an error
1219*b1cdbd2cSJim Jagielski TokenInfo aEndTag( aTag );
1220*b1cdbd2cSJim Jagielski aEndTag.nId = TAG_COMMONEND;
1221*b1cdbd2cSJim Jagielski match( aTag, TAG_COMMONSTART );
1222*b1cdbd2cSJim Jagielski Paragraph();
1223*b1cdbd2cSJim Jagielski match( aTag, aEndTag );
1224*b1cdbd2cSJim Jagielski }
1225*b1cdbd2cSJim Jagielski break;
1226*b1cdbd2cSJim Jagielski default:
1227*b1cdbd2cSJim Jagielski ParseError( 10, "<#BOLD>, <#ITALIC>, <#UNDER> expected.", aTag );
1228*b1cdbd2cSJim Jagielski }
1229*b1cdbd2cSJim Jagielski }
1230*b1cdbd2cSJim Jagielski
1231*b1cdbd2cSJim Jagielski
TagRef()1232*b1cdbd2cSJim Jagielski void TokenParser::TagRef()
1233*b1cdbd2cSJim Jagielski {
1234*b1cdbd2cSJim Jagielski switch ( aTag.nId )
1235*b1cdbd2cSJim Jagielski {
1236*b1cdbd2cSJim Jagielski case TAG_GRAPHIC:
1237*b1cdbd2cSJim Jagielski case TAG_NEXTVERSION:
1238*b1cdbd2cSJim Jagielski {
1239*b1cdbd2cSJim Jagielski if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) )
1240*b1cdbd2cSJim Jagielski {
1241*b1cdbd2cSJim Jagielski TokenId aThisToken = aTag.nId;
1242*b1cdbd2cSJim Jagielski SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
1243*b1cdbd2cSJim Jagielski match( aTag, aTag );
1244*b1cdbd2cSJim Jagielski Paragraph();
1245*b1cdbd2cSJim Jagielski if ( aThisToken == TAG_GRAPHIC )
1246*b1cdbd2cSJim Jagielski match( aTag, TAG_ENDGRAPHIC );
1247*b1cdbd2cSJim Jagielski else
1248*b1cdbd2cSJim Jagielski match( aTag, TAG_VERSIONEND );
1249*b1cdbd2cSJim Jagielski // don't reset since alowed only once per paragraph
1250*b1cdbd2cSJim Jagielski // RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
1251*b1cdbd2cSJim Jagielski }
1252*b1cdbd2cSJim Jagielski else
1253*b1cdbd2cSJim Jagielski {
1254*b1cdbd2cSJim Jagielski ParseError( 11, "Tags <#GRAPHIC>,<#NEXTVERSION> allowed only once per paragraph at", aTag );
1255*b1cdbd2cSJim Jagielski }
1256*b1cdbd2cSJim Jagielski }
1257*b1cdbd2cSJim Jagielski break;
1258*b1cdbd2cSJim Jagielski case TAG_AVIS:
1259*b1cdbd2cSJim Jagielski case TAG_AHID:
1260*b1cdbd2cSJim Jagielski {
1261*b1cdbd2cSJim Jagielski if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) )
1262*b1cdbd2cSJim Jagielski {
1263*b1cdbd2cSJim Jagielski TokenId aThisToken = aTag.nId;
1264*b1cdbd2cSJim Jagielski SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
1265*b1cdbd2cSJim Jagielski match( aTag, aTag );
1266*b1cdbd2cSJim Jagielski Paragraph();
1267*b1cdbd2cSJim Jagielski match( aTag, TAG_AEND );
1268*b1cdbd2cSJim Jagielski RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
1269*b1cdbd2cSJim Jagielski }
1270*b1cdbd2cSJim Jagielski else
1271*b1cdbd2cSJim Jagielski {
1272*b1cdbd2cSJim Jagielski ParseError( 11, "Nested <#AHID>,<#AVIS> not allowed.", aTag );
1273*b1cdbd2cSJim Jagielski }
1274*b1cdbd2cSJim Jagielski }
1275*b1cdbd2cSJim Jagielski break;
1276*b1cdbd2cSJim Jagielski case TAG_HREF:
1277*b1cdbd2cSJim Jagielski case TAG_NAME:
1278*b1cdbd2cSJim Jagielski {
1279*b1cdbd2cSJim Jagielski
1280*b1cdbd2cSJim Jagielski }
1281*b1cdbd2cSJim Jagielski // NOBREAK
1282*b1cdbd2cSJim Jagielski case TAG_KEY:
1283*b1cdbd2cSJim Jagielski case TAG_INDEX:
1284*b1cdbd2cSJim Jagielski case TAG_TITEL:
1285*b1cdbd2cSJim Jagielski case TAG_REFSTART:
1286*b1cdbd2cSJim Jagielski {
1287*b1cdbd2cSJim Jagielski if ( !HAS_FLAG( nActiveRefTypes, TAG_NOGROUP( aTag.nId ) ) )
1288*b1cdbd2cSJim Jagielski {
1289*b1cdbd2cSJim Jagielski TokenId aThisToken = aTag.nId;
1290*b1cdbd2cSJim Jagielski match( aTag, aTag );
1291*b1cdbd2cSJim Jagielski if ( aThisToken != TAG_NAME )
1292*b1cdbd2cSJim Jagielski { // TAG_NAME has no TAG_END
1293*b1cdbd2cSJim Jagielski SET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
1294*b1cdbd2cSJim Jagielski Paragraph();
1295*b1cdbd2cSJim Jagielski match( aTag, TAG_END );
1296*b1cdbd2cSJim Jagielski RESET_FLAG( nActiveRefTypes, TAG_NOGROUP( aThisToken ) );
1297*b1cdbd2cSJim Jagielski }
1298*b1cdbd2cSJim Jagielski }
1299*b1cdbd2cSJim Jagielski else
1300*b1cdbd2cSJim Jagielski {
1301*b1cdbd2cSJim Jagielski ParseError( 11, "Nested <#HREF>,<#NAME> or <#KEY> not allowed.", aTag );
1302*b1cdbd2cSJim Jagielski }
1303*b1cdbd2cSJim Jagielski }
1304*b1cdbd2cSJim Jagielski break;
1305*b1cdbd2cSJim Jagielski default:
1306*b1cdbd2cSJim Jagielski ParseError( 12, "<#HREF>,<#NAME> or <#KEY> expected.", aTag );
1307*b1cdbd2cSJim Jagielski }
1308*b1cdbd2cSJim Jagielski }
1309*b1cdbd2cSJim Jagielski
match(const TokenInfo & aCurrentToken,const TokenId & aExpectedToken)1310*b1cdbd2cSJim Jagielski sal_Bool TokenParser::match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken )
1311*b1cdbd2cSJim Jagielski {
1312*b1cdbd2cSJim Jagielski return match( aCurrentToken, TokenInfo( aExpectedToken, TOK_INVALIDPOS ) );
1313*b1cdbd2cSJim Jagielski }
1314*b1cdbd2cSJim Jagielski
match(const TokenInfo & aCurrentToken,const TokenInfo & rExpectedToken)1315*b1cdbd2cSJim Jagielski sal_Bool TokenParser::match( const TokenInfo &aCurrentToken, const TokenInfo &rExpectedToken )
1316*b1cdbd2cSJim Jagielski {
1317*b1cdbd2cSJim Jagielski TokenInfo aExpectedToken( rExpectedToken );
1318*b1cdbd2cSJim Jagielski if ( aCurrentToken.nId == aExpectedToken.nId )
1319*b1cdbd2cSJim Jagielski {
1320*b1cdbd2cSJim Jagielski if ( ( aCurrentToken.nId == TAG_COMMONEND
1321*b1cdbd2cSJim Jagielski && aCurrentToken.GetTagName().Equals( aExpectedToken.GetTagName() ) )
1322*b1cdbd2cSJim Jagielski || aCurrentToken.nId != TAG_COMMONEND )
1323*b1cdbd2cSJim Jagielski {
1324*b1cdbd2cSJim Jagielski aTag = aParser.GetNextToken( *pErrorList );
1325*b1cdbd2cSJim Jagielski return sal_True;
1326*b1cdbd2cSJim Jagielski }
1327*b1cdbd2cSJim Jagielski }
1328*b1cdbd2cSJim Jagielski
1329*b1cdbd2cSJim Jagielski if ( aExpectedToken.nId == TAG_COMMONEND )
1330*b1cdbd2cSJim Jagielski {
1331*b1cdbd2cSJim Jagielski aExpectedToken.aTokenString.Insert( String::CreateFromAscii( "Close tag for " ), 0 );
1332*b1cdbd2cSJim Jagielski }
1333*b1cdbd2cSJim Jagielski
1334*b1cdbd2cSJim Jagielski ByteString sTmp( "Expected Symbol" );
1335*b1cdbd2cSJim Jagielski if ( aCurrentToken.nId == TAG_NOMORETAGS )
1336*b1cdbd2cSJim Jagielski {
1337*b1cdbd2cSJim Jagielski ParseError( 7, sTmp, aExpectedToken );
1338*b1cdbd2cSJim Jagielski }
1339*b1cdbd2cSJim Jagielski else
1340*b1cdbd2cSJim Jagielski {
1341*b1cdbd2cSJim Jagielski sTmp += ": ";
1342*b1cdbd2cSJim Jagielski sTmp += ByteString( aParser.GetLexem( aExpectedToken ), RTL_TEXTENCODING_UTF8 );
1343*b1cdbd2cSJim Jagielski sTmp += " near ";
1344*b1cdbd2cSJim Jagielski ParseError( 7, sTmp, aCurrentToken );
1345*b1cdbd2cSJim Jagielski }
1346*b1cdbd2cSJim Jagielski return sal_False;
1347*b1cdbd2cSJim Jagielski }
1348*b1cdbd2cSJim Jagielski
ParseError(sal_uInt16 nErrNr,ByteString aErrMsg,const TokenInfo & rTag)1349*b1cdbd2cSJim Jagielski void TokenParser::ParseError( sal_uInt16 nErrNr, ByteString aErrMsg, const TokenInfo &rTag )
1350*b1cdbd2cSJim Jagielski {
1351*b1cdbd2cSJim Jagielski pErrorList->AddError( nErrNr, aErrMsg, rTag);
1352*b1cdbd2cSJim Jagielski
1353*b1cdbd2cSJim Jagielski // Das Fehlerhafte Tag ueberspringen
1354*b1cdbd2cSJim Jagielski aTag = aParser.GetNextToken( *pErrorList );
1355*b1cdbd2cSJim Jagielski }
1356*b1cdbd2cSJim Jagielski
1357*b1cdbd2cSJim Jagielski
ParserMessage(sal_uInt16 PnErrorNr,ByteString PaErrorText,const TokenInfo & rTag)1358*b1cdbd2cSJim Jagielski ParserMessage::ParserMessage( sal_uInt16 PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag )
1359*b1cdbd2cSJim Jagielski : nErrorNr( PnErrorNr )
1360*b1cdbd2cSJim Jagielski , aErrorText( PaErrorText )
1361*b1cdbd2cSJim Jagielski , nTagBegin( 0 )
1362*b1cdbd2cSJim Jagielski , nTagLength( 0 )
1363*b1cdbd2cSJim Jagielski {
1364*b1cdbd2cSJim Jagielski String aLexem( SimpleParser::GetLexem( rTag ) );
1365*b1cdbd2cSJim Jagielski aErrorText.Append(": ");
1366*b1cdbd2cSJim Jagielski aErrorText += ByteString( aLexem, RTL_TEXTENCODING_UTF8 );
1367*b1cdbd2cSJim Jagielski if ( rTag.nId == TAG_NOMORETAGS )
1368*b1cdbd2cSJim Jagielski aErrorText.Append(" at end of line ");
1369*b1cdbd2cSJim Jagielski else if ( rTag.nPos != TOK_INVALIDPOS )
1370*b1cdbd2cSJim Jagielski {
1371*b1cdbd2cSJim Jagielski aErrorText.Append(" at Position ");
1372*b1cdbd2cSJim Jagielski aErrorText.Append( ByteString::CreateFromInt32( rTag.nPos ) );
1373*b1cdbd2cSJim Jagielski }
1374*b1cdbd2cSJim Jagielski nTagBegin = rTag.nPos;
1375*b1cdbd2cSJim Jagielski nTagLength = aLexem.Len();
1376*b1cdbd2cSJim Jagielski }
1377*b1cdbd2cSJim Jagielski
ParserError(sal_uInt16 ErrorNr,ByteString ErrorText,const TokenInfo & rTag)1378*b1cdbd2cSJim Jagielski ParserError::ParserError( sal_uInt16 ErrorNr, ByteString ErrorText, const TokenInfo &rTag )
1379*b1cdbd2cSJim Jagielski : ParserMessage( ErrorNr, ErrorText, rTag )
1380*b1cdbd2cSJim Jagielski {}
1381*b1cdbd2cSJim Jagielski
ParserWarning(sal_uInt16 ErrorNr,ByteString ErrorText,const TokenInfo & rTag)1382*b1cdbd2cSJim Jagielski ParserWarning::ParserWarning( sal_uInt16 ErrorNr, ByteString ErrorText, const TokenInfo &rTag )
1383*b1cdbd2cSJim Jagielski : ParserMessage( ErrorNr, ErrorText, rTag )
1384*b1cdbd2cSJim Jagielski {}
1385*b1cdbd2cSJim Jagielski
IsTagMandatory(TokenInfo const & aToken,TokenId & aMetaTokens)1386*b1cdbd2cSJim Jagielski sal_Bool LingTest::IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens )
1387*b1cdbd2cSJim Jagielski {
1388*b1cdbd2cSJim Jagielski TokenId aTokenId = aToken.nId;
1389*b1cdbd2cSJim Jagielski TokenId aTokenGroup = TAG_GROUP( aTokenId );
1390*b1cdbd2cSJim Jagielski if ( TAG_GROUP_PROGSWITCH == aTokenGroup
1391*b1cdbd2cSJim Jagielski || TAG_REFINSERT == aTokenId
1392*b1cdbd2cSJim Jagielski || TAG_REFSTART == aTokenId
1393*b1cdbd2cSJim Jagielski || TAG_NAME == aTokenId
1394*b1cdbd2cSJim Jagielski || TAG_HREF == aTokenId
1395*b1cdbd2cSJim Jagielski || TAG_AVIS == aTokenId
1396*b1cdbd2cSJim Jagielski || TAG_AHID == aTokenId
1397*b1cdbd2cSJim Jagielski || TAG_GRAPHIC == aTokenId
1398*b1cdbd2cSJim Jagielski || TAG_NEXTVERSION == aTokenId
1399*b1cdbd2cSJim Jagielski || ( TAG_GROUP_META == aTokenGroup && (aMetaTokens & aTokenId) == aTokenId ) )
1400*b1cdbd2cSJim Jagielski {
1401*b1cdbd2cSJim Jagielski if ( TAG_GROUP_META == aTokenGroup )
1402*b1cdbd2cSJim Jagielski aMetaTokens |= aTokenId;
1403*b1cdbd2cSJim Jagielski return sal_True;
1404*b1cdbd2cSJim Jagielski }
1405*b1cdbd2cSJim Jagielski else if ( TAG_COMMONSTART == aTokenId
1406*b1cdbd2cSJim Jagielski || TAG_COMMONEND == aTokenId )
1407*b1cdbd2cSJim Jagielski {
1408*b1cdbd2cSJim Jagielski String aTagName = aToken.GetTagName();
1409*b1cdbd2cSJim Jagielski return !(aTagName.EqualsIgnoreCaseAscii( "comment" )
1410*b1cdbd2cSJim Jagielski || aTagName.EqualsIgnoreCaseAscii( "bookmark_value" )
1411*b1cdbd2cSJim Jagielski || aTagName.EqualsIgnoreCaseAscii( "emph" )
1412*b1cdbd2cSJim Jagielski || aTagName.EqualsIgnoreCaseAscii( "item" )
1413*b1cdbd2cSJim Jagielski || aTagName.EqualsIgnoreCaseAscii( "br" ) );
1414*b1cdbd2cSJim Jagielski }
1415*b1cdbd2cSJim Jagielski return sal_False;
1416*b1cdbd2cSJim Jagielski }
1417*b1cdbd2cSJim Jagielski
CheckTags(TokenList & aReference,TokenList & aTestee,sal_Bool bFixTags)1418*b1cdbd2cSJim Jagielski void LingTest::CheckTags( TokenList &aReference, TokenList &aTestee, sal_Bool bFixTags )
1419*b1cdbd2cSJim Jagielski {
1420*b1cdbd2cSJim Jagielski sal_uLong i=0,j=0;
1421*b1cdbd2cSJim Jagielski // Clean old Warnings
1422*b1cdbd2cSJim Jagielski while ( aCompareWarningList.Count() )
1423*b1cdbd2cSJim Jagielski {
1424*b1cdbd2cSJim Jagielski delete aCompareWarningList.GetCurObject();
1425*b1cdbd2cSJim Jagielski aCompareWarningList.Remove();
1426*b1cdbd2cSJim Jagielski }
1427*b1cdbd2cSJim Jagielski
1428*b1cdbd2cSJim Jagielski /* in xml tags, do not require the following tags
1429*b1cdbd2cSJim Jagielski comment
1430*b1cdbd2cSJim Jagielski bookmark_value
1431*b1cdbd2cSJim Jagielski emph
1432*b1cdbd2cSJim Jagielski item
1433*b1cdbd2cSJim Jagielski br
1434*b1cdbd2cSJim Jagielski */
1435*b1cdbd2cSJim Jagielski
1436*b1cdbd2cSJim Jagielski // filter uninteresting Tags
1437*b1cdbd2cSJim Jagielski TokenId aMetaTokens = 0;
1438*b1cdbd2cSJim Jagielski for ( i=0 ; i < aReference.Count() ; i++ )
1439*b1cdbd2cSJim Jagielski {
1440*b1cdbd2cSJim Jagielski if ( !IsTagMandatory( aReference.GetObject( i ), aMetaTokens ) )
1441*b1cdbd2cSJim Jagielski aReference.GetObject( i ).SetDone();
1442*b1cdbd2cSJim Jagielski }
1443*b1cdbd2cSJim Jagielski
1444*b1cdbd2cSJim Jagielski aMetaTokens = 0;
1445*b1cdbd2cSJim Jagielski for ( i=0 ; i < aTestee.Count() ; i++ )
1446*b1cdbd2cSJim Jagielski {
1447*b1cdbd2cSJim Jagielski if ( !IsTagMandatory( aTestee.GetObject( i ), aMetaTokens ) )
1448*b1cdbd2cSJim Jagielski aTestee.GetObject( i ).SetDone();
1449*b1cdbd2cSJim Jagielski }
1450*b1cdbd2cSJim Jagielski
1451*b1cdbd2cSJim Jagielski // remove all matching tags
1452*b1cdbd2cSJim Jagielski for ( i=0 ; i < aReference.Count() ; i++ )
1453*b1cdbd2cSJim Jagielski {
1454*b1cdbd2cSJim Jagielski if ( aReference.GetObject( i ).IsDone() )
1455*b1cdbd2cSJim Jagielski continue;
1456*b1cdbd2cSJim Jagielski
1457*b1cdbd2cSJim Jagielski sal_Bool bTagFound = sal_False;
1458*b1cdbd2cSJim Jagielski for ( j=0 ; j < aTestee.Count() && !bTagFound ; j++ )
1459*b1cdbd2cSJim Jagielski {
1460*b1cdbd2cSJim Jagielski if ( aTestee.GetObject( j ).IsDone() )
1461*b1cdbd2cSJim Jagielski continue;
1462*b1cdbd2cSJim Jagielski
1463*b1cdbd2cSJim Jagielski if ( aReference.GetObject( i ).MatchesTranslation( aTestee.GetObject( j ), sal_False, aCompareWarningList ) )
1464*b1cdbd2cSJim Jagielski {
1465*b1cdbd2cSJim Jagielski aReference.GetObject( i ).SetDone();
1466*b1cdbd2cSJim Jagielski aTestee.GetObject( j ).SetDone();
1467*b1cdbd2cSJim Jagielski bTagFound = sal_True;
1468*b1cdbd2cSJim Jagielski }
1469*b1cdbd2cSJim Jagielski }
1470*b1cdbd2cSJim Jagielski }
1471*b1cdbd2cSJim Jagielski
1472*b1cdbd2cSJim Jagielski sal_Bool bCanFix = sal_True;
1473*b1cdbd2cSJim Jagielski
1474*b1cdbd2cSJim Jagielski if ( bFixTags )
1475*b1cdbd2cSJim Jagielski {
1476*b1cdbd2cSJim Jagielski // we fix only if its a really simple case
1477*b1cdbd2cSJim Jagielski sal_uInt16 nTagCount = 0;
1478*b1cdbd2cSJim Jagielski for ( i=0 ; i < aReference.Count() ; i++ )
1479*b1cdbd2cSJim Jagielski if ( !aReference.GetObject( i ).IsDone() )
1480*b1cdbd2cSJim Jagielski nTagCount++;
1481*b1cdbd2cSJim Jagielski if ( nTagCount > 1 )
1482*b1cdbd2cSJim Jagielski bCanFix = sal_False;
1483*b1cdbd2cSJim Jagielski
1484*b1cdbd2cSJim Jagielski nTagCount = 0;
1485*b1cdbd2cSJim Jagielski for ( i=0 ; i < aTestee.Count() ; i++ )
1486*b1cdbd2cSJim Jagielski if ( !aTestee.GetObject( i ).IsDone() )
1487*b1cdbd2cSJim Jagielski nTagCount++;
1488*b1cdbd2cSJim Jagielski if ( nTagCount > 1 )
1489*b1cdbd2cSJim Jagielski bCanFix = sal_False;
1490*b1cdbd2cSJim Jagielski }
1491*b1cdbd2cSJim Jagielski
1492*b1cdbd2cSJim Jagielski // generate errors for tags that have differing attributes
1493*b1cdbd2cSJim Jagielski for ( i=0 ; i < aReference.Count() ; i++ )
1494*b1cdbd2cSJim Jagielski {
1495*b1cdbd2cSJim Jagielski if ( aReference.GetObject( i ).IsDone() )
1496*b1cdbd2cSJim Jagielski continue;
1497*b1cdbd2cSJim Jagielski
1498*b1cdbd2cSJim Jagielski sal_Bool bTagFound = sal_False;
1499*b1cdbd2cSJim Jagielski for ( j=0 ; j < aTestee.Count() && !bTagFound ; j++ )
1500*b1cdbd2cSJim Jagielski {
1501*b1cdbd2cSJim Jagielski if ( aTestee.GetObject( j ).IsDone() )
1502*b1cdbd2cSJim Jagielski continue;
1503*b1cdbd2cSJim Jagielski
1504*b1cdbd2cSJim Jagielski if ( aReference.GetObject( i ).MatchesTranslation( aTestee.GetObject( j ), sal_True, aCompareWarningList, bCanFix && bFixTags ) )
1505*b1cdbd2cSJim Jagielski {
1506*b1cdbd2cSJim Jagielski aReference.GetObject( i ).SetDone();
1507*b1cdbd2cSJim Jagielski aTestee.GetObject( j ).SetDone();
1508*b1cdbd2cSJim Jagielski bTagFound = sal_True;
1509*b1cdbd2cSJim Jagielski }
1510*b1cdbd2cSJim Jagielski }
1511*b1cdbd2cSJim Jagielski }
1512*b1cdbd2cSJim Jagielski
1513*b1cdbd2cSJim Jagielski // list remaining tags as errors
1514*b1cdbd2cSJim Jagielski for ( i=0 ; i < aReference.Count() ; i++ )
1515*b1cdbd2cSJim Jagielski {
1516*b1cdbd2cSJim Jagielski if ( aReference.GetObject( i ).IsDone() )
1517*b1cdbd2cSJim Jagielski continue;
1518*b1cdbd2cSJim Jagielski
1519*b1cdbd2cSJim Jagielski aCompareWarningList.AddError( 20, "Missing Tag in Translation", aReference.GetObject( i ) );
1520*b1cdbd2cSJim Jagielski }
1521*b1cdbd2cSJim Jagielski for ( i=0 ; i < aTestee.Count() ; i++ )
1522*b1cdbd2cSJim Jagielski {
1523*b1cdbd2cSJim Jagielski if ( aTestee.GetObject( i ).IsDone() )
1524*b1cdbd2cSJim Jagielski continue;
1525*b1cdbd2cSJim Jagielski
1526*b1cdbd2cSJim Jagielski aCompareWarningList.AddError( 21, "Extra Tag in Translation", aTestee.GetObject( i ) );
1527*b1cdbd2cSJim Jagielski }
1528*b1cdbd2cSJim Jagielski
1529*b1cdbd2cSJim Jagielski for ( i=0 ; i < aReference.Count() ; i++ )
1530*b1cdbd2cSJim Jagielski aReference.GetObject( i ).SetDone( sal_False );
1531*b1cdbd2cSJim Jagielski
1532*b1cdbd2cSJim Jagielski for ( i=0 ; i < aTestee.Count() ; i++ )
1533*b1cdbd2cSJim Jagielski aTestee.GetObject( i ).SetDone( sal_False );
1534*b1cdbd2cSJim Jagielski }
1535*b1cdbd2cSJim Jagielski
CheckReference(GSILine * aReference)1536*b1cdbd2cSJim Jagielski void LingTest::CheckReference( GSILine *aReference )
1537*b1cdbd2cSJim Jagielski {
1538*b1cdbd2cSJim Jagielski aReferenceParser.Parse( aReference->GetUText(), aReference->GetMessageList() );
1539*b1cdbd2cSJim Jagielski }
1540*b1cdbd2cSJim Jagielski
CheckTestee(GSILine * aTestee,sal_Bool bHasSourceLine,sal_Bool bFixTags)1541*b1cdbd2cSJim Jagielski void LingTest::CheckTestee( GSILine *aTestee, sal_Bool bHasSourceLine, sal_Bool bFixTags )
1542*b1cdbd2cSJim Jagielski {
1543*b1cdbd2cSJim Jagielski aFixedTestee = aTestee->GetUText();
1544*b1cdbd2cSJim Jagielski aTesteeParser.Parse( aFixedTestee, aTestee->GetMessageList() );
1545*b1cdbd2cSJim Jagielski
1546*b1cdbd2cSJim Jagielski if ( bHasSourceLine )
1547*b1cdbd2cSJim Jagielski CheckTags( aReferenceParser.GetTokenList(), aTesteeParser.GetTokenList(), bFixTags );
1548*b1cdbd2cSJim Jagielski
1549*b1cdbd2cSJim Jagielski if ( bFixTags )
1550*b1cdbd2cSJim Jagielski {
1551*b1cdbd2cSJim Jagielski TokenList& aTesteeTokens = aTesteeParser.GetTokenList();
1552*b1cdbd2cSJim Jagielski sal_Bool bFixesDone = sal_False;
1553*b1cdbd2cSJim Jagielski // count backwards to allow replacing from right to left
1554*b1cdbd2cSJim Jagielski int i;
1555*b1cdbd2cSJim Jagielski for ( i=aTesteeTokens.Count()-1 ; i>=0 ; i-- )
1556*b1cdbd2cSJim Jagielski {
1557*b1cdbd2cSJim Jagielski if ( aTesteeTokens.GetObject( i ).HasBeenFixed() )
1558*b1cdbd2cSJim Jagielski {
1559*b1cdbd2cSJim Jagielski bFixesDone = sal_True;
1560*b1cdbd2cSJim Jagielski aFixedTestee.Replace( aTesteeTokens.GetObject( i ).nPos, aTesteeTokens.GetObject( i ).aTokenString.Len(), aTesteeTokens.GetObject( i ).MakeTag() );
1561*b1cdbd2cSJim Jagielski }
1562*b1cdbd2cSJim Jagielski }
1563*b1cdbd2cSJim Jagielski if ( bFixesDone )
1564*b1cdbd2cSJim Jagielski {
1565*b1cdbd2cSJim Jagielski aTestee->SetUText( aFixedTestee );
1566*b1cdbd2cSJim Jagielski aTestee->SetFixed();
1567*b1cdbd2cSJim Jagielski }
1568*b1cdbd2cSJim Jagielski }
1569*b1cdbd2cSJim Jagielski }
1570*b1cdbd2cSJim Jagielski
1571