cmWIXPatchParser.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2013 Kitware, Inc.
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmWIXPatchParser.h"
  11. #include <CPack/cmCPackGenerator.h>
  12. #include <cm_expat.h>
  13. cmWIXPatchElement::~cmWIXPatchElement()
  14. {
  15. for(child_list_t::iterator i = children.begin(); i != children.end(); ++i)
  16. {
  17. delete *i;
  18. }
  19. }
  20. cmWIXPatchParser::cmWIXPatchParser(
  21. fragment_map_t& fragments, cmCPackLog* logger):
  22. Logger(logger),
  23. State(BEGIN_DOCUMENT),
  24. Valid(true),
  25. Fragments(fragments)
  26. {
  27. }
  28. void cmWIXPatchParser::StartElement(const std::string& name, const char **atts)
  29. {
  30. if(State == BEGIN_DOCUMENT)
  31. {
  32. if(name == "CPackWiXPatch")
  33. {
  34. State = BEGIN_FRAGMENTS;
  35. }
  36. else
  37. {
  38. ReportValidationError("Expected root element 'CPackWiXPatch'");
  39. }
  40. }
  41. else if(State == BEGIN_FRAGMENTS)
  42. {
  43. if(name == "CPackWiXFragment")
  44. {
  45. State = INSIDE_FRAGMENT;
  46. StartFragment(atts);
  47. }
  48. else
  49. {
  50. ReportValidationError("Expected 'CPackWixFragment' element");
  51. }
  52. }
  53. else if(State == INSIDE_FRAGMENT)
  54. {
  55. cmWIXPatchElement &parent = *ElementStack.back();
  56. parent.children.resize(parent.children.size() + 1);
  57. cmWIXPatchElement*& currentElement = parent.children.back();
  58. currentElement = new cmWIXPatchElement;
  59. currentElement->name = name;
  60. for(size_t i = 0; atts[i]; i += 2)
  61. {
  62. std::string key = atts[i];
  63. std::string value = atts[i+1];
  64. currentElement->attributes[key] = value;
  65. }
  66. ElementStack.push_back(currentElement);
  67. }
  68. }
  69. void cmWIXPatchParser::StartFragment(const char **attributes)
  70. {
  71. for(size_t i = 0; attributes[i]; i += 2)
  72. {
  73. std::string key = attributes[i];
  74. std::string value = attributes[i+1];
  75. if(key == "Id")
  76. {
  77. if(Fragments.find(value) != Fragments.end())
  78. {
  79. std::stringstream tmp;
  80. tmp << "Invalid reuse of 'CPackWixFragment' 'Id': " << value;
  81. ReportValidationError(tmp.str());
  82. }
  83. ElementStack.push_back(&Fragments[value]);
  84. }
  85. else
  86. {
  87. ReportValidationError(
  88. "The only allowed 'CPackWixFragment' attribute is 'Id'");
  89. }
  90. }
  91. }
  92. void cmWIXPatchParser::EndElement(const std::string& name)
  93. {
  94. if(State == INSIDE_FRAGMENT)
  95. {
  96. if(name == "CPackWiXFragment")
  97. {
  98. State = BEGIN_FRAGMENTS;
  99. ElementStack.clear();
  100. }
  101. else
  102. {
  103. ElementStack.pop_back();
  104. }
  105. }
  106. }
  107. void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
  108. {
  109. cmCPackLogger(cmCPackLog::LOG_ERROR,
  110. "Error while processing XML patch file at " << line << ":" << column <<
  111. ": "<< msg << std::endl);
  112. Valid = false;
  113. }
  114. void cmWIXPatchParser::ReportValidationError(std::string const& message)
  115. {
  116. ReportError(XML_GetCurrentLineNumber(Parser),
  117. XML_GetCurrentColumnNumber(Parser),
  118. message.c_str());
  119. }
  120. bool cmWIXPatchParser::IsValid() const
  121. {
  122. return Valid;
  123. }