1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: parse.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
36 #include <xmlelem.hxx>
39 #pragma warning(disable:4365)
43 #define strnicmp strncasecmp
48 // NOT FULLY DEFINED SERVICES
52 #define AssertionOf(x) \
53 {if (!(x)) {std::cerr << "Assertion failed: " << #x << __FILE__ << __LINE__ << std::endl; exit(3); }}
57 X2CParser::X2CParser( XmlElement
& o_rDocumentData
)
60 pDocumentData(&o_rDocumentData
),
66 X2CParser::~X2CParser()
72 X2CParser::LoadFile( const char * i_sFilename
)
74 sFileName
= i_sFilename
;
78 if ( ! LoadXmlFile( aFile
, i_sFilename
) )
82 const char * pLastTag
= strrchr(aFile
.operator const char *(),'<');
85 if ( strnicmp(pLastTag
+2, pDocumentData
->Name().str(), pDocumentData
->Name().l()) != 0
86 || strnicmp(pLastTag
, "</", 2) != 0 )
88 if (strchr(pLastTag
,'>') == 0)
97 text
= aFile
.operator const char *();
99 Parse_XmlDeclaration();
102 pDocumentData
->Parse(*this);
106 X2CParser::Parse( const char * i_sFilename
)
108 bool ret
= LoadFile(i_sFilename
);
115 X2CParser::Parse_XmlDeclaration()
118 if ( IsText("<?xml") )
125 X2CParser::Parse_Doctype()
128 if ( IsText("<!DOCTYPE") )
133 X2CParser::Parse_Sequence( DynamicList
<XmlElement
> & o_rElements
,
134 const Simstr
& i_sElementName
)
136 CheckAndPassBeginTag(i_sElementName
.str());
138 unsigned int i_max
= o_rElements
.size();
139 for (unsigned i
= 0; i
< i_max
; ++i
)
141 o_rElements
[i
]->Parse(*this);
144 CheckAndPassEndTag(i_sElementName
.str());
148 X2CParser::Parse_FreeChoice( DynamicList
<XmlElement
> & o_rElements
)
150 unsigned nSize
= o_rElements
.size();
152 for ( bool bBreak
= false; !bBreak
; )
155 for ( unsigned i
= 0; i
< nSize
; ++i
)
158 if ( IsBeginTag(o_rElements
[i
]->Name().str()) )
160 o_rElements
[i
]->Parse(*this);
169 X2CParser::Parse_List( ListElement
& o_rListElem
)
172 for ( Goto('<'); IsBeginTag(o_rListElem
.Name().str()); Goto('<') )
174 XmlElement
* pNew
= o_rListElem
.Create_and_Add_NewElement();
180 X2CParser::Parse_Text( Simstr
& o_sText
,
181 const Simstr
& i_sElementName
,
182 bool i_bReverseName
)
185 if ( ! CheckAndPassBeginTag(i_sElementName
.str()) )
189 GetTextTill( o_sText
, '<', i_bReverseName
);
190 o_sText
.remove_trailing_blanks();
192 CheckAndPassEndTag(i_sElementName
.str());
196 X2CParser::Parse_MultipleText( List
<Simstr
> & o_rTexts
,
197 const Simstr
& i_sElementName
,
198 bool i_bReverseName
)
200 for ( Goto('<'); IsBeginTag(i_sElementName
.str()); Goto('<') )
203 Parse_Text(sNew
, i_sElementName
, i_bReverseName
);
205 o_rTexts
.push_back(sNew
);
210 X2CParser::Parse_SglAttr( Simstr
& o_sAttrValue
,
211 const Simstr
& i_sElementName
,
212 const Simstr
& i_sAttrName
)
215 if ( !IsBeginTag(i_sElementName
.str()) )
216 SyntaxError("unexpected element");
217 Move( i_sElementName
.l() + 1 );
221 SyntaxError("no attribute found, where one was expected");
223 Get_Attribute(o_sAttrValue
, sAttrName
);
224 if (sAttrName
!= i_sAttrName
)
225 SyntaxError("unknown attribute found");
227 if (strncmp(text
,"/>",2) != 0)
228 SyntaxError("missing \"/>\" at end of empty element");
233 X2CParser::Parse_MultipleAttr( List
<Simstr
> & o_rAttrValues
,
234 const Simstr
& i_sElementName
,
235 const List
<Simstr
> & i_rAttrNames
)
238 if ( !IsBeginTag(i_sElementName
.str()) )
239 SyntaxError("unexpected element");
240 Move( i_sElementName
.l() + 1 );
243 unsigned nSize
= i_rAttrNames
.size();
246 for ( Pass_White(); *text
!= '/'; Pass_White() )
249 Get_Attribute(sAttrValue
, sAttrName
);
251 for ( i
= 0; i
< nSize
; ++i
)
253 if ( i_rAttrNames
[i
] == sAttrName
)
255 o_rAttrValues
[i
] = sAttrValue
;
260 SyntaxError("unknown attribute found");
267 X2CParser::Get_Attribute( Simstr
& o_rAttrValue
,
268 Simstr
& o_rAttrName
)
270 GetTextTill( o_rAttrName
, '=');
272 while (*(++text
) != '"')
275 SyntaxError("unexpected end of file");
279 GetTextTill( o_rAttrValue
, '"');
284 X2CParser::IsText( const char * i_sComparedText
)
286 return strnicmp( text
, i_sComparedText
, strlen(i_sComparedText
) ) == 0;
290 X2CParser::IsBeginTag( const char * i_sTagName
)
292 return strnicmp( text
+1, i_sTagName
, strlen(i_sTagName
) ) == 0
297 X2CParser::IsEndTag( const char * i_sTagName
)
299 return strnicmp( text
+2, i_sTagName
, strlen(i_sTagName
) ) == 0
300 && strnicmp( text
, "</", 2 ) == 0;
304 X2CParser::Goto( char i_cNext
)
306 while (*text
!= i_cNext
)
314 X2CParser::Goto_And_Pass( char i_cNext
)
321 X2CParser::Move( int i_nForward
)
327 X2CParser::Pass_White()
337 X2CParser::GetTextTill( Simstr
& o_rText
,
339 bool i_bReverseName
)
341 char * pResult
= &sWord
[0];
344 for ( pSet
= pResult
;
352 while ( *pResult
< 33 && *pResult
> 0 )
354 while ( pSet
> pResult
? *(pSet
-1) < 33 : false )
361 const unsigned int nMaxLen
= 1000;
362 if (strlen(pResult
) < nMaxLen
)
364 char * sBreak
= strrchr(pResult
,'.');
367 static char sScope
[nMaxLen
+10];
368 static char sName
[nMaxLen
+10];
370 unsigned nScopeLen
= sBreak
- pResult
;
371 strncpy ( sScope
, pResult
, nScopeLen
); // STRNCPY SAFE HERE
372 sScope
[nScopeLen
] = '\0';
373 strcpy( sName
, sBreak
+ 1 ); // STRCPY SAFE HERE
374 strcat( sName
, " in " ); // STRCAT SAFE HERE
375 strcat( sName
, sScope
); // STRCAT SAFE HERE
381 } // endif (i_bReverseName)
387 X2CParser::CheckAndPassBeginTag( const char * i_sElementName
)
391 if ( ! IsBeginTag(i_sElementName
) )
392 SyntaxError( "unexpected element");
393 if (IsAbsoluteEmpty())
402 X2CParser::CheckAndPassEndTag( const char * i_sElementName
)
405 if ( !IsEndTag(i_sElementName
) )
406 SyntaxError("missing or not matching end tag");
411 X2CParser::IsAbsoluteEmpty() const
413 const char * pEnd
= strchr(text
+1, '>');
416 if ( *(pEnd
-1) == '/' )
418 const char * pAttr
= strchr(text
+1, '"');
421 else if ( (pAttr
-text
) > (pEnd
-text
) )
429 X2CParser::SyntaxError( const char * i_sText
)
445 X2CParser::TestCurChar()
447 // if (*text == '\0')
448 // SyntaxError("unexpected end of file");