/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmXMLParser.h"

#include <cm_expat.h>
#include <ctype.h>

//----------------------------------------------------------------------------
cmXMLParser::cmXMLParser()
{
  this->Parser = 0;
  this->ParseError = 0;
}

//----------------------------------------------------------------------------
cmXMLParser::~cmXMLParser()
{
  if ( this->Parser )
    {
    this->CleanupParser();
    }
}

//----------------------------------------------------------------------------
int cmXMLParser::Parse(const char* string)
{
  return (int)this->InitializeParser() &&
    this->ParseChunk(string, strlen(string)) &&
    this->CleanupParser();
}

int cmXMLParser::ParseFile(const char* file)
{
  if ( !file )
    {
    return 0;
    }

  std::ifstream ifs(file);
  if ( !ifs )
    {
    return 0;
    }

  cmOStringStream str;
  str << ifs.rdbuf();
  return this->Parse(str.str().c_str());
}

//----------------------------------------------------------------------------
int cmXMLParser::InitializeParser()
{
  if ( this->Parser )
    {
    std::cerr << "Parser already initialized" << std::endl;
    this->ParseError = 1;
    return 0;
    }

  // Create the expat XML parser.
  this->Parser = XML_ParserCreate(0);
  XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
                        &cmXMLParserStartElement,
                        &cmXMLParserEndElement);
  XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
                              &cmXMLParserCharacterDataHandler);
  XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
  this->ParseError = 0;
  return 1;
}

//----------------------------------------------------------------------------
int cmXMLParser::ParseChunk(const char* inputString,
                            std::string::size_type length)
{
  if ( !this->Parser )
    {
    std::cerr << "Parser not initialized" << std::endl;
    this->ParseError = 1;
    return 0;
    }
  int res;
  res = this->ParseBuffer(inputString, length);
  if ( res == 0 )
    {
    this->ParseError = 1;
    }
  return res;
}

//----------------------------------------------------------------------------
int cmXMLParser::CleanupParser()
{
  if ( !this->Parser )
    {
    std::cerr << "Parser not initialized" << std::endl;
    this->ParseError = 1;
    return 0;
    }
  int result = !this->ParseError;
  if(result)
    {
    // Tell the expat XML parser about the end-of-input.
    if(!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1))
      {
      this->ReportXmlParseError();
      result = 0;
      }
    }

  // Clean up the parser.
  XML_ParserFree(static_cast<XML_Parser>(this->Parser));
  this->Parser = 0;

  return result;
}

//----------------------------------------------------------------------------
int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count)
{
  // Pass the buffer to the expat XML parser.
  if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
                static_cast<int>(count), 0))
    {
    this->ReportXmlParseError();
    return 0;
    }
  return 1;
}

//----------------------------------------------------------------------------
int cmXMLParser::ParseBuffer(const char* buffer)
{
  return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
}

//----------------------------------------------------------------------------
int cmXMLParser::ParsingComplete()
{
  // Default behavior is to parse to end of stream.
  return 0;
}

//----------------------------------------------------------------------------
void cmXMLParser::StartElement(const char * name,
  const char ** /*atts*/)
{
  std::cout << "Start element: " << name << std::endl;
}

//----------------------------------------------------------------------------
void cmXMLParser::EndElement(const char * name)
{
  std::cout << "End element: " << name << std::endl;
}

//----------------------------------------------------------------------------
void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
  int /*inLength*/)
{
}

//----------------------------------------------------------------------------
int cmXMLParser::IsSpace(char c)
{
  return isspace(c);
}

//----------------------------------------------------------------------------
const char* cmXMLParser::FindAttribute(const char** atts,
                                       const char* attribute)
{
  if(atts && attribute)
    {
    for(const char** a = atts; *a && *(a+1); a += 2)
      {
      if(strcmp(*a, attribute) == 0)
        {
        return *(a+1);
        }
      }
    }
  return 0;
}

//----------------------------------------------------------------------------
void cmXMLParserStartElement(void* parser, const char *name,
                              const char **atts)
{
  // Begin element handler that is registered with the XML_Parser.
  // This just casts the user data to a cmXMLParser and calls
  // StartElement.
  static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
}

//----------------------------------------------------------------------------
void cmXMLParserEndElement(void* parser, const char *name)
{
  // End element handler that is registered with the XML_Parser.  This
  // just casts the user data to a cmXMLParser and calls EndElement.
  static_cast<cmXMLParser*>(parser)->EndElement(name);
}

//----------------------------------------------------------------------------
void cmXMLParserCharacterDataHandler(void* parser, const char* data,
                                      int length)
{
  // Character data handler that is registered with the XML_Parser.
  // This just casts the user data to a cmXMLParser and calls
  // CharacterDataHandler.
  static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
}

//----------------------------------------------------------------------------
void cmXMLParser::ReportXmlParseError()
{
  XML_Parser parser = static_cast<XML_Parser>(this->Parser);
  this->ReportError(XML_GetCurrentLineNumber(parser),
                    XML_GetCurrentColumnNumber(parser),
                    XML_ErrorString(XML_GetErrorCode(parser)));
}

//----------------------------------------------------------------------------
void cmXMLParser::ReportError(int line, int, const char* msg)
{
  std::cerr << "Error parsing XML in stream at line "
            << line << ": " << msg << std::endl;
}
