diff options
Diffstat (limited to 'xml2cmp/source/xcd/parse.cxx')
-rw-r--r-- | xml2cmp/source/xcd/parse.cxx | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/xml2cmp/source/xcd/parse.cxx b/xml2cmp/source/xcd/parse.cxx new file mode 100644 index 000000000000..c17d74b5a948 --- /dev/null +++ b/xml2cmp/source/xcd/parse.cxx @@ -0,0 +1,452 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#include <parse.hxx> + +#include <string.h> +#include <iostream> +#include <xmlelem.hxx> + +#if (_MSC_VER >=1400) +#pragma warning(disable:4365) +#endif + +#ifdef UNX +#define strnicmp strncasecmp +#endif + + + +// NOT FULLY DEFINED SERVICES + + + +#define AssertionOf(x) \ + {if (!(x)) {std::cerr << "Assertion failed: " << #x << __FILE__ << __LINE__ << std::endl; exit(3); }} + + + +X2CParser::X2CParser( XmlElement & o_rDocumentData ) + : // sFileName, + nFileLine(0), + pDocumentData(&o_rDocumentData), + // sWord, + text(0) +{ +} + +X2CParser::~X2CParser() +{ +} + + +bool +X2CParser::LoadFile( const char * i_sFilename ) +{ + sFileName = i_sFilename; + nFileLine = 1; + + // Load file: + if ( ! LoadXmlFile( aFile, i_sFilename ) ) + return false; + + // Test correct end: + const char * pLastTag = strrchr(aFile.operator const char *(),'<'); + if (pLastTag == 0) + return false; + if ( strnicmp(pLastTag+2, pDocumentData->Name().str(), pDocumentData->Name().l()) != 0 + || strnicmp(pLastTag, "</", 2) != 0 ) + return false; + if (strchr(pLastTag,'>') == 0) + return false; + return true; +} + +void +X2CParser::Parse() +{ + // Parse: + text = aFile.operator const char *(); + + Parse_XmlDeclaration(); + Parse_Doctype(); + + pDocumentData->Parse(*this); +} + +bool +X2CParser::Parse( const char * i_sFilename ) +{ + bool ret = LoadFile(i_sFilename); + if (ret) + Parse(); + return ret; +} + +void +X2CParser::Parse_XmlDeclaration() +{ + Goto('<'); + if ( IsText("<?xml") ) + { + Goto_And_Pass('>'); + } +} + +void +X2CParser::Parse_Doctype() +{ + Goto('<'); + if ( IsText("<!DOCTYPE") ) + Goto_And_Pass('>'); +} + +void +X2CParser::Parse_Sequence( DynamicList<XmlElement> & o_rElements, + const Simstr & i_sElementName ) +{ + CheckAndPassBeginTag(i_sElementName.str()); + + unsigned int i_max = o_rElements.size(); + for (unsigned i = 0; i < i_max; ++i) + { + o_rElements[i]->Parse(*this); + } // end for + + CheckAndPassEndTag(i_sElementName.str()); +} + +void +X2CParser::Parse_FreeChoice( DynamicList<XmlElement> & o_rElements ) +{ + unsigned nSize = o_rElements.size(); + + for ( bool bBreak = false; !bBreak; ) + { + bBreak = true; + for ( unsigned i = 0; i < nSize; ++i ) + { + Goto('<'); + if ( IsBeginTag(o_rElements[i]->Name().str()) ) + { + o_rElements[i]->Parse(*this); + bBreak = false; + break; + } + } // end for i + } // end for !bBreak +} + +void +X2CParser::Parse_List( ListElement & o_rListElem ) +{ + + for ( Goto('<'); IsBeginTag(o_rListElem.Name().str()); Goto('<') ) + { + XmlElement * pNew = o_rListElem.Create_and_Add_NewElement(); + pNew->Parse(*this); + } +} + +void +X2CParser::Parse_Text( Simstr & o_sText, + const Simstr & i_sElementName, + bool i_bReverseName ) +{ + + if ( ! CheckAndPassBeginTag(i_sElementName.str()) ) + return; + + // Add new Element + GetTextTill( o_sText, '<', i_bReverseName ); + o_sText.remove_trailing_blanks(); + + CheckAndPassEndTag(i_sElementName.str()); +} + +void +X2CParser::Parse_MultipleText( List<Simstr> & o_rTexts, + const Simstr & i_sElementName, + bool i_bReverseName ) +{ + for ( Goto('<'); IsBeginTag(i_sElementName.str()); Goto('<') ) + { + Simstr sNew; + Parse_Text(sNew, i_sElementName, i_bReverseName); + if (sNew.l() > 0) + o_rTexts.push_back(sNew); + } +} + +void +X2CParser::Parse_SglAttr( Simstr & o_sAttrValue, + const Simstr & i_sElementName, + const Simstr & i_sAttrName ) +{ + Goto('<'); + if ( !IsBeginTag(i_sElementName.str()) ) + SyntaxError("unexpected element"); + Move( i_sElementName.l() + 1 ); + + Pass_White(); + if (*text == '>') + SyntaxError("no attribute found, where one was expected"); + Simstr sAttrName; + Get_Attribute(o_sAttrValue, sAttrName); + if (sAttrName != i_sAttrName) + SyntaxError("unknown attribute found"); + Pass_White(); + if (strncmp(text,"/>",2) != 0) + SyntaxError("missing \"/>\" at end of empty element"); + Move(2); +} + +void +X2CParser::Parse_MultipleAttr( List<Simstr> & o_rAttrValues, + const Simstr & i_sElementName, + const List<Simstr> & i_rAttrNames ) +{ + Goto('<'); + if ( !IsBeginTag(i_sElementName.str()) ) + SyntaxError("unexpected element"); + Move( i_sElementName.l() + 1 ); + Simstr sAttrName; + Simstr sAttrValue; + unsigned nSize = i_rAttrNames.size(); + unsigned i; + + for ( Pass_White(); *text != '/'; Pass_White() ) + { + + Get_Attribute(sAttrValue, sAttrName); + + for ( i = 0; i < nSize; ++i ) + { + if ( i_rAttrNames[i] == sAttrName ) + { + o_rAttrValues[i] = sAttrValue; + break; + } + } + if (i == nSize) + SyntaxError("unknown attribute found"); + } + Move(2); +} + + +void +X2CParser::Get_Attribute( Simstr & o_rAttrValue, + Simstr & o_rAttrName ) +{ + GetTextTill( o_rAttrName, '='); + + while (*(++text) != '"') + { + if (*text == '\0') + SyntaxError("unexpected end of file"); + } + + ++text; + GetTextTill( o_rAttrValue, '"'); + ++text; +} + +bool +X2CParser::IsText( const char * i_sComparedText ) +{ + return strnicmp( text, i_sComparedText, strlen(i_sComparedText) ) == 0; +} + +bool +X2CParser::IsBeginTag( const char * i_sTagName ) +{ + return strnicmp( text+1, i_sTagName, strlen(i_sTagName) ) == 0 + && *text == '<'; +} + +bool +X2CParser::IsEndTag( const char * i_sTagName ) +{ + return strnicmp( text+2, i_sTagName, strlen(i_sTagName) ) == 0 + && strnicmp( text, "</", 2 ) == 0; +} + +void +X2CParser::Goto( char i_cNext ) +{ + while (*text != i_cNext) + { + TestCurChar(); + ++text; + } +} + +void +X2CParser::Goto_And_Pass( char i_cNext ) +{ + Goto(i_cNext); + ++text; +} + +void +X2CParser::Move( int i_nForward ) +{ + text += i_nForward; +} + +void +X2CParser::Pass_White() +{ + while (*text <= 32) + { + TestCurChar(); + ++text; + } +} + +void +X2CParser::GetTextTill( Simstr & o_rText, + char i_cEnd, + bool i_bReverseName ) +{ + char * pResult = &sWord[0]; + char * pSet; + + for ( pSet = pResult; + *text != i_cEnd; + ++text ) + { + TestCurChar(); + *pSet++ = *text; + } + + while ( *pResult < 33 && *pResult > 0 ) + ++pResult; + while ( pSet > pResult ? *(pSet-1) < 33 : false ) + pSet--; + *pSet = '\0'; + + + if (i_bReverseName) + { + const unsigned int nMaxLen = 1000; + if (strlen(pResult) < nMaxLen) + { + char * sBreak = strrchr(pResult,'.'); + if (sBreak != 0) + { + static char sScope[nMaxLen+10]; + static char sName[nMaxLen+10]; + + unsigned nScopeLen = sBreak - pResult; + strncpy ( sScope, pResult, nScopeLen ); // STRNCPY SAFE HERE + sScope[nScopeLen] = '\0'; + strcpy( sName, sBreak + 1 ); // STRCPY SAFE HERE + strcat( sName, " in " ); // STRCAT SAFE HERE + strcat( sName, sScope ); // STRCAT SAFE HERE + + o_rText = sName; + return; + } + } + } // endif (i_bReverseName) + + o_rText = &sWord[0]; +} + +bool +X2CParser::CheckAndPassBeginTag( const char * i_sElementName ) +{ + bool ret = true; + Goto('<'); + if ( ! IsBeginTag(i_sElementName) ) + SyntaxError( "unexpected element"); + if (IsAbsoluteEmpty()) + ret = false; + Goto_And_Pass('>'); + if (ret) + Pass_White(); + return ret; +} + +void +X2CParser::CheckAndPassEndTag( const char * i_sElementName ) +{ + Pass_White(); + if ( !IsEndTag(i_sElementName) ) + SyntaxError("missing or not matching end tag"); + Goto_And_Pass('>'); +} + +bool +X2CParser::IsAbsoluteEmpty() const +{ + const char * pEnd = strchr(text+1, '>'); + if (pEnd != 0) + { + if ( *(pEnd-1) == '/' ) + { + const char * pAttr = strchr(text+1, '"'); + if (pAttr == 0) + return true; + else if ( (pAttr-text) > (pEnd-text) ) + return true; + } + } + return false; +} + +void +X2CParser::SyntaxError( const char * i_sText ) +{ + std::cerr + << "Syntax error " + << i_sText + << " in file: " + << sFileName.str() + << " in line " + << nFileLine + << "." + << std::endl; + + exit(3); +} + +void +X2CParser::TestCurChar() +{ +// if (*text == '\0') +// SyntaxError("unexpected end of file"); +// else + + if (*text == '\n') + nFileLine++; +} + + |