[Cmake-commits] CMake branch, next, updated. v3.2.2-3171-gb9a2166

Brad King brad.king at kitware.com
Tue May 26 11:36:19 EDT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  b9a2166437958b8f46814c6c50892850fff3ba59 (commit)
       via  de2ef3053c37d0a958a92f8d763168d5b4e5dc17 (commit)
       via  b04500a7259437dca9a2d8c8f0ce500b3bd2b057 (commit)
       via  8fbc509a48e53f7462143dded5a01c77ab5ba6bd (commit)
       via  82455a9d3af88296741a6b087fceed1bb6a28b1e (commit)
       via  1dbd86fd6dee7fc330f613558d44f37937fd454b (commit)
       via  a53bd63e0cb84fafeadb801437c5acde9298c3e7 (commit)
       via  9c0bb7d8070039cfa3f5b944f90308e0283c4ce3 (commit)
       via  6cf5cc717f522bcd9e8286a864068d09012dad41 (commit)
       via  ed42c203ed4b258091bd6eeaa1fe567c6f9b120a (commit)
       via  18825bafd99c6a9c8ec1fb4e7b22a8059c680572 (commit)
       via  f6413400a00362cf307d0fbb85daf96265091686 (commit)
      from  c7b4f59b1917ff01ee43ea651068d5e681d103d7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b9a2166437958b8f46814c6c50892850fff3ba59
commit b9a2166437958b8f46814c6c50892850fff3ba59
Merge: c7b4f59 de2ef30
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue May 26 11:36:17 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue May 26 11:36:17 2015 -0400

    Merge topic 'ctest-xml-refactor' into next
    
    de2ef305 cmCTest: Drop unused method overloads
    b04500a7 cmCTest{Test,MemCheck}Handler: Port to cmXMLWriter
    8fbc509a cmCTestCoverageHandler: Port to cmXMLWriter
    82455a9d cmCTestBuildHandler: Port to cmXMLWriter
    1dbd86fd cmCTestLaunch: Port to cmXMLWriter
    a53bd63e cmCTest: Port GenerateNotesFile to cmXMLWriter
    9c0bb7d8 cmCTestConfigureHandler: Port to cmXMLWriter
    6cf5cc71 cmCTestUploadHandler: Port to cmXMLWriter
    ed42c203 cmCTestUpdateHandler: Port to cmXMLWriter
    18825baf cmCTest: Port to cmXMLWriter
    f6413400 Add cmXMLWriter class to consolidate XML generation


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=de2ef3053c37d0a958a92f8d763168d5b4e5dc17
commit de2ef3053c37d0a958a92f8d763168d5b4e5dc17
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 00:13:15 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:22 2015 -0400

    cmCTest: Drop unused method overloads
    
    The StartXML, EndXML, and AddSiteProperties overloads that take a stream
    directly are no longer called anywhere.  All clients hvae been ported to
    cmXMLWriter.  Drop the old overloads.

diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 16edd1f..cc42f47 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -1491,64 +1491,6 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
 }
 
 //----------------------------------------------------------------------
-void cmCTest::StartXML(std::ostream& ostr, bool append)
-{
-  if(this->CurrentTag.empty())
-    {
-    cmCTestLog(this, ERROR_MESSAGE,
-               "Current Tag empty, this may mean"
-               " NightlStartTime was not set correctly." << std::endl);
-    cmSystemTools::SetFatalErrorOccured();
-    }
-
-  // find out about the system
-  cmsys::SystemInformation info;
-  info.RunCPUCheck();
-  info.RunOSCheck();
-  info.RunMemoryCheck();
-
-  std::string buildname = cmCTest::SafeBuildIdField(
-    this->GetCTestConfiguration("BuildName"));
-  std::string stamp = cmCTest::SafeBuildIdField(
-    this->CurrentTag + "-" + this->GetTestModelString());
-  std::string site = cmCTest::SafeBuildIdField(
-    this->GetCTestConfiguration("Site"));
-
-  ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-       << "<Site BuildName=\"" << buildname << "\"\n"
-       << "\tBuildStamp=\"" << stamp << "\"\n"
-       << "\tName=\"" << site << "\"\n"
-       << "\tGenerator=\"ctest-" << cmVersion::GetCMakeVersion() << "\"\n"
-       << (append? "\tAppend=\"true\"\n":"")
-       << "\tCompilerName=\"" << this->GetCTestConfiguration("Compiler")
-       << "\"\n"
-#ifdef _COMPILER_VERSION
-       << "\tCompilerVersion=\"_COMPILER_VERSION\"\n"
-#endif
-       << "\tOSName=\"" << info.GetOSName() << "\"\n"
-       << "\tHostname=\"" << info.GetHostname() << "\"\n"
-       << "\tOSRelease=\"" << info.GetOSRelease() << "\"\n"
-       << "\tOSVersion=\"" << info.GetOSVersion() << "\"\n"
-       << "\tOSPlatform=\"" << info.GetOSPlatform() << "\"\n"
-       << "\tIs64Bits=\"" << info.Is64Bits() << "\"\n"
-       << "\tVendorString=\"" << info.GetVendorString() << "\"\n"
-       << "\tVendorID=\"" << info.GetVendorID() << "\"\n"
-       << "\tFamilyID=\"" << info.GetFamilyID() << "\"\n"
-       << "\tModelID=\"" << info.GetModelID() << "\"\n"
-       << "\tProcessorCacheSize=\"" << info.GetProcessorCacheSize() << "\"\n"
-       << "\tNumberOfLogicalCPU=\"" << info.GetNumberOfLogicalCPU() << "\"\n"
-       << "\tNumberOfPhysicalCPU=\""<< info.GetNumberOfPhysicalCPU() << "\"\n"
-       << "\tTotalVirtualMemory=\"" << info.GetTotalVirtualMemory() << "\"\n"
-       << "\tTotalPhysicalMemory=\""<< info.GetTotalPhysicalMemory() << "\"\n"
-       << "\tLogicalProcessorsPerPhysical=\""
-       << info.GetLogicalProcessorsPerPhysical() << "\"\n"
-       << "\tProcessorClockFrequency=\""
-       << info.GetProcessorClockFrequency() << "\"\n"
-       << ">" << std::endl;
-  this->AddSiteProperties(ostr);
-}
-
-//----------------------------------------------------------------------
 void cmCTest::StartXML(cmXMLWriter& xml, bool append)
 {
   if(this->CurrentTag.empty())
@@ -1610,53 +1552,6 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
 }
 
 //----------------------------------------------------------------------
-void cmCTest::AddSiteProperties(std::ostream& ostr)
-{
-  cmCTestScriptHandler* ch =
-    static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
-  cmake* cm =  ch->GetCMake();
-  // if no CMake then this is the old style script and props like
-  // this will not work anyway.
-  if(!cm)
-    {
-    return;
-    }
-  // This code should go when cdash is changed to use labels only
-  const char* subproject = cm->GetState()
-                             ->GetGlobalProperty("SubProject");
-  if(subproject)
-    {
-    ostr << "<Subproject name=\"" << subproject << "\">\n";
-    const char* labels =
-      ch->GetCMake()->GetState()
-                    ->GetGlobalProperty("SubProjectLabels");
-    if(labels)
-      {
-      ostr << "  <Labels>\n";
-      std::string l = labels;
-      std::vector<std::string> args;
-      cmSystemTools::ExpandListArgument(l, args);
-      for(std::vector<std::string>::iterator i = args.begin();
-          i != args.end(); ++i)
-        {
-        ostr << "    <Label>" << *i << "</Label>\n";
-        }
-      ostr << "  </Labels>\n";
-      }
-    ostr << "</Subproject>\n";
-    }
-
-  // This code should stay when cdash only does label based sub-projects
-  const char* label = cm->GetState()->GetGlobalProperty("Label");
-  if(label)
-    {
-    ostr << "<Labels>\n";
-    ostr << "  <Label>" << label << "</Label>\n";
-    ostr << "</Labels>\n";
-    }
-}
-
-//----------------------------------------------------------------------
 void cmCTest::AddSiteProperties(cmXMLWriter& xml)
 {
   cmCTestScriptHandler* ch =
@@ -1704,13 +1599,6 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
     }
 }
 
-
-//----------------------------------------------------------------------
-void cmCTest::EndXML(std::ostream& ostr)
-{
-  ostr << "</Site>" << std::endl;
-}
-
 //----------------------------------------------------------------------
 void cmCTest::EndXML(cmXMLWriter& xml)
 {
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 7153e8f..db3ea10 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -274,11 +274,9 @@ public:
   static std::string SafeBuildIdField(const std::string& value);
 
   //! Start CTest XML output file
-  void StartXML(std::ostream& ostr, bool append);
   void StartXML(cmXMLWriter& xml, bool append);
 
   //! End CTest XML output file
-  void EndXML(std::ostream& ostr);
   void EndXML(cmXMLWriter& xml);
 
   //! Run command specialized for make and configure. Returns process status
@@ -423,7 +421,6 @@ public:
   /** Direct process output to given streams.  */
   void SetStreams(std::ostream* out, std::ostream* err)
     { this->StreamOut = out; this->StreamErr = err; }
-  void AddSiteProperties(std::ostream& );
   void AddSiteProperties(cmXMLWriter& xml);
   bool GetLabelSummary() { return this->LabelSummary;}
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b04500a7259437dca9a2d8c8f0ce500b3bd2b057
commit b04500a7259437dca9a2d8c8f0ce500b3bd2b057
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 20:40:47 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:22 2015 -0400

    cmCTest{Test,MemCheck}Handler: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 061f3fd..8f26716 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -21,7 +21,7 @@
 #include <cmsys/Glob.hxx>
 #include <cmsys/FStream.hxx>
 #include "cmMakefile.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 #include <stdlib.h>
 #include <math.h>
@@ -352,55 +352,52 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf)
 }
 
 //----------------------------------------------------------------------
-void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
+void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
 {
   if ( !this->CTest->GetProduceXML() )
     {
     return;
     }
-  this->CTest->StartXML(os, this->AppendXML);
-  os << "<DynamicAnalysis Checker=\"";
+  this->CTest->StartXML(xml, this->AppendXML);
+  xml.StartElement("DynamicAnalysis");
   switch ( this->MemoryTesterStyle )
     {
     case cmCTestMemCheckHandler::VALGRIND:
-      os << "Valgrind";
+      xml.Attribute("Checker", "Valgrind");
       break;
     case cmCTestMemCheckHandler::PURIFY:
-      os << "Purify";
+      xml.Attribute("Checker", "Purify");
       break;
     case cmCTestMemCheckHandler::BOUNDS_CHECKER:
-      os << "BoundsChecker";
+      xml.Attribute("Checker", "BoundsChecker");
       break;
     case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
-      os << "AddressSanitizer";
+      xml.Attribute("Checker", "AddressSanitizer");
       break;
     case cmCTestMemCheckHandler::THREAD_SANITIZER:
-      os << "ThreadSanitizer";
+      xml.Attribute("Checker", "ThreadSanitizer");
       break;
     case cmCTestMemCheckHandler::MEMORY_SANITIZER:
-      os << "MemorySanitizer";
+      xml.Attribute("Checker", "MemorySanitizer");
       break;
     case cmCTestMemCheckHandler::UB_SANITIZER:
-      os << "UndefinedBehaviorSanitizer";
+      xml.Attribute("Checker", "UndefinedBehaviorSanitizer");
       break;
     default:
-      os << "Unknown";
+      xml.Attribute("Checker", "Unknown");
     }
-  os << "\">" << std::endl;
 
-  os << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n"
-     << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n"
-     << "\t<TestList>\n";
+  xml.Element("StartDateTime", this->StartTest);
+  xml.Element("StartTestTime", this->StartTestTime);
+  xml.StartElement("TestList");
   cmCTestMemCheckHandler::TestResultsVector::size_type cc;
   for ( cc = 0; cc < this->TestResults.size(); cc ++ )
     {
     cmCTestTestResult *result = &this->TestResults[cc];
     std::string testPath = result->Path + "/" + result->Name;
-    os << "\t\t<Test>" << cmXMLSafe(
-      this->CTest->GetShortPathToFile(testPath.c_str()))
-      << "</Test>" << std::endl;
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
     }
-  os << "\t</TestList>\n";
+  xml.EndElement(); // TestList
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
     "-- Processing memory checking output: ", this->Quiet);
   size_t total = this->TestResults.size();
@@ -419,37 +416,33 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
       }
     this->CleanTestOutput(memcheckstr,
       static_cast<size_t>(this->CustomMaximumFailedTestOutputSize));
-    this->WriteTestResultHeader(os, result);
-    os << "\t\t<Results>" << std::endl;
+    this->WriteTestResultHeader(xml, result);
+    xml.StartElement("Results");
     for(std::vector<int>::size_type kk = 0;
         kk < memcheckresults.size(); ++kk)
       {
       if ( memcheckresults[kk] )
         {
-        os << "\t\t\t<Defect type=\"" << this->ResultStringsLong[kk]
-          << "\">"
-           << memcheckresults[kk]
-           << "</Defect>" << std::endl;
+        xml.StartElement("Defect");
+        xml.Attribute("type", this->ResultStringsLong[kk]);
+        xml.Content(memcheckresults[kk]);
+        xml.EndElement(); // Defect
         }
       this->GlobalResults[kk] += memcheckresults[kk];
       }
+    xml.EndElement(); // Results
 
-    std::string logTag;
+    xml.StartElement("Log");
     if(this->CTest->ShouldCompressMemCheckOutput())
       {
       this->CTest->CompressString(memcheckstr);
-      logTag = "\t<Log compression=\"gzip\" encoding=\"base64\">\n";
-      }
-    else
-      {
-      logTag = "\t<Log>\n";
+      xml.Attribute("compression", "gzip");
+      xml.Attribute("encoding", "base64");
       }
+    xml.Content(memcheckstr);
+    xml.EndElement(); // Log
 
-    os
-      << "\t\t</Results>\n"
-      << logTag << cmXMLSafe(memcheckstr) << std::endl
-      << "\t</Log>\n";
-    this->WriteTestResultFooter(os, result);
+    this->WriteTestResultFooter(xml, result);
     if ( current < cc )
       {
       cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush,
@@ -460,7 +453,7 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet);
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:"
     << std::endl, this->Quiet);
-  os << "\t<DefectList>" << std::endl;
+  xml.StartElement("DefectList");
   for ( cc = 0; cc < this->GlobalResults.size(); cc ++ )
     {
     if ( this->GlobalResults[cc] )
@@ -473,21 +466,20 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
       cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
         this->ResultStringsLong[cc] << " - "
         << this->GlobalResults[cc] << std::endl, this->Quiet);
-      os << "\t\t<Defect Type=\"" << this->ResultStringsLong[cc]
-        << "\"/>" << std::endl;
+      xml.StartElement("Defect");
+      xml.Attribute("Type", this->ResultStringsLong[cc]);
+      xml.EndElement();
       }
     }
-  os << "\t</DefectList>" << std::endl;
+  xml.EndElement(); // DefectList
 
-  os << "\t<EndDateTime>" << this->EndTest << "</EndDateTime>" << std::endl;
-  os << "\t<EndTestTime>" << this->EndTestTime
-     << "</EndTestTime>" << std::endl;
-  os << "<ElapsedMinutes>"
-     << static_cast<int>(this->ElapsedTestingTime/6)/10.0
-     << "</ElapsedMinutes>\n";
+  xml.Element("EndDateTime", this->EndTest);
+  xml.Element("EndTestTime", this->EndTestTime);
+  xml.Element("ElapsedMinutes",
+    static_cast<int>(this->ElapsedTestingTime/6)/10.0);
 
-  os << "</DynamicAnalysis>" << std::endl;
-  this->CTest->EndXML(os);
+  xml.EndElement(); // DynamicAnalysis
+  this->CTest->EndXML(xml);
 }
 
 //----------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 69fdd9f..f1ac794 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -21,6 +21,7 @@
 #include <string>
 
 class cmMakefile;
+class cmXMLWriter;
 
 /** \class cmCTestMemCheckHandler
  * \brief A class that handles ctest -S invocations
@@ -119,7 +120,7 @@ private:
   /**
    * Generate the Dart compatible output
    */
-  void GenerateDartOutput(std::ostream& os);
+  void GenerateDartOutput(cmXMLWriter& xml);
 
   std::vector<std::string> CustomPreMemCheck;
   std::vector<std::string> CustomPostMemCheck;
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index aa68461..c0b9a65 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -27,7 +27,7 @@
 #include "cmLocalGenerator.h"
 #include "cmCommand.h"
 #include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 #include "cm_utf8.h"
 
 #include <stdlib.h>
@@ -633,7 +633,8 @@ int cmCTestTestHandler::ProcessHandler()
       this->LogFile = 0;
       return 1;
       }
-    this->GenerateDartOutput(xmlfile);
+    cmXMLWriter xml(xmlfile);
+    this->GenerateDartOutput(xml);
     }
 
   if ( ! this->PostProcessHandler() )
@@ -1142,54 +1143,53 @@ void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&, int)
 }
 
 //----------------------------------------------------------------------
-void cmCTestTestHandler::GenerateDartOutput(std::ostream& os)
+void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
 {
   if ( !this->CTest->GetProduceXML() )
     {
     return;
     }
 
-  this->CTest->StartXML(os, this->AppendXML);
-  os << "<Testing>\n"
-    << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n"
-    << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n"
-    << "\t<TestList>\n";
+  this->CTest->StartXML(xml, this->AppendXML);
+  xml.StartElement("Testing");
+  xml.Element("StartDateTime", this->StartTest);
+  xml.Element("StartTestTime", this->StartTestTime);
+  xml.StartElement("TestList");
   cmCTestTestHandler::TestResultsVector::size_type cc;
   for ( cc = 0; cc < this->TestResults.size(); cc ++ )
     {
     cmCTestTestResult *result = &this->TestResults[cc];
     std::string testPath = result->Path + "/" + result->Name;
-    os << "\t\t<Test>" << cmXMLSafe(
-      this->CTest->GetShortPathToFile(testPath.c_str()))
-      << "</Test>" << std::endl;
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
     }
-  os << "\t</TestList>\n";
+  xml.EndElement(); // TestList
   for ( cc = 0; cc < this->TestResults.size(); cc ++ )
     {
     cmCTestTestResult *result = &this->TestResults[cc];
-    this->WriteTestResultHeader(os, result);
-    os << "\t\t<Results>" << std::endl;
+    this->WriteTestResultHeader(xml, result);
+    xml.StartElement("Results");
     if ( result->Status != cmCTestTestHandler::NOT_RUN )
       {
       if ( result->Status != cmCTestTestHandler::COMPLETED ||
         result->ReturnValue )
         {
-        os << "\t\t\t<NamedMeasurement type=\"text/string\" "
-          "name=\"Exit Code\"><Value>"
-          << cmXMLSafe(this->GetTestStatus(result->Status))
-          << "</Value>"
-          "</NamedMeasurement>\n"
-          << "\t\t\t<NamedMeasurement type=\"text/string\" "
-          "name=\"Exit Value\"><Value>"
-          << result->ReturnValue
-          << "</Value></NamedMeasurement>"
-          << std::endl;
+        xml.StartElement("NamedMeasurement");
+        xml.Attribute("type", "text/string");
+        xml.Attribute("name", "Exit Code");
+        xml.Element("Value", this->GetTestStatus(result->Status));
+        xml.EndElement(); // NamedMeasurement
+        xml.StartElement("NamedMeasurement");
+        xml.Attribute("type", "text/string");
+        xml.Attribute("name", "Exit Value");
+        xml.Element("Value", result->ReturnValue);
+        xml.EndElement(); // NamedMeasurement
         }
-      this->GenerateRegressionImages(os, result->DartString);
-      os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
-        << "name=\"Execution Time\"><Value>"
-        << result->ExecutionTime
-        << "</Value></NamedMeasurement>\n";
+      this->GenerateRegressionImages(xml, result->DartString);
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute("type", "numeric/double");
+      xml.Attribute("name", "Execution Time");
+      xml.Element("Value", result->ExecutionTime);
+      xml.EndElement(); // NamedMeasurement
       if(!result->Reason.empty())
         {
         const char* reasonType = "Pass Reason";
@@ -1198,109 +1198,103 @@ void cmCTestTestHandler::GenerateDartOutput(std::ostream& os)
           {
           reasonType = "Fail Reason";
           }
-        os << "\t\t\t<NamedMeasurement type=\"text/string\" "
-           << "name=\"" << reasonType << "\"><Value>"
-           << cmXMLSafe(result->Reason)
-           << "</Value></NamedMeasurement>\n";
+        xml.StartElement("NamedMeasurement");
+        xml.Attribute("type", "text/string");
+        xml.Attribute("name", reasonType);
+        xml.Element("Value", result->Reason);
+        xml.EndElement(); // NamedMeasurement
         }
-      os
-        << "\t\t\t<NamedMeasurement type=\"text/string\" "
-        << "name=\"Completion Status\"><Value>"
-        << cmXMLSafe(result->CompletionStatus)
-        << "</Value></NamedMeasurement>\n";
-      }
-    os
-      << "\t\t\t<NamedMeasurement type=\"text/string\" "
-      << "name=\"Command Line\"><Value>"
-      << cmXMLSafe(result->FullCommandLine)
-      << "</Value></NamedMeasurement>\n";
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute("type", "text/string");
+      xml.Attribute("name", "Completion Status");
+      xml.Element("Value", result->CompletionStatus);
+      xml.EndElement(); // NamedMeasurement
+      }
+    xml.StartElement("NamedMeasurement");
+    xml.Attribute("type", "text/string");
+    xml.Attribute("name", "Command Line");
+    xml.Element("Value", result->FullCommandLine);
+    xml.EndElement(); // NamedMeasurement
     std::map<std::string,std::string>::iterator measureIt;
     for ( measureIt = result->Properties->Measurements.begin();
       measureIt != result->Properties->Measurements.end();
       ++ measureIt )
       {
-      os
-        << "\t\t\t<NamedMeasurement type=\"text/string\" "
-        << "name=\"" << measureIt->first << "\"><Value>"
-        << cmXMLSafe(measureIt->second)
-        << "</Value></NamedMeasurement>\n";
-      }
-    os
-      << "\t\t\t<Measurement>\n"
-      << "\t\t\t\t<Value"
-      << (result->CompressOutput ?
-      " encoding=\"base64\" compression=\"gzip\">"
-      : ">");
-    os << cmXMLSafe(result->Output);
-    os
-      << "</Value>\n"
-      << "\t\t\t</Measurement>\n"
-      << "\t\t</Results>\n";
-
-    this->AttachFiles(os, result);
-    this->WriteTestResultFooter(os, result);
-    }
-
-  os << "\t<EndDateTime>" << this->EndTest << "</EndDateTime>\n"
-     << "\t<EndTestTime>" << this->EndTestTime << "</EndTestTime>\n"
-     << "<ElapsedMinutes>"
-     << static_cast<int>(this->ElapsedTestingTime/6)/10.0
-     << "</ElapsedMinutes>"
-    << "</Testing>" << std::endl;
-  this->CTest->EndXML(os);
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute("type", "text/string");
+      xml.Attribute("name", measureIt->first);
+      xml.Element("Value", measureIt->second);
+      xml.EndElement(); // NamedMeasurement
+      }
+    xml.StartElement("Measurement");
+    xml.StartElement("Value");
+    if (result->CompressOutput)
+      {
+      xml.Attribute("encoding", "base64");
+      xml.Attribute("compression", "gzip");
+      }
+    xml.Content(result->Output);
+    xml.EndElement(); // Value
+    xml.EndElement(); // Measurement
+    xml.EndElement(); // Results
+
+    this->AttachFiles(xml, result);
+    this->WriteTestResultFooter(xml, result);
+    }
+
+  xml.Element("EndDateTime", this->EndTest);
+  xml.Element("EndTestTime", this->EndTestTime);
+  xml.Element("ElapsedMinutes",
+    static_cast<int>(this->ElapsedTestingTime/6)/10.0);
+  xml.EndElement(); // Testing
+  this->CTest->EndXML(xml);
 }
 
 //----------------------------------------------------------------------------
-void cmCTestTestHandler::WriteTestResultHeader(std::ostream& os,
+void cmCTestTestHandler::WriteTestResultHeader(cmXMLWriter& xml,
                                                cmCTestTestResult* result)
 {
-  os << "\t<Test Status=\"";
+  xml.StartElement("Test");
   if ( result->Status == cmCTestTestHandler::COMPLETED )
     {
-    os << "passed";
+    xml.Attribute("Status", "passed");
     }
   else if ( result->Status == cmCTestTestHandler::NOT_RUN )
     {
-    os << "notrun";
+    xml.Attribute("Status", "notrun");
     }
   else
     {
-    os << "failed";
+    xml.Attribute("Status", "failed");
     }
   std::string testPath = result->Path + "/" + result->Name;
-  os << "\">\n"
-     << "\t\t<Name>" << cmXMLSafe(result->Name) << "</Name>\n"
-     << "\t\t<Path>" << cmXMLSafe(
-       this->CTest->GetShortPathToFile(result->Path.c_str())) << "</Path>\n"
-     << "\t\t<FullName>" << cmXMLSafe(
-       this->CTest->GetShortPathToFile(testPath.c_str())) << "</FullName>\n"
-     << "\t\t<FullCommandLine>"
-     << cmXMLSafe(result->FullCommandLine)
-     << "</FullCommandLine>\n";
+  xml.Element("Name", result->Name);
+  xml.Element("Path", this->CTest->GetShortPathToFile(result->Path.c_str()));
+  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str()));
+  xml.Element("FullCommandLine", result->FullCommandLine);
 }
 
 //----------------------------------------------------------------------------
-void cmCTestTestHandler::WriteTestResultFooter(std::ostream& os,
+void cmCTestTestHandler::WriteTestResultFooter(cmXMLWriter& xml,
                                                cmCTestTestResult* result)
 {
   if(!result->Properties->Labels.empty())
     {
-    os << "\t\t<Labels>\n";
+    xml.StartElement("Labels");
     std::vector<std::string> const& labels = result->Properties->Labels;
     for(std::vector<std::string>::const_iterator li = labels.begin();
         li != labels.end(); ++li)
       {
-      os << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n";
+      xml.Element("Label", *li);
       }
-    os << "\t\t</Labels>\n";
+    xml.EndElement(); // Labels
     }
 
-  os
-    << "\t</Test>" << std::endl;
+  xml.EndElement(); // Test
 }
 
 //----------------------------------------------------------------------
-void cmCTestTestHandler::AttachFiles(std::ostream& os,
+void cmCTestTestHandler::AttachFiles(cmXMLWriter& xml,
                                      cmCTestTestResult* result)
 {
   if(result->Status != cmCTestTestHandler::COMPLETED
@@ -1317,11 +1311,14 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os,
     {
     const std::string &base64 = this->CTest->Base64GzipEncodeFile(*file);
     std::string fname = cmSystemTools::GetFilenameName(*file);
-    os << "\t\t<NamedMeasurement name=\"Attached File\" encoding=\"base64\" "
-      "compression=\"tar/gzip\" filename=\"" << fname << "\" type=\"file\">"
-      "\n\t\t\t<Value>\n\t\t\t"
-      << base64
-      << "\n\t\t\t</Value>\n\t\t</NamedMeasurement>\n";
+    xml.StartElement("NamedMeasurement");
+    xml.Attribute("name", "Attached File");
+    xml.Attribute("encoding", "base64");
+    xml.Attribute("compression", "tar/gzip");
+    xml.Attribute("filename", fname);
+    xml.Attribute("type", "file");
+    xml.Element("Value", base64);
+    xml.EndElement(); // NamedMeasurement
     }
 }
 
@@ -1829,7 +1826,7 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
 #define SPACE_REGEX "[ \t\r\n]"
 //----------------------------------------------------------------------
 void cmCTestTestHandler::GenerateRegressionImages(
-  std::ostream& ostr, const std::string& xml)
+  cmXMLWriter& xml, const std::string& dart)
 {
   cmsys::RegularExpression twoattributes(
     "<DartMeasurement"
@@ -1865,69 +1862,61 @@ void cmCTestTestHandler::GenerateRegressionImages(
     SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");
 
   bool done = false;
-  std::string cxml = xml;
+  std::string cxml = dart;
   while ( ! done )
     {
     if ( twoattributes.find(cxml) )
       {
-      ostr
-        << "\t\t\t<NamedMeasurement"
-        << " " << twoattributes.match(1) << "=\""
-        << twoattributes.match(2) << "\""
-        << " " << twoattributes.match(3) << "=\""
-        << twoattributes.match(4) << "\""
-        << "><Value>" << twoattributes.match(5)
-        << "</Value></NamedMeasurement>"
-        << std::endl;
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute(twoattributes.match(1).c_str(),
+                    twoattributes.match(2));
+      xml.Attribute(twoattributes.match(3).c_str(),
+                    twoattributes.match(4));
+      xml.Element("Value", twoattributes.match(5));
+      xml.EndElement();
       cxml.erase(twoattributes.start(),
         twoattributes.end() - twoattributes.start());
       }
     else if ( threeattributes.find(cxml) )
       {
-      ostr
-        << "\t\t\t<NamedMeasurement"
-        << " " << threeattributes.match(1) << "=\""
-        << threeattributes.match(2) << "\""
-        << " " << threeattributes.match(3) << "=\""
-        << threeattributes.match(4) << "\""
-        << " " << threeattributes.match(5) << "=\""
-        << threeattributes.match(6) << "\""
-        << "><Value>" << threeattributes.match(7)
-        << "</Value></NamedMeasurement>"
-        << std::endl;
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute(threeattributes.match(1).c_str(),
+                    threeattributes.match(2));
+      xml.Attribute(threeattributes.match(3).c_str(),
+                    threeattributes.match(4));
+      xml.Attribute(threeattributes.match(5).c_str(),
+                    threeattributes.match(6));
+      xml.Element("Value", twoattributes.match(7));
+      xml.EndElement();
       cxml.erase(threeattributes.start(),
         threeattributes.end() - threeattributes.start());
       }
     else if ( fourattributes.find(cxml) )
       {
-      ostr
-        << "\t\t\t<NamedMeasurement"
-        << " " << fourattributes.match(1) << "=\""
-        << fourattributes.match(2) << "\""
-        << " " << fourattributes.match(3) << "=\""
-        << fourattributes.match(4) << "\""
-        << " " << fourattributes.match(5) << "=\""
-        << fourattributes.match(6) << "\""
-        << " " << fourattributes.match(7) << "=\""
-        << fourattributes.match(8) << "\""
-        << "><Value>" << fourattributes.match(9)
-        << "</Value></NamedMeasurement>"
-        << std::endl;
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute(fourattributes.match(1).c_str(),
+                    fourattributes.match(2));
+      xml.Attribute(fourattributes.match(3).c_str(),
+                    fourattributes.match(4));
+      xml.Attribute(fourattributes.match(5).c_str(),
+                    fourattributes.match(6));
+      xml.Attribute(fourattributes.match(7).c_str(),
+                    fourattributes.match(8));
+      xml.Element("Value", twoattributes.match(9));
+      xml.EndElement();
       cxml.erase(fourattributes.start(),
         fourattributes.end() - fourattributes.start());
       }
     else if ( cdatastart.find(cxml) && cdataend.find(cxml) )
       {
-      ostr
-        << "\t\t\t<NamedMeasurement"
-        << " " << cdatastart.match(1) << "=\""
-        << cdatastart.match(2) << "\""
-        << " " << cdatastart.match(3) << "=\""
-        << cdatastart.match(4) << "\""
-        << "><Value><![CDATA["
-        << cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end())
-        << "]]></Value></NamedMeasurement>"
-        << std::endl;
+      xml.StartElement("NamedMeasurement");
+      xml.Attribute(cdatastart.match(1).c_str(), cdatastart.match(2));
+      xml.Attribute(cdatastart.match(3).c_str(), cdatastart.match(4));
+      xml.StartElement("Value");
+      xml.CData(
+          cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end()));
+      xml.EndElement(); // Value
+      xml.EndElement(); // NamedMeasurement
       cxml.erase(cdatastart.start(),
         cdataend.end() - cdatastart.start());
       }
@@ -1953,13 +1942,12 @@ void cmCTestTestHandler::GenerateRegressionImages(
             v2 = "text/string";
             }
 
-          ostr
-            << "\t\t\t<NamedMeasurement"
-            << " " << k1 << "=\"" << v1 << "\""
-            << " " << k2 << "=\"" << v2 << "\""
-            << " encoding=\"none\""
-            << "><Value>Image " << filename
-            << " is empty</Value></NamedMeasurement>";
+          xml.StartElement("NamedMeasurement");
+          xml.Attribute(k1.c_str(), v1);
+          xml.Attribute(k2.c_str(), v2);
+          xml.Attribute("encoding", "none");
+          xml.Element("Value", "Image " + filename + " is empty");
+          xml.EndElement();
           }
         else
           {
@@ -1977,14 +1965,13 @@ void cmCTestTestHandler::GenerateRegressionImages(
           size_t rlen
             = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
 
-          ostr
-            << "\t\t\t<NamedMeasurement"
-            << " " << measurementfile.match(1) << "=\""
-            << measurementfile.match(2) << "\""
-            << " " << measurementfile.match(3) << "=\""
-            << measurementfile.match(4) << "\""
-            << " encoding=\"base64\""
-            << ">" << std::endl << "\t\t\t\t<Value>";
+          xml.StartElement("NamedMeasurement");
+          xml.Attribute(measurementfile.match(1).c_str(),
+                        measurementfile.match(2));
+          xml.Attribute(measurementfile.match(3).c_str(),
+                        measurementfile.match(4));
+          xml.Attribute("encoding", "base64");
+          std::stringstream ostr;
           for (size_t cc = 0; cc < rlen; cc ++ )
             {
             ostr << encoded_buffer[cc];
@@ -1993,9 +1980,8 @@ void cmCTestTestHandler::GenerateRegressionImages(
               ostr << std::endl;
               }
             }
-          ostr
-            << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>"
-            << std::endl;
+          xml.Element("Value", ostr.str());
+          xml.EndElement(); // NamedMeasurement
           delete [] file_buffer;
           delete [] encoded_buffer;
           }
@@ -2007,13 +1993,11 @@ void cmCTestTestHandler::GenerateRegressionImages(
           {
           idx = 2;
           }
-        ostr
-          << "\t\t\t<NamedMeasurement"
-          << " name=\"" << measurementfile.match(idx) << "\""
-          << " text=\"text/string\""
-          << "><Value>File " << filename
-          << " not found</Value></NamedMeasurement>"
-          << std::endl;
+        xml.StartElement("NamedMeasurement");
+        xml.Attribute("name", measurementfile.match(idx));
+        xml.Attribute("text", "text/string");
+        xml.Element("Value", "File " + filename + " not found");
+        xml.EndElement();
         cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename
           << "\" not found." << std::endl, this->Quiet);
         }
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 623c996..14067d5 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -18,6 +18,7 @@
 #include <cmsys/RegularExpression.hxx>
 
 class cmMakefile;
+class cmXMLWriter;
 
 /** \class cmCTestTestHandler
  * \brief A class that handles ctest -S invocations
@@ -164,10 +165,10 @@ protected:
   virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
   int ExecuteCommands(std::vector<std::string>& vec);
 
-  void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result);
-  void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result);
+  void WriteTestResultHeader(cmXMLWriter& xml, cmCTestTestResult* result);
+  void WriteTestResultFooter(cmXMLWriter& xml, cmCTestTestResult* result);
   // Write attached test files into the xml
-  void AttachFiles(std::ostream& os, cmCTestTestResult* result);
+  void AttachFiles(cmXMLWriter& xml, cmCTestTestResult* result);
 
   //! Clean test output to specified length
   bool CleanTestOutput(std::string& output, size_t length);
@@ -204,7 +205,7 @@ private:
   /**
    * Generate the Dart compatible output
    */
-  virtual void GenerateDartOutput(std::ostream& os);
+  virtual void GenerateDartOutput(cmXMLWriter& xml);
 
   void PrintLabelSummary();
   /**
@@ -270,7 +271,7 @@ private:
   cmsys::RegularExpression IncludeTestsRegularExpression;
   cmsys::RegularExpression ExcludeTestsRegularExpression;
 
-  void GenerateRegressionImages(std::ostream& ostr, const std::string& xml);
+  void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
   cmsys::RegularExpression DartStuff1;
   void CheckLabelFilter(cmCTestTestProperties& it);
   void CheckLabelFilterExclude(cmCTestTestProperties& it);

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8fbc509a48e53f7462143dded5a01c77ab5ba6bd
commit 8fbc509a48e53f7462143dded5a01c77ab5ba6bd
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 21:18:40 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:22 2015 -0400

    cmCTestCoverageHandler: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 790e488..f92f19a 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -22,7 +22,7 @@
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
 #include "cmGeneratedFileStream.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 #include <cmsys/Process.h>
 #include <cmsys/RegularExpression.hxx>
@@ -185,14 +185,6 @@ bool cmCTestCoverageHandler::StartCoverageLogFile(
       << covLogFilename << std::endl);
     return false;
     }
-  std::string local_start_time = this->CTest->CurrentTime();
-  this->CTest->StartXML(covLogFile, this->AppendXML);
-  covLogFile << "<CoverageLog>" << std::endl
-             << "\t<StartDateTime>" << local_start_time << "</StartDateTime>"
-             << "\t<StartTime>"
-             << static_cast<unsigned int>(cmSystemTools::GetTime())
-             << "</StartTime>"
-    << std::endl;
   return true;
 }
 
@@ -200,13 +192,6 @@ bool cmCTestCoverageHandler::StartCoverageLogFile(
 void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr,
   int logFileCount)
 {
-  std::string local_end_time = this->CTest->CurrentTime();
-  ostr << "\t<EndDateTime>" << local_end_time << "</EndDateTime>" << std::endl
-       << "\t<EndTime>" <<
-       static_cast<unsigned int>(cmSystemTools::GetTime())
-       << "</EndTime>" << std::endl
-    << "</CoverageLog>" << std::endl;
-  this->CTest->EndXML(ostr);
   char covLogFilename[1024];
   sprintf(covLogFilename, "CoverageLog-%d.xml", logFileCount);
   cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Close file: "
@@ -215,6 +200,25 @@ void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr,
 }
 
 //----------------------------------------------------------------------
+void cmCTestCoverageHandler::StartCoverageLogXML(cmXMLWriter& xml)
+{
+  this->CTest->StartXML(xml, this->AppendXML);
+  xml.StartElement("CoverageLog");
+  xml.Element("StartDateTime", this->CTest->CurrentTime());
+  xml.Element("StartTime",
+    static_cast<unsigned int>(cmSystemTools::GetTime()));
+}
+
+//----------------------------------------------------------------------
+void cmCTestCoverageHandler::EndCoverageLogXML(cmXMLWriter& xml)
+{
+  xml.Element("EndDateTime", this->CTest->CurrentTime());
+  xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime()));
+  xml.EndElement(); // CoverageLog
+  this->CTest->EndXML(xml);
+}
+
+//----------------------------------------------------------------------
 bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
   const char* srcDir,
   const char* binDir)
@@ -451,6 +455,8 @@ int cmCTestCoverageHandler::ProcessHandler()
     }
   cmGeneratedFileStream covSumFile;
   cmGeneratedFileStream covLogFile;
+  cmXMLWriter covSumXML(covSumFile);
+  cmXMLWriter covLogXML(covLogFile);
 
   if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile))
     {
@@ -458,20 +464,21 @@ int cmCTestCoverageHandler::ProcessHandler()
       "Cannot open coverage summary file." << std::endl);
     return -1;
     }
+  covSumFile.setf(std::ios::fixed, std::ios::floatfield);
+  covSumFile.precision(2);
 
-  this->CTest->StartXML(covSumFile, this->AppendXML);
+  this->CTest->StartXML(covSumXML, this->AppendXML);
   // Produce output xml files
 
-  covSumFile << "<Coverage>" << std::endl
-    << "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>"
-    << std::endl
-    << "\t<StartTime>" << coverage_start_time_time << "</StartTime>"
-    << std::endl;
+  covSumXML.StartElement("Coverage");
+  covSumXML.Element("StartDateTime", coverage_start_time);
+  covSumXML.Element("StartTime", coverage_start_time_time);
   int logFileCount = 0;
   if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
     {
     return -1;
     }
+  this->StartCoverageLogXML(covLogXML);
   cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator fileIterator;
   int cnt = 0;
   long total_tested = 0;
@@ -528,12 +535,14 @@ int cmCTestCoverageHandler::ProcessHandler()
 
     if ( ++cnt % 100 == 0 )
       {
+      this->EndCoverageLogXML(covLogXML);
       this->EndCoverageLogFile(covLogFile, logFileCount);
       logFileCount ++;
       if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
         {
         return -1;
         }
+      this->StartCoverageLogXML(covLogXML);
       }
 
     const std::string fileName
@@ -542,9 +551,10 @@ int cmCTestCoverageHandler::ProcessHandler()
       this->CTest->GetShortPathToFile(fullFileName.c_str());
     const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov
       = fileIterator->second;
-    covLogFile << "\t<File Name=\"" << cmXMLSafe(fileName)
-      << "\" FullPath=\"" << cmXMLSafe(shortFileName) << "\">\n"
-      << "\t\t<Report>" << std::endl;
+    covLogXML.StartElement("File");
+    covLogXML.Attribute("Name", fileName);
+    covLogXML.Attribute("FullPath", shortFileName);
+    covLogXML.StartElement("Report");
 
     cmsys::ifstream ifs(fullFileName.c_str());
     if ( !ifs)
@@ -576,9 +586,11 @@ int cmCTestCoverageHandler::ProcessHandler()
         error ++;
         break;
         }
-      covLogFile << "\t\t<Line Number=\"" << cc << "\" Count=\"" << fcov[cc]
-        << "\">"
-        << cmXMLSafe(line) << "</Line>" << std::endl;
+      covLogXML.StartElement("Line");
+      covLogXML.Attribute("Number", cc);
+      covLogXML.Attribute("Count", fcov[cc]);
+      covLogXML.Content(line);
+      covLogXML.EndElement(); // Line
       if ( fcov[cc] == 0 )
         {
         untested ++;
@@ -605,24 +617,19 @@ int cmCTestCoverageHandler::ProcessHandler()
       }
     total_tested += tested;
     total_untested += untested;
-    covLogFile << "\t\t</Report>" << std::endl
-      << "\t</File>" << std::endl;
-    covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName)
-      << "\" FullPath=\"" << cmXMLSafe(
-        this->CTest->GetShortPathToFile(fullFileName.c_str()))
-      << "\" Covered=\"" << (tested+untested > 0 ? "true":"false") << "\">\n"
-      << "\t\t<LOCTested>" << tested << "</LOCTested>\n"
-      << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n"
-      << "\t\t<PercentCoverage>";
-    covSumFile.setf(std::ios::fixed, std::ios::floatfield);
-    covSumFile.precision(2);
-    covSumFile << (cper) << "</PercentCoverage>\n"
-      << "\t\t<CoverageMetric>";
-    covSumFile.setf(std::ios::fixed, std::ios::floatfield);
-    covSumFile.precision(2);
-    covSumFile << (cmet) << "</CoverageMetric>\n";
-    this->WriteXMLLabels(covSumFile, shortFileName);
-    covSumFile << "\t</File>" << std::endl;
+    covLogXML.EndElement(); // Report
+    covLogXML.EndElement(); // File
+    covSumXML.StartElement("File");
+    covSumXML.Attribute("Name", fileName);
+    covSumXML.Attribute("FullPath",
+      this->CTest->GetShortPathToFile(fullFileName.c_str()));
+    covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false");
+    covSumXML.Element("LOCTested", tested);
+    covSumXML.Element("LOCUnTested", untested);
+    covSumXML.Element("PercentCoverage", cper);
+    covSumXML.Element("CoverageMetric", cmet);
+    this->WriteXMLLabels(covSumXML, shortFileName);
+    covSumXML.EndElement(); // File
     }
 
   //Handle all the files in the extra coverage globs that have no cov data
@@ -632,9 +639,10 @@ int cmCTestCoverageHandler::ProcessHandler()
     std::string fileName = cmSystemTools::GetFilenameName(*i);
     std::string fullPath = cont.SourceDir + "/" + *i;
 
-    covLogFile << "\t<File Name=\"" << cmXMLSafe(fileName)
-      << "\" FullPath=\"" << cmXMLSafe(*i) << "\">\n"
-      << "\t\t<Report>" << std::endl;
+    covLogXML.StartElement("File");
+    covLogXML.Attribute("Name", fileName);
+    covLogXML.Attribute("FullPath", *i);
+    covLogXML.StartElement("Report");
 
     cmsys::ifstream ifs(fullPath.c_str());
     if (!ifs)
@@ -651,24 +659,30 @@ int cmCTestCoverageHandler::ProcessHandler()
       "Actually performing coverage for: " << *i << std::endl, this->Quiet);
     while (cmSystemTools::GetLineFromStream(ifs, line))
       {
-      covLogFile << "\t\t<Line Number=\"" << untested << "\" Count=\"0\">"
-        << cmXMLSafe(line) << "</Line>" << std::endl;
+      covLogXML.StartElement("Line");
+      covLogXML.Attribute("Number", untested);
+      covLogXML.Attribute("Count", 0);
+      covLogXML.Content(line);
+      covLogXML.EndElement(); // Line
       untested ++;
       }
-    covLogFile << "\t\t</Report>\n\t</File>" << std::endl;
+    covLogXML.EndElement(); // Report
+    covLogXML.EndElement(); // File
 
     total_untested += untested;
-    covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName)
-      << "\" FullPath=\"" << cmXMLSafe(i->c_str())
-      << "\" Covered=\"true\">\n"
-      << "\t\t<LOCTested>0</LOCTested>\n"
-      << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n"
-      << "\t\t<PercentCoverage>0</PercentCoverage>\n"
-      << "\t\t<CoverageMetric>0</CoverageMetric>\n";
-    this->WriteXMLLabels(covSumFile, *i);
-    covSumFile << "\t</File>" << std::endl;
-    }
-
+    covSumXML.StartElement("File");
+    covSumXML.Attribute("Name", fileName);
+    covSumXML.Attribute("FullPath", *i);
+    covSumXML.Attribute("Covered", "true");
+    covSumXML.Element("LOCTested", 0);
+    covSumXML.Element("LOCUnTested", untested);
+    covSumXML.Element("PercentCoverage", 0);
+    covSumXML.Element("CoverageMetric", 0);
+    this->WriteXMLLabels(covSumXML, *i);
+    covSumXML.EndElement(); // File
+    }
+
+  this->EndCoverageLogXML(covLogXML);
   this->EndCoverageLogFile(covLogFile, logFileCount);
 
   if (!errorsWhileAccumulating.empty())
@@ -696,22 +710,17 @@ int cmCTestCoverageHandler::ProcessHandler()
 
   std::string end_time = this->CTest->CurrentTime();
 
-  covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
-    << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
-    << "\t<LOC>" << total_lines << "</LOC>\n"
-    << "\t<PercentCoverage>";
-  covSumFile.setf(std::ios::fixed, std::ios::floatfield);
-  covSumFile.precision(2);
-  covSumFile << (percent_coverage)<< "</PercentCoverage>\n"
-    << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
-    << "\t<EndTime>" <<
-         static_cast<unsigned int>(cmSystemTools::GetTime())
-    << "</EndTime>\n";
-  covSumFile << "<ElapsedMinutes>" <<
-    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
-    << "</ElapsedMinutes>"
-    << "</Coverage>" << std::endl;
-  this->CTest->EndXML(covSumFile);
+  covSumXML.Element("LOCTested", total_tested);
+  covSumXML.Element("LOCUntested", total_untested);
+  covSumXML.Element("LOC", total_lines);
+  covSumXML.Element("PercentCoverage", percent_coverage);
+  covSumXML.Element("EndDateTime", end_time);
+  covSumXML.Element("EndTime",
+    static_cast<unsigned int>(cmSystemTools::GetTime()));
+  covSumXML.Element("ElapsedMinutes",
+    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+  covSumXML.EndElement(); // Coverage
+  this->CTest->EndXML(covSumXML);
 
   cmCTestLog(this->CTest, HANDLER_OUTPUT, "" << std::endl
     << "\tCovered LOC:         "
@@ -1952,11 +1961,13 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
     }
   // create the output stream for the CoverageLog-N.xml file
   cmGeneratedFileStream covLogFile;
+  cmXMLWriter covLogXML(covLogFile);
   int logFileCount = 0;
   if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
     {
     return -1;
     }
+  this->StartCoverageLogXML(covLogXML);
   // for each file run covbr on that file to get the coverage
   // information for that file
   std::string outputFile;
@@ -2009,20 +2020,22 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
       // if we are in a valid file close it because a new one started
       if(valid)
         {
-        covLogFile << "\t\t</Report>" << std::endl
-                   << "\t</File>" << std::endl;
+        covLogXML.EndElement(); // Report
+        covLogXML.EndElement(); // File
         }
       // only allow 100 files in each log file
       if ( count != 0 && count % 100 == 0 )
         {
         cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
           "start a new log file: " << count << std::endl, this->Quiet);
+        this->EndCoverageLogXML(covLogXML);
         this->EndCoverageLogFile(covLogFile, logFileCount);
         logFileCount ++;
         if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
           {
           return -1;
           }
+        this->StartCoverageLogXML(covLogXML);
         count++; // move on one
         }
       std::map<std::string, std::string>::iterator
@@ -2036,19 +2049,20 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
           "Produce coverage for file: " << file << " " << count
           << std::endl, this->Quiet);
         // start the file output
-        covLogFile << "\t<File Name=\""
-                   << cmXMLSafe(i->first)
-                   << "\" FullPath=\"" << cmXMLSafe(
-                     this->CTest->GetShortPathToFile(
-                       i->second.c_str())) << "\">" << std::endl
-                   << "\t\t<Report>" << std::endl;
+        covLogXML.StartElement("File");
+        covLogXML.Attribute("Name", i->first);
+        covLogXML.Attribute("FullPath",
+          this->CTest->GetShortPathToFile(i->second.c_str()));
+        covLogXML.StartElement("Report");
         // write the bullseye header
         line =0;
         for(int k =0; bullseyeHelp[k] != 0; ++k)
           {
-          covLogFile << "\t\t<Line Number=\"" << line << "\" Count=\"-1\">"
-                     << cmXMLSafe(bullseyeHelp[k])
-                     << "</Line>" << std::endl;
+          covLogXML.StartElement("Line");
+          covLogXML.Attribute("Number", line);
+          covLogXML.Attribute("Count", -1);
+          covLogXML.Content(bullseyeHelp[k]);
+          covLogXML.EndElement(); // Line
           line++;
           }
         valid = true; // we are in a valid file section
@@ -2062,18 +2076,21 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
     // we are not at a start file, and we are in a valid file output the line
     else if(valid)
       {
-      covLogFile << "\t\t<Line Number=\"" << line << "\" Count=\"-1\">"
-                 << cmXMLSafe(lineIn)
-                 << "</Line>" << std::endl;
+      covLogXML.StartElement("Line");
+      covLogXML.Attribute("Number", line);
+      covLogXML.Attribute("Count", -1);
+      covLogXML.Content(lineIn);
+      covLogXML.EndElement(); // Line
       line++;
       }
     }
   // if we ran out of lines a valid file then close that file
   if(valid)
     {
-    covLogFile << "\t\t</Report>" << std::endl
-               << "\t</File>" << std::endl;
+    covLogXML.EndElement(); // Report
+    covLogXML.EndElement(); // File
     }
+  this->EndCoverageLogXML(covLogXML);
   this->EndCoverageLogFile(covLogFile, logFileCount);
   return 1;
 }
@@ -2143,23 +2160,20 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
   std::ostream& tmpLog = *cont->OFS;
   // copen the Coverage.xml file in the Testing directory
   cmGeneratedFileStream covSumFile;
+  cmXMLWriter xml(covSumFile);
   if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile))
     {
     cmCTestLog(this->CTest, ERROR_MESSAGE,
       "Cannot open coverage summary file." << std::endl);
     return 0;
     }
-  this->CTest->StartXML(covSumFile, this->AppendXML);
+  this->CTest->StartXML(xml, this->AppendXML);
   double elapsed_time_start = cmSystemTools::GetTime();
   std::string coverage_start_time = this->CTest->CurrentTime();
-  covSumFile << "<Coverage>" << std::endl
-             << "\t<StartDateTime>"
-             << coverage_start_time << "</StartDateTime>"
-             << std::endl
-             << "\t<StartTime>"
-             << static_cast<unsigned int>(cmSystemTools::GetTime())
-             << "</StartTime>"
-             << std::endl;
+  xml.StartElement("Coverage");
+  xml.Element("StartDateTime", coverage_start_time);
+  xml.Element("StartTime",
+    static_cast<unsigned int>(cmSystemTools::GetTime()));
   std::string stdline;
   std::string errline;
   // expected output:
@@ -2271,58 +2285,35 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary(
       tmpLog << "percentBranch: " << percentBranch << "\n";
       tmpLog << "percentCoverage: " << percent_coverage << "\n";
       tmpLog << "coverage metric: " << cmet << "\n";
-      covSumFile << "\t<File Name=\"" << cmXMLSafe(sourceFile)
-                 << "\" FullPath=\"" << cmXMLSafe(shortFileName)
-                 << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n"
-                 << "\t\t<BranchesTested>"
-                 << branchCovered
-                 << "</BranchesTested>\n"
-                 << "\t\t<BranchesUnTested>"
-                 << totalBranches - branchCovered
-                 << "</BranchesUnTested>\n"
-                 << "\t\t<FunctionsTested>"
-                 << functionsCalled
-                 << "</FunctionsTested>\n"
-                 << "\t\t<FunctionsUnTested>"
-                 << totalFunctions - functionsCalled
-                 << "</FunctionsUnTested>\n"
-        // Hack for conversion of function to loc assume a function
-        // has 100 lines of code
-                 << "\t\t<LOCTested>" << functionsCalled *100
-                 << "</LOCTested>\n"
-                 << "\t\t<LOCUnTested>"
-                 << (totalFunctions - functionsCalled)*100
-                 << "</LOCUnTested>\n"
-                 << "\t\t<PercentCoverage>";
-      covSumFile.setf(std::ios::fixed, std::ios::floatfield);
-      covSumFile.precision(2);
-      covSumFile << (cper) << "</PercentCoverage>\n"
-                 << "\t\t<CoverageMetric>";
-      covSumFile.setf(std::ios::fixed, std::ios::floatfield);
-      covSumFile.precision(2);
-      covSumFile << (cmet) << "</CoverageMetric>\n";
-      this->WriteXMLLabels(covSumFile, shortFileName);
-      covSumFile << "\t</File>" << std::endl;
+      xml.StartElement("File");
+      xml.Attribute("Name", sourceFile);
+      xml.Attribute("FullPath", shortFileName);
+      xml.Attribute("Covered", cmet > 0 ? "true" : "false");
+      xml.Element("BranchesTested", branchCovered);
+      xml.Element("BranchesUnTested", totalBranches - branchCovered);
+      xml.Element("FunctionsTested", functionsCalled);
+      xml.Element("FunctionsUnTested", totalFunctions - functionsCalled);
+      // Hack for conversion of function to loc assume a function
+      // has 100 lines of code
+      xml.Element("LOCTested", functionsCalled * 100);
+      xml.Element("LOCUnTested", (totalFunctions - functionsCalled) * 100);
+      xml.Element("PercentCoverage", cper);
+      xml.Element("CoverageMetric", cmet);
+      this->WriteXMLLabels(xml, shortFileName);
+      xml.EndElement(); // File
       }
     }
   std::string end_time = this->CTest->CurrentTime();
-  covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
-    << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
-    << "\t<LOC>" << total_functions << "</LOC>\n"
-    << "\t<PercentCoverage>";
-  covSumFile.setf(std::ios::fixed, std::ios::floatfield);
-  covSumFile.precision(2);
-  covSumFile
-    << SAFEDIV(percent_coverage,number_files)<< "</PercentCoverage>\n"
-    << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
-    << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime())
-    << "</EndTime>\n";
-  covSumFile
-    << "<ElapsedMinutes>" <<
-    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
-    << "</ElapsedMinutes>"
-    << "</Coverage>" << std::endl;
-  this->CTest->EndXML(covSumFile);
+  xml.Element("LOCTested", total_tested);
+  xml.Element("LOCUntested", total_untested);
+  xml.Element("LOC", total_functions);
+  xml.Element("PercentCoverage", SAFEDIV(percent_coverage, number_files));
+  xml.Element("EndDateTime", end_time);
+  xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime()));
+  xml.Element("ElapsedMinutes",
+    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+  xml.EndElement(); // Coverage
+  this->CTest->EndXML(xml);
 
   // Now create the coverage information for each file
   return this->RunBullseyeCoverageBranch(cont,
@@ -2514,19 +2505,19 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir)
 }
 
 //----------------------------------------------------------------------
-void cmCTestCoverageHandler::WriteXMLLabels(std::ostream& os,
+void cmCTestCoverageHandler::WriteXMLLabels(cmXMLWriter& xml,
                                             std::string const& source)
 {
   LabelMapType::const_iterator li = this->SourceLabels.find(source);
   if(li != this->SourceLabels.end() && !li->second.empty())
     {
-    os << "\t\t<Labels>\n";
+    xml.StartElement("Labels");
     for(LabelSet::const_iterator lsi = li->second.begin();
         lsi != li->second.end(); ++lsi)
       {
-      os << "\t\t\t<Label>" << cmXMLSafe(this->Labels[*lsi]) << "</Label>\n";
+      xml.Element("Label", this->Labels[*lsi]);
       }
-    os << "\t\t</Labels>\n";
+    xml.EndElement(); // Labels
     }
 }
 
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 3258ddb..2ca123a 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -20,6 +20,7 @@
 #include <cmsys/RegularExpression.hxx>
 
 class cmGeneratedFileStream;
+class cmXMLWriter;
 class cmCTestCoverageHandlerContainer
 {
 public:
@@ -65,6 +66,9 @@ private:
   bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
   void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
 
+  void StartCoverageLogXML(cmXMLWriter& xml);
+  void EndCoverageLogXML(cmXMLWriter& xml);
+
   //! Handle coverage using GCC's GCov
   int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont);
   void FindGCovFiles(std::vector<std::string>& files);
@@ -146,7 +150,7 @@ private:
   // Label reading and writing methods.
   void LoadLabels();
   void LoadLabels(const char* dir);
-  void WriteXMLLabels(std::ostream& os, std::string const& source);
+  void WriteXMLLabels(cmXMLWriter& xml, std::string const& source);
 
   // Label-based filtering.
   std::set<int> LabelFilter;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=82455a9d3af88296741a6b087fceed1bb6a28b1e
commit 82455a9d3af88296741a6b087fceed1bb6a28b1e
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 21:36:12 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:22 2015 -0400

    cmCTestBuildHandler: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 29e07ef..47d9c7a 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -18,7 +18,7 @@
 #include "cmLocalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmGeneratedFileStream.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 #include "cmFileTimeComparison.h"
 #include "cmAlgorithms.h"
 
@@ -523,16 +523,17 @@ int cmCTestBuildHandler::ProcessHandler()
       << std::endl);
     return -1;
     }
-  this->GenerateXMLHeader(xofs);
+  cmXMLWriter xml(xofs);
+  this->GenerateXMLHeader(xml);
   if(this->UseCTestLaunch)
     {
-    this->GenerateXMLLaunched(xofs);
+    this->GenerateXMLLaunched(xml);
     }
   else
     {
-    this->GenerateXMLLogScraped(xofs);
+    this->GenerateXMLLogScraped(xml);
     }
-  this->GenerateXMLFooter(xofs, elapsed_build_time);
+  this->GenerateXMLFooter(xml, elapsed_build_time);
 
   if (res != cmsysProcess_State_Exited || retVal || this->TotalErrors > 0)
     {
@@ -552,17 +553,14 @@ int cmCTestBuildHandler::ProcessHandler()
 }
 
 //----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLHeader(std::ostream& os)
+void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml)
 {
-  this->CTest->StartXML(os, this->AppendXML);
-  os << "<Build>\n"
-     << "\t<StartDateTime>" << this->StartBuild << "</StartDateTime>\n"
-     << "\t<StartBuildTime>" <<
-    static_cast<unsigned int>(this->StartBuildTime)
-     << "</StartBuildTime>\n"
-     << "<BuildCommand>"
-     << cmXMLSafe(this->GetMakeCommand())
-     << "</BuildCommand>" << std::endl;
+  this->CTest->StartXML(xml, this->AppendXML);
+  xml.StartElement("Build");
+  xml.Element("StartDateTime", this->StartBuild);
+  xml.Element("StartBuildTime",
+    static_cast<unsigned int>(this->StartBuildTime));
+  xml.Element("BuildCommand", this->GetMakeCommand());
 }
 
 //----------------------------------------------------------------------------
@@ -591,7 +589,7 @@ private:
 };
 
 //----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
+void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
 {
   if(this->CTestLaunchDir.empty())
     {
@@ -632,12 +630,12 @@ void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
   for(Fragments::const_iterator fi = fragments.begin();
       fi != fragments.end(); ++fi)
     {
-    this->GenerateXMLLaunchedFragment(os, fi->c_str());
+    xml.FragmentFile(fi->c_str());
     }
 }
 
 //----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
+void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml)
 {
   std::vector<cmCTestBuildErrorWarning>& ew = this->ErrorsAndWarnings;
   std::vector<cmCTestBuildErrorWarning>::iterator it;
@@ -665,10 +663,9 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
         {
         numWarningsAllowed--;
         }
-      os << "\t<" << (cm->Error ? "Error" : "Warning") << ">\n"
-         << "\t\t<BuildLogLine>" << cm->LogLine << "</BuildLogLine>\n"
-         << "\t\t<Text>" << cmXMLSafe(cm->Text).Quotes(false)
-         << "\n</Text>" << std::endl;
+      xml.StartElement(cm->Error ? "Error" : "Warning");
+      xml.Element("BuildLogLine", cm->LogLine);
+      xml.Element("Text", cm->Text);
       std::vector<cmCTestCompileErrorWarningRex>::iterator rit;
       for ( rit = this->ErrorWarningFileLineRegex.begin();
             rit != this->ErrorWarningFileLineRegex.end(); ++ rit )
@@ -706,62 +703,48 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
         {
         if (!cm->SourceFile.empty())
           {
-          os << "\t\t<SourceFile>" << cm->SourceFile << "</SourceFile>"
-            << std::endl;
+          xml.Element("SourceFile", cm->SourceFile);
           }
         if (!cm->SourceFileTail.empty())
           {
-          os << "\t\t<SourceFileTail>" << cm->SourceFileTail
-            << "</SourceFileTail>" << std::endl;
+          xml.Element("SourceFileTail", cm->SourceFileTail);
           }
         if ( cm->LineNumber >= 0 )
           {
-          os << "\t\t<SourceLineNumber>" << cm->LineNumber
-            << "</SourceLineNumber>" << std::endl;
+          xml.Element("SourceLineNumber", cm->LineNumber);
           }
         }
-      os << "\t\t<PreContext>" << cmXMLSafe(cm->PreContext).Quotes(false)
-         << "</PreContext>\n"
-         << "\t\t<PostContext>" << cmXMLSafe(cm->PostContext).Quotes(false);
+      xml.Element("PreContext", cm->PreContext);
+      xml.StartElement("PostContext");
+      xml.Content(cm->PostContext);
       // is this the last warning or error, if so notify
       if ((cm->Error && !numErrorsAllowed) ||
           (!cm->Error && !numWarningsAllowed))
         {
-        os << "\nThe maximum number of reported warnings or errors has been "
-          "reached!!!\n";
+        xml.Content("\nThe maximum number of reported warnings or errors "
+          "has been reached!!!\n");
         }
-      os << "</PostContext>\n"
-         << "\t\t<RepeatCount>0</RepeatCount>\n"
-         << "</" << (cm->Error ? "Error" : "Warning") << ">\n\n"
-         << std::endl;
+      xml.EndElement(); // PostContext
+      xml.Element("RepeatCount", "0");
+      xml.EndElement(); // "Error" / "Warning"
       }
     }
 }
 
 //----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLFooter(std::ostream& os,
+void cmCTestBuildHandler::GenerateXMLFooter(cmXMLWriter& xml,
                                             double elapsed_build_time)
 {
-  os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n"
-     << "\t<EndDateTime>" << this->EndBuild << "</EndDateTime>\n"
-     << "\t<EndBuildTime>" << static_cast<unsigned int>(this->EndBuildTime)
-     << "</EndBuildTime>\n"
-     << "<ElapsedMinutes>" << static_cast<int>(elapsed_build_time/6)/10.0
-     << "</ElapsedMinutes>"
-     << "</Build>" << std::endl;
-  this->CTest->EndXML(os);
-}
-
-//----------------------------------------------------------------------------
-void cmCTestBuildHandler::GenerateXMLLaunchedFragment(std::ostream& os,
-                                                      const char* fname)
-{
-  cmsys::ifstream fin(fname, std::ios::in | std::ios::binary);
-  std::string line;
-  while(cmSystemTools::GetLineFromStream(fin, line))
-    {
-    os << line << "\n";
-    }
+  xml.StartElement("Log");
+  xml.Attribute("Encoding", "base64");
+  xml.Attribute("Compression", "bin/gzip");
+  xml.EndElement(); // Log
+
+  xml.Element("EndDateTime", this->EndBuild);
+  xml.Element("EndBuildTime", static_cast<unsigned int>(this->EndBuildTime));
+  xml.Element("ElapsedMinutes", static_cast<int>(elapsed_build_time/6)/10.0);
+  xml.EndElement(); // Build
+  this->CTest->EndXML(xml);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index d13d5cf..2e9b92a 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -22,6 +22,7 @@
 #include <deque>
 
 class cmMakefile;
+class cmXMLWriter;
 
 /** \class cmCTestBuildHandler
  * \brief A class that handles ctest -S invocations
@@ -86,11 +87,10 @@ private:
   };
 
   // generate the XML output
-  void GenerateXMLHeader(std::ostream& os);
-  void GenerateXMLLaunched(std::ostream& os);
-  void GenerateXMLLogScraped(std::ostream& os);
-  void GenerateXMLFooter(std::ostream& os, double elapsed_build_time);
-  void GenerateXMLLaunchedFragment(std::ostream& os, const char* fname);
+  void GenerateXMLHeader(cmXMLWriter& xml);
+  void GenerateXMLLaunched(cmXMLWriter& xml);
+  void GenerateXMLLogScraped(cmXMLWriter& xml);
+  void GenerateXMLFooter(cmXMLWriter& xml, double elapsed_build_time);
   bool IsLaunchedErrorFile(const char* fname);
   bool IsLaunchedWarningFile(const char* fname);
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1dbd86fd6dee7fc330f613558d44f37937fd454b
commit 1dbd86fd6dee7fc330f613558d44f37937fd454b
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 20:32:33 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:21 2015 -0400

    cmCTestLaunch: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 6f43a1e..50639b0 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -13,7 +13,7 @@
 
 #include "cmGeneratedFileStream.h"
 #include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 #include "cmake.h"
 
 #include <cmsys/MD5.h>
@@ -407,35 +407,32 @@ void cmCTestLaunch::WriteXML()
 
   // Use cmGeneratedFileStream to atomically create the report file.
   cmGeneratedFileStream fxml(logXML.c_str());
-  fxml << "\t<Failure type=\""
-       << (this->IsError()? "Error" : "Warning") << "\">\n";
-  this->WriteXMLAction(fxml);
-  this->WriteXMLCommand(fxml);
-  this->WriteXMLResult(fxml);
-  this->WriteXMLLabels(fxml);
-  fxml << "\t</Failure>\n";
+  cmXMLWriter xml(fxml, 2);
+  xml.StartElement("Failure");
+  xml.Attribute("type", this->IsError() ? "Error" : "Warning");
+  this->WriteXMLAction(xml);
+  this->WriteXMLCommand(xml);
+  this->WriteXMLResult(xml);
+  this->WriteXMLLabels(xml);
+  xml.EndElement(); // Failure
 }
 
 //----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLAction(cmXMLWriter& xml)
 {
-  fxml << "\t\t<!-- Meta-information about the build action -->\n";
-  fxml << "\t\t<Action>\n";
+  xml.Comment("Meta-information about the build action");
+  xml.StartElement("Action");
 
   // TargetName
   if(!this->OptionTargetName.empty())
     {
-    fxml << "\t\t\t<TargetName>"
-         << cmXMLSafe(this->OptionTargetName)
-         << "</TargetName>\n";
+    xml.Element("TargetName", this->OptionTargetName);
     }
 
   // Language
   if(!this->OptionLanguage.empty())
     {
-    fxml << "\t\t\t<Language>"
-         << cmXMLSafe(this->OptionLanguage)
-         << "</Language>\n";
+    xml.Element("Language", this->OptionLanguage);
     }
 
   // SourceFile
@@ -454,17 +451,13 @@ void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
                                            source.c_str());
       }
 
-    fxml << "\t\t\t<SourceFile>"
-         << cmXMLSafe(source)
-         << "</SourceFile>\n";
+    xml.Element("SourceFile", source);
     }
 
   // OutputFile
   if(!this->OptionOutput.empty())
     {
-    fxml << "\t\t\t<OutputFile>"
-         << cmXMLSafe(this->OptionOutput)
-         << "</OutputFile>\n";
+    xml.Element("OutputFile", this->OptionOutput);
     }
 
   // OutputType
@@ -494,103 +487,94 @@ void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
     }
   if(outputType)
     {
-    fxml << "\t\t\t<OutputType>"
-         << cmXMLSafe(outputType)
-         << "</OutputType>\n";
+    xml.Element("OutputType", outputType);
     }
 
-  fxml << "\t\t</Action>\n";
+  xml.EndElement(); // Action
 }
 
 //----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLCommand(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLCommand(cmXMLWriter& xml)
 {
-  fxml << "\n";
-  fxml << "\t\t<!-- Details of command -->\n";
-  fxml << "\t\t<Command>\n";
+  xml.Comment("Details of command");
+  xml.StartElement("Command");
   if(!this->CWD.empty())
     {
-    fxml << "\t\t\t<WorkingDirectory>"
-         << cmXMLSafe(this->CWD)
-         << "</WorkingDirectory>\n";
+    xml.Element("WorkingDirectory", this->CWD);
     }
   for(std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
       ai != this->RealArgs.end(); ++ai)
     {
-    fxml << "\t\t\t<Argument>"
-         << cmXMLSafe(ai->c_str())
-         << "</Argument>\n";
+    xml.Element("Argument", *ai);
     }
-  fxml << "\t\t</Command>\n";
+  xml.EndElement(); // Command
 }
 
 //----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLResult(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLResult(cmXMLWriter& xml)
 {
-  fxml << "\n";
-  fxml << "\t\t<!-- Result of command -->\n";
-  fxml << "\t\t<Result>\n";
+  xml.Comment("Result of command");
+  xml.StartElement("Result");
 
   // StdOut
-  fxml << "\t\t\t<StdOut>";
-  this->DumpFileToXML(fxml, this->LogOut);
-  fxml << "</StdOut>\n";
+  xml.StartElement("StdOut");
+  this->DumpFileToXML(xml, this->LogOut);
+  xml.EndElement(); // StdOut
 
   // StdErr
-  fxml << "\t\t\t<StdErr>";
-  this->DumpFileToXML(fxml, this->LogErr);
-  fxml << "</StdErr>\n";
+  xml.StartElement("StdErr");
+  this->DumpFileToXML(xml, this->LogErr);
+  xml.EndElement(); // StdErr
 
   // ExitCondition
-  fxml << "\t\t\t<ExitCondition>";
+  xml.StartElement("ExitCondition");
   cmsysProcess* cp = this->Process;
   switch (cmsysProcess_GetState(cp))
     {
     case cmsysProcess_State_Starting:
-      fxml << "No process has been executed"; break;
+      xml.Content("No process has been executed"); break;
     case cmsysProcess_State_Executing:
-      fxml << "The process is still executing"; break;
+      xml.Content("The process is still executing"); break;
     case cmsysProcess_State_Disowned:
-      fxml << "Disowned"; break;
+      xml.Content("Disowned"); break;
     case cmsysProcess_State_Killed:
-      fxml << "Killed by parent"; break;
+      xml.Content("Killed by parent"); break;
 
     case cmsysProcess_State_Expired:
-      fxml << "Killed when timeout expired"; break;
+      xml.Content("Killed when timeout expired"); break;
     case cmsysProcess_State_Exited:
-      fxml << this->ExitCode; break;
+      xml.Content(this->ExitCode); break;
     case cmsysProcess_State_Exception:
-      fxml << "Terminated abnormally: "
-           << cmXMLSafe(cmsysProcess_GetExceptionString(cp)); break;
+      xml.Content("Terminated abnormally: ");
+      xml.Content(cmsysProcess_GetExceptionString(cp)); break;
     case cmsysProcess_State_Error:
-      fxml << "Error administrating child process: "
-           << cmXMLSafe(cmsysProcess_GetErrorString(cp)); break;
+      xml.Content("Error administrating child process: ");
+      xml.Content(cmsysProcess_GetErrorString(cp)); break;
     };
-  fxml << "</ExitCondition>\n";
+  xml.EndElement(); // ExitCondition
 
-  fxml << "\t\t</Result>\n";
+  xml.EndElement(); // Result
 }
 
 //----------------------------------------------------------------------------
-void cmCTestLaunch::WriteXMLLabels(std::ostream& fxml)
+void cmCTestLaunch::WriteXMLLabels(cmXMLWriter& xml)
 {
   this->LoadLabels();
   if(!this->Labels.empty())
     {
-    fxml << "\n";
-    fxml << "\t\t<!-- Interested parties -->\n";
-    fxml << "\t\t<Labels>\n";
+    xml.Comment("Interested parties");
+    xml.StartElement("Labels");
     for(std::set<std::string>::const_iterator li = this->Labels.begin();
         li != this->Labels.end(); ++li)
       {
-      fxml << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n";
+      xml.Element("Label", *li);
       }
-    fxml << "\t\t</Labels>\n";
+    xml.EndElement(); // Labels
     }
 }
 
 //----------------------------------------------------------------------------
-void cmCTestLaunch::DumpFileToXML(std::ostream& fxml,
+void cmCTestLaunch::DumpFileToXML(cmXMLWriter& xml,
                                   std::string const& fname)
 {
   cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
@@ -605,7 +589,8 @@ void cmCTestLaunch::DumpFileToXML(std::ostream& fxml,
       continue;
       }
 
-    fxml << sep << cmXMLSafe(line).Quotes(false);
+    xml.Content(sep);
+    xml.Content(line);
     sep = "\n";
     }
 }
diff --git a/Source/CTest/cmCTestLaunch.h b/Source/CTest/cmCTestLaunch.h
index bc90d28..b13e484 100644
--- a/Source/CTest/cmCTestLaunch.h
+++ b/Source/CTest/cmCTestLaunch.h
@@ -15,6 +15,8 @@
 #include "cmStandardIncludes.h"
 #include <cmsys/RegularExpression.hxx>
 
+class cmXMLWriter;
+
 /** \class cmCTestLaunch
  * \brief Launcher for make rules to report results for ctest
  *
@@ -92,11 +94,11 @@ private:
 
   // Methods to generate the xml fragment.
   void WriteXML();
-  void WriteXMLAction(std::ostream& fxml);
-  void WriteXMLCommand(std::ostream& fxml);
-  void WriteXMLResult(std::ostream& fxml);
-  void WriteXMLLabels(std::ostream& fxml);
-  void DumpFileToXML(std::ostream& fxml, std::string const& fname);
+  void WriteXMLAction(cmXMLWriter& xml);
+  void WriteXMLCommand(cmXMLWriter& xml);
+  void WriteXMLResult(cmXMLWriter& xml);
+  void WriteXMLLabels(cmXMLWriter& xml);
+  void DumpFileToXML(cmXMLWriter& xml, std::string const& fname);
 
   // Configuration
   void LoadConfig();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a53bd63e0cb84fafeadb801437c5acde9298c3e7
commit a53bd63e0cb84fafeadb801437c5acde9298c3e7
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 00:08:35 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:21 2015 -0400

    cmCTest: Port GenerateNotesFile to cmXMLWriter

diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 48a7ec7..16edd1f 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -1719,54 +1719,56 @@ void cmCTest::EndXML(cmXMLWriter& xml)
 }
 
 //----------------------------------------------------------------------
-int cmCTest::GenerateCTestNotesOutput(std::ostream& os,
+int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml,
   const cmCTest::VectorOfStrings& files)
 {
   std::string buildname = cmCTest::SafeBuildIdField(
     this->GetCTestConfiguration("BuildName"));
   cmCTest::VectorOfStrings::const_iterator it;
-  os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-     << "<?xml-stylesheet type=\"text/xsl\" "
+  xml.StartDocument();
+  xml.ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" "
     "href=\"Dart/Source/Server/XSL/Build.xsl "
-    "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
-     << "<Site BuildName=\"" << buildname
-     << "\" BuildStamp=\""
-     << this->CurrentTag << "-" << this->GetTestModelString() << "\" Name=\""
-     << this->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
-     << cmVersion::GetCMakeVersion()
-     << "\">\n";
-  this->AddSiteProperties(os);
-  os << "<Notes>" << std::endl;
+    "<file:///Dart/Source/Server/XSL/Build.xsl> \"");
+  xml.StartElement("Site");
+  xml.Attribute("BuildName", buildname);
+  xml.Attribute("BuildStamp", this->CurrentTag+"-"+this->GetTestModelString());
+  xml.Attribute("Name", this->GetCTestConfiguration("Site"));
+  xml.Attribute("Generator",std::string("ctest")+cmVersion::GetCMakeVersion());
+  this->AddSiteProperties(xml);
+  xml.StartElement("Notes");
 
   for ( it = files.begin(); it != files.end(); it ++ )
     {
     cmCTestLog(this, OUTPUT, "\tAdd file: " << *it << std::endl);
     std::string note_time = this->CurrentTime();
-    os << "<Note Name=\"" << cmXMLSafe(*it) << "\">\n"
-      << "<Time>" << cmSystemTools::GetTime() << "</Time>\n"
-      << "<DateTime>" << note_time << "</DateTime>\n"
-      << "<Text>" << std::endl;
+    xml.StartElement("Note");
+    xml.Attribute("Name", *it);
+    xml.Element("Time", cmSystemTools::GetTime());
+    xml.Element("DateTime", note_time);
+    xml.StartElement("Text");
     cmsys::ifstream ifs(it->c_str());
     if ( ifs )
       {
       std::string line;
       while ( cmSystemTools::GetLineFromStream(ifs, line) )
         {
-        os << cmXMLSafe(line) << std::endl;
+        xml.Content(line);
+        xml.Content("\n");
         }
       ifs.close();
       }
     else
       {
-      os << "Problem reading file: " << *it << std::endl;
+      xml.Content("Problem reading file: " + *it + "\n");
       cmCTestLog(this, ERROR_MESSAGE, "Problem reading file: " << *it
         << " while creating notes" << std::endl);
       }
-    os << "</Text>\n"
-      << "</Note>" << std::endl;
+    xml.EndElement(); // Text
+    xml.EndElement(); // Note
     }
-  os << "</Notes>\n"
-    << "</Site>" << std::endl;
+  xml.EndElement(); // Notes
+  xml.EndElement(); // Site
+  xml.EndDocument();
   return 1;
 }
 
@@ -1779,8 +1781,8 @@ int cmCTest::GenerateNotesFile(const VectorOfStrings &files)
     cmCTestLog(this, ERROR_MESSAGE, "Cannot open notes file" << std::endl);
     return 1;
     }
-
-  this->GenerateCTestNotesOutput(ofs, files);
+  cmXMLWriter xml(ofs);
+  this->GenerateCTestNotesOutput(xml, files);
   return 0;
 }
 
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 47c337a..7153e8f 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -557,7 +557,7 @@ private:
   bool UpdateCTestConfiguration();
 
   //! Create note from files.
-  int GenerateCTestNotesOutput(std::ostream& os,
+  int GenerateCTestNotesOutput(cmXMLWriter& xml,
     const VectorOfStrings& files);
 
   //! Check if the argument is the one specified

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9c0bb7d8070039cfa3f5b944f90308e0283c4ce3
commit 9c0bb7d8070039cfa3f5b944f90308e0283c4ce3
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sat May 23 23:41:09 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:21 2015 -0400

    cmCTestConfigureHandler: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index 2c2951d..2e8aeb9 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -15,7 +15,7 @@
 #include "cmCTest.h"
 #include "cmGeneratedFileStream.h"
 #include "cmake.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 #include <cmsys/Process.h>
 
 
@@ -89,28 +89,22 @@ int cmCTestConfigureHandler::ProcessHandler()
 
     if ( os )
       {
-      this->CTest->StartXML(os, this->AppendXML);
-      os << "<Configure>\n"
-         << "\t<StartDateTime>" << start_time << "</StartDateTime>"
-         << std::endl
-         << "\t<StartConfigureTime>" << start_time_time
-         << "</StartConfigureTime>\n";
-      os << "<ConfigureCommand>" << cCommand << "</ConfigureCommand>"
-        << std::endl;
+      cmXMLWriter xml(os);
+      this->CTest->StartXML(xml, this->AppendXML);
+      xml.StartElement("Configure");
+      xml.Element("StartDateTime", start_time);
+      xml.Element("StartConfigureTime", start_time_time);
+      xml.Element("ConfigureCommand", cCommand);
       cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet);
-      os << "<Log>" << cmXMLSafe(output) << "</Log>" << std::endl;
-      std::string end_time = this->CTest->CurrentTime();
-      os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n"
-         << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
-         << "\t<EndConfigureTime>" <<
-        static_cast<unsigned int>(cmSystemTools::GetTime())
-         << "</EndConfigureTime>\n"
-         << "<ElapsedMinutes>"
-         << static_cast<int>(
-           (cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
-         << "</ElapsedMinutes>"
-         << "</Configure>" << std::endl;
-      this->CTest->EndXML(os);
+      xml.Element("Log", output);
+      xml.Element("ConfigureStatus", retVal);
+      xml.Element("EndDateTime", this->CTest->CurrentTime());
+      xml.Element("EndConfigureTime",
+        static_cast<unsigned int>(cmSystemTools::GetTime()));
+      xml.Element("ElapsedMinutes", static_cast<int>(
+        (cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+      xml.EndElement(); // Configure
+      this->CTest->EndXML(xml);
       }
     }
   else

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6cf5cc717f522bcd9e8286a864068d09012dad41
commit 6cf5cc717f522bcd9e8286a864068d09012dad41
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sat May 23 23:31:20 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:21 2015 -0400

    cmCTestUploadHandler: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
index 579190a..5c6b229 100644
--- a/Source/CTest/cmCTestUploadHandler.cxx
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -13,7 +13,7 @@
 
 #include "cmGeneratedFileStream.h"
 #include "cmVersion.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 //----------------------------------------------------------------------------
 cmCTestUploadHandler::cmCTestUploadHandler()
@@ -47,32 +47,36 @@ int cmCTestUploadHandler::ProcessHandler()
   std::string buildname = cmCTest::SafeBuildIdField(
     this->CTest->GetCTestConfiguration("BuildName"));
   cmCTest::SetOfStrings::const_iterator it;
-  ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-     << "<?xml-stylesheet type=\"text/xsl\" "
+
+  cmXMLWriter xml(ofs);
+  xml.StartDocument();
+  xml.ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" "
     "href=\"Dart/Source/Server/XSL/Build.xsl "
-    "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
-     << "<Site BuildName=\""
-     << buildname
-     << "\" BuildStamp=\""
-     << this->CTest->GetCurrentTag() << "-"
-     << this->CTest->GetTestModelString() << "\" Name=\""
-     << this->CTest->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
-     << cmVersion::GetCMakeVersion()
-     << "\">\n";
-  this->CTest->AddSiteProperties(ofs);
-  ofs << "<Upload>\n";
+    "<file:///Dart/Source/Server/XSL/Build.xsl> \"");
+  xml.StartElement("Site");
+  xml.Attribute("BuildName", buildname);
+  xml.Attribute("BuildStamp",
+    this->CTest->GetCurrentTag() + "-" + this->CTest->GetTestModelString());
+  xml.Attribute("Name", this->CTest->GetCTestConfiguration("Site"));
+  xml.Attribute("Generator",
+    std::string("ctest") + cmVersion::GetCMakeVersion());
+  this->CTest->AddSiteProperties(xml);
+  xml.StartElement("Upload");
 
   for ( it = this->Files.begin(); it != this->Files.end(); it ++ )
     {
     cmCTestOptionalLog(this->CTest, OUTPUT,
       "\tUpload file: " << *it << std::endl, this->Quiet);
-    ofs << "<File filename=\"" << cmXMLSafe(*it) << "\">\n"
-       << "<Content encoding=\"base64\">\n";
-    ofs << this->CTest->Base64EncodeFile(*it);
-    ofs << "\n</Content>\n"
-      << "</File>\n";
+    xml.StartElement("File");
+    xml.Attribute("filename", *it);
+    xml.StartElement("Content");
+    xml.Attribute("encoding", "base64");
+    xml.Content(this->CTest->Base64EncodeFile(*it));
+    xml.EndElement(); // Content
+    xml.EndElement(); // File
     }
-  ofs << "</Upload>\n"
-    << "</Site>\n";
+  xml.EndElement(); // Upload
+  xml.EndElement(); // Site
+  xml.EndDocument();
   return 0;
 }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed42c203ed4b258091bd6eeaa1fe567c6f9b120a
commit ed42c203ed4b258091bd6eeaa1fe567c6f9b120a
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 00:33:24 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:21 2015 -0400

    cmCTestUpdateHandler: Port to cmXMLWriter

diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index ab363d0..0fb3fec 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -13,7 +13,7 @@
 
 #include "cmCTest.h"
 #include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 #include <cmsys/RegularExpression.hxx>
 #include <cmsys/FStream.hxx>
@@ -266,13 +266,13 @@ void cmCTestCVS::LoadRevisions(std::string const& file,
 }
 
 //----------------------------------------------------------------------------
-void cmCTestCVS::WriteXMLDirectory(std::ostream& xml,
+void cmCTestCVS::WriteXMLDirectory(cmXMLWriter& xml,
                                    std::string const& path,
                                    Directory const& dir)
 {
   const char* slash = path.empty()? "":"/";
-  xml << "\t<Directory>\n"
-      << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";
+  xml.StartElement("Directory");
+  xml.Element("Name", path);
 
   // Lookup the branch checked out in the working tree.
   std::string branchFlag = this->ComputeBranchFlag(path);
@@ -298,11 +298,11 @@ void cmCTestCVS::WriteXMLDirectory(std::ostream& xml,
     File f(fi->second, &revisions[0], &revisions[1]);
     this->WriteXMLEntry(xml, path, fi->first, full, f);
     }
-  xml << "\t</Directory>\n";
+  xml.EndElement(); // Directory
 }
 
 //----------------------------------------------------------------------------
-bool cmCTestCVS::WriteXMLUpdates(std::ostream& xml)
+bool cmCTestCVS::WriteXMLUpdates(cmXMLWriter& xml)
 {
   cmCTestLog(this->CTest, HANDLER_OUTPUT,
              "   Gathering version information (one . per updated file):\n"
diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h
index 64e1747..f2c0a73 100644
--- a/Source/CTest/cmCTestCVS.h
+++ b/Source/CTest/cmCTestCVS.h
@@ -29,7 +29,7 @@ public:
 private:
   // Implement cmCTestVC internal API.
   virtual bool UpdateImpl();
-  virtual bool WriteXMLUpdates(std::ostream& xml);
+  virtual bool WriteXMLUpdates(cmXMLWriter& xml);
 
   // Update status for files in each directory.
   class Directory: public std::map<std::string, PathStatus> {};
@@ -38,7 +38,7 @@ private:
   std::string ComputeBranchFlag(std::string const& dir);
   void LoadRevisions(std::string const& file, const char* branchFlag,
                      std::vector<Revision>& revisions);
-  void WriteXMLDirectory(std::ostream& xml, std::string const& path,
+  void WriteXMLDirectory(cmXMLWriter& xml, std::string const& path,
                          Directory const& dir);
 
   // Parsing helper classes.
diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx
index 5f570b5..c091ec4 100644
--- a/Source/CTest/cmCTestGlobalVC.cxx
+++ b/Source/CTest/cmCTestGlobalVC.cxx
@@ -13,7 +13,7 @@
 
 #include "cmCTest.h"
 #include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 #include <cmsys/RegularExpression.hxx>
 
@@ -91,36 +91,36 @@ void cmCTestGlobalVC::DoModification(PathStatus status,
 }
 
 //----------------------------------------------------------------------------
-void cmCTestGlobalVC::WriteXMLDirectory(std::ostream& xml,
+void cmCTestGlobalVC::WriteXMLDirectory(cmXMLWriter& xml,
                                         std::string const& path,
                                         Directory const& dir)
 {
   const char* slash = path.empty()? "":"/";
-  xml << "\t<Directory>\n"
-      << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";
+  xml.StartElement("Directory");
+  xml.Element("Name", path);
   for(Directory::const_iterator fi = dir.begin(); fi != dir.end(); ++fi)
     {
     std::string full = path + slash + fi->first;
     this->WriteXMLEntry(xml, path, fi->first, full, fi->second);
     }
-  xml << "\t</Directory>\n";
+  xml.EndElement(); // Directory
 }
 
 //----------------------------------------------------------------------------
-void cmCTestGlobalVC::WriteXMLGlobal(std::ostream& xml)
+void cmCTestGlobalVC::WriteXMLGlobal(cmXMLWriter& xml)
 {
   if(!this->NewRevision.empty())
     {
-    xml << "\t<Revision>" << this->NewRevision << "</Revision>\n";
+    xml.Element("Revision", this->NewRevision);
     }
   if(!this->OldRevision.empty() && this->OldRevision != this->NewRevision)
     {
-    xml << "\t<PriorRevision>" << this->OldRevision << "</PriorRevision>\n";
+    xml.Element("PriorRevision", this->OldRevision);
     }
 }
 
 //----------------------------------------------------------------------------
-bool cmCTestGlobalVC::WriteXMLUpdates(std::ostream& xml)
+bool cmCTestGlobalVC::WriteXMLUpdates(cmXMLWriter& xml)
 {
   cmCTestLog(this->CTest, HANDLER_OUTPUT,
              "   Gathering version information (one . per revision):\n"
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
index 29e0a61..d0e9410 100644
--- a/Source/CTest/cmCTestGlobalVC.h
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -30,7 +30,7 @@ public:
 
 protected:
   // Implement cmCTestVC internal API.
-  virtual bool WriteXMLUpdates(std::ostream& xml);
+  virtual bool WriteXMLUpdates(cmXMLWriter& xml);
 
   /** Represent a vcs-reported action for one path in a revision.  */
   struct Change
@@ -62,8 +62,8 @@ protected:
   virtual void LoadModifications() = 0;
   virtual void LoadRevisions() = 0;
 
-  virtual void WriteXMLGlobal(std::ostream& xml);
-  void WriteXMLDirectory(std::ostream& xml, std::string const& path,
+  virtual void WriteXMLGlobal(cmXMLWriter& xml);
+  void WriteXMLDirectory(cmXMLWriter& xml, std::string const& path,
                          Directory const& dir);
 };
 
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 86dc2f2..f7bd1f9 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -14,7 +14,7 @@
 #include "cmCTest.h"
 #include "cmSystemTools.h"
 #include "cmXMLParser.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 #include <cmsys/RegularExpression.hxx>
 
@@ -535,11 +535,11 @@ void cmCTestSVN::LoadModifications()
 }
 
 //----------------------------------------------------------------------------
-void cmCTestSVN::WriteXMLGlobal(std::ostream& xml)
+void cmCTestSVN::WriteXMLGlobal(cmXMLWriter& xml)
 {
   this->cmCTestGlobalVC::WriteXMLGlobal(xml);
 
-  xml << "\t<SVNPath>" << this->RootInfo->Base << "</SVNPath>\n";
+  xml.Element("SVNPath", this->RootInfo->Base);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 17bf7cb..f9febc5 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -84,7 +84,7 @@ private:
   void DoRevisionSVN(Revision const& revision,
                      std::vector<Change> const& changes);
 
-  void WriteXMLGlobal(std::ostream& xml);
+  void WriteXMLGlobal(cmXMLWriter& xml);
 
   // Parsing helper classes.
   class InfoParser;
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index 10927e7..8494d28 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -20,7 +20,7 @@
 #include "cmVersion.h"
 #include "cmGeneratedFileStream.h"
 #include "cmXMLParser.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 #include "cmCLocaleEnvironmentScope.h"
 
 #include "cmCTestVC.h"
@@ -224,24 +224,24 @@ int cmCTestUpdateHandler::ProcessHandler()
   bool updated = vc->Update();
   std::string buildname = cmCTest::SafeBuildIdField(
     this->CTest->GetCTestConfiguration("BuildName"));
-  os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-    << "<Update mode=\"Client\" Generator=\"ctest-"
-    << cmVersion::GetCMakeVersion() << "\">\n"
-    << "\t<Site>" << this->CTest->GetCTestConfiguration("Site") << "</Site>\n"
-    << "\t<BuildName>" << buildname
-    << "</BuildName>\n"
-    << "\t<BuildStamp>" << this->CTest->GetCurrentTag() << "-"
-    << this->CTest->GetTestModelString() << "</BuildStamp>" << std::endl;
-  os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n"
-    << "\t<StartTime>" << start_time_time << "</StartTime>\n"
-    << "\t<UpdateCommand>"
-     << cmXMLSafe(vc->GetUpdateCommandLine()).Quotes(false)
-    << "</UpdateCommand>\n"
-    << "\t<UpdateType>" << cmXMLSafe(
-      cmCTestUpdateHandlerUpdateToString(this->UpdateType))
-    << "</UpdateType>\n";
-
-  vc->WriteXML(os);
+
+  cmXMLWriter xml(os);
+  xml.StartDocument();
+  xml.StartElement("Update");
+  xml.Attribute("mode", "Client");
+  xml.Attribute("Generator",
+    std::string("ctest-") + cmVersion::GetCMakeVersion());
+  xml.Element("Site", this->CTest->GetCTestConfiguration("Site"));
+  xml.Element("BuildName", buildname);
+  xml.Element("BuildStamp", this->CTest->GetCurrentTag() + "-" +
+    this->CTest->GetTestModelString());
+  xml.Element("StartDateTime", start_time);
+  xml.Element("StartTime", start_time_time);
+  xml.Element("UpdateCommand", vc->GetUpdateCommandLine());
+  xml.Element("UpdateType",
+    cmCTestUpdateHandlerUpdateToString(this->UpdateType));
+
+  vc->WriteXML(xml);
 
   int localModifications = 0;
   int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
@@ -265,29 +265,30 @@ int cmCTestUpdateHandler::ProcessHandler()
 
   cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet);
   std::string end_time = this->CTest->CurrentTime();
-  os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
-     << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime())
-     << "</EndTime>\n"
-    << "<ElapsedMinutes>" <<
-    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
-    << "</ElapsedMinutes>\n"
-    << "\t<UpdateReturnStatus>";
+  xml.Element("EndDateTime", end_time);
+  xml.Element("EndTime", static_cast<unsigned int>(cmSystemTools::GetTime()));
+  xml.Element("ElapsedMinutes",
+    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0);
+
+  xml.StartElement("UpdateReturnStatus");
   if(localModifications)
     {
-    os << "Update error: There are modified or conflicting files in the "
-      "repository";
+    xml.Content("Update error: "
+      "There are modified or conflicting files in the repository");
     cmCTestLog(this->CTest, ERROR_MESSAGE,
       "   There are modified or conflicting files in the repository"
       << std::endl);
     }
   if(!updated)
     {
-    os << "Update command failed:\n" << vc->GetUpdateCommandLine();
+    xml.Content("Update command failed:\n");
+    xml.Content(vc->GetUpdateCommandLine());
     cmCTestLog(this->CTest, ERROR_MESSAGE, "   Update command failed: "
                << vc->GetUpdateCommandLine() << "\n");
     }
-  os << "</UpdateReturnStatus>" << std::endl;
-  os << "</Update>" << std::endl;
+  xml.EndElement(); // UpdateReturnStatus
+  xml.EndElement(); // Update
+  xml.EndDocument();
   return numUpdated;
 }
 
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 6e93e95..8eff4d6 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -13,7 +13,7 @@
 
 #include "cmCTest.h"
 #include "cmSystemTools.h"
-#include "cmXMLSafe.h"
+#include "cmXMLWriter.h"
 
 #include <cmsys/Process.h>
 
@@ -202,7 +202,7 @@ bool cmCTestVC::UpdateImpl()
 }
 
 //----------------------------------------------------------------------------
-bool cmCTestVC::WriteXML(std::ostream& xml)
+bool cmCTestVC::WriteXML(cmXMLWriter& xml)
 {
   this->Log << "--- Begin Revisions ---\n";
   bool result = this->WriteXMLUpdates(xml);
@@ -211,7 +211,7 @@ bool cmCTestVC::WriteXML(std::ostream& xml)
 }
 
 //----------------------------------------------------------------------------
-bool cmCTestVC::WriteXMLUpdates(std::ostream&)
+bool cmCTestVC::WriteXMLUpdates(cmXMLWriter&)
 {
   cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
              "* CTest cannot extract updates for this VCS tool.\n");
@@ -219,7 +219,7 @@ bool cmCTestVC::WriteXMLUpdates(std::ostream&)
 }
 
 //----------------------------------------------------------------------------
-void cmCTestVC::WriteXMLEntry(std::ostream& xml,
+void cmCTestVC::WriteXMLEntry(cmXMLWriter& xml,
                               std::string const& path,
                               std::string const& name,
                               std::string const& full,
@@ -228,21 +228,19 @@ void cmCTestVC::WriteXMLEntry(std::ostream& xml,
   static const char* desc[3] = { "Updated", "Modified", "Conflicting"};
   Revision const& rev = f.Rev? *f.Rev : this->Unknown;
   std::string prior = f.PriorRev? f.PriorRev->Rev : std::string("Unknown");
-  xml << "\t\t<" << desc[f.Status] << ">\n"
-      << "\t\t\t<File>" << cmXMLSafe(name) << "</File>\n"
-      << "\t\t\t<Directory>" << cmXMLSafe(path) << "</Directory>\n"
-      << "\t\t\t<FullName>" << cmXMLSafe(full) << "</FullName>\n"
-      << "\t\t\t<CheckinDate>" << cmXMLSafe(rev.Date) << "</CheckinDate>\n"
-      << "\t\t\t<Author>" << cmXMLSafe(rev.Author) << "</Author>\n"
-      << "\t\t\t<Email>" << cmXMLSafe(rev.EMail) << "</Email>\n"
-      << "\t\t\t<Committer>" << cmXMLSafe(rev.Committer) << "</Committer>\n"
-      << "\t\t\t<CommitterEmail>" << cmXMLSafe(rev.CommitterEMail)
-      << "</CommitterEmail>\n"
-      << "\t\t\t<CommitDate>" << cmXMLSafe(rev.CommitDate)
-      << "</CommitDate>\n"
-      << "\t\t\t<Log>" << cmXMLSafe(rev.Log) << "</Log>\n"
-      << "\t\t\t<Revision>" << cmXMLSafe(rev.Rev) << "</Revision>\n"
-      << "\t\t\t<PriorRevision>" << cmXMLSafe(prior) << "</PriorRevision>\n"
-      << "\t\t</" << desc[f.Status] << ">\n";
+  xml.StartElement(desc[f.Status]);
+  xml.Element("File", name);
+  xml.Element("Directory", path);
+  xml.Element("FullName", full);
+  xml.Element("CheckinDate", rev.Date);
+  xml.Element("Author", rev.Author);
+  xml.Element("Email", rev.EMail);
+  xml.Element("Committer", rev.Committer);
+  xml.Element("CommitterEmail", rev.CommitterEMail);
+  xml.Element("CommitDate", rev.CommitDate);
+  xml.Element("Log", rev.Log);
+  xml.Element("Revision", rev.Rev);
+  xml.Element("PriorRevision", prior);
+  xml.EndElement();
   ++this->PathCount[f.Status];
 }
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 9dd0651..bc89302 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -15,6 +15,7 @@
 #include "cmProcessTools.h"
 
 class cmCTest;
+class cmXMLWriter;
 
 /** \class cmCTestVC
  * \brief Base class for version control system handlers
@@ -51,7 +52,7 @@ public:
     { return this->UpdateCommandLine; }
 
   /** Write Update.xml entries for the updates found.  */
-  bool WriteXML(std::ostream& xml);
+  bool WriteXML(cmXMLWriter& xml);
 
   /** Enumerate non-trivial working tree states during update.  */
   enum PathStatus { PathUpdated, PathModified, PathConflicting };
@@ -65,7 +66,7 @@ protected:
   virtual void NoteOldRevision();
   virtual bool UpdateImpl();
   virtual void NoteNewRevision();
-  virtual bool WriteXMLUpdates(std::ostream& xml);
+  virtual bool WriteXMLUpdates(cmXMLWriter& xml);
 
 #if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x510
 public: // Sun CC 5.1 needs help to allow cmCTestSVN::Revision to see this
@@ -110,7 +111,7 @@ protected:
                         OutputParser* out, OutputParser* err = 0);
 
   /** Write xml element for one file.  */
-  void WriteXMLEntry(std::ostream& xml, std::string const& path,
+  void WriteXMLEntry(cmXMLWriter& xml, std::string const& path,
                      std::string const& name, std::string const& full,
                      File const& f);
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=18825bafd99c6a9c8ec1fb4e7b22a8059c680572
commit 18825bafd99c6a9c8ec1fb4e7b22a8059c680572
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sun May 24 00:00:16 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:20 2015 -0400

    cmCTest: Port to cmXMLWriter
    
    Re-implement StartXML, EndXML, and AddSiteProperties using cmXMLWriter.
    Leave the old overloads behind for use by CTest/* until they are ported.

diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 211c83c..48a7ec7 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -28,6 +28,7 @@
 #include "cmCTestStartCommand.h"
 #include "cmAlgorithms.h"
 #include "cmState.h"
+#include "cmXMLWriter.h"
 
 #include "cmCTestBuildHandler.h"
 #include "cmCTestBuildAndTestHandler.h"
@@ -1548,6 +1549,67 @@ void cmCTest::StartXML(std::ostream& ostr, bool append)
 }
 
 //----------------------------------------------------------------------
+void cmCTest::StartXML(cmXMLWriter& xml, bool append)
+{
+  if(this->CurrentTag.empty())
+    {
+    cmCTestLog(this, ERROR_MESSAGE,
+               "Current Tag empty, this may mean"
+               " NightlStartTime was not set correctly." << std::endl);
+    cmSystemTools::SetFatalErrorOccured();
+    }
+
+  // find out about the system
+  cmsys::SystemInformation info;
+  info.RunCPUCheck();
+  info.RunOSCheck();
+  info.RunMemoryCheck();
+
+  std::string buildname = cmCTest::SafeBuildIdField(
+    this->GetCTestConfiguration("BuildName"));
+  std::string stamp = cmCTest::SafeBuildIdField(
+    this->CurrentTag + "-" + this->GetTestModelString());
+  std::string site = cmCTest::SafeBuildIdField(
+    this->GetCTestConfiguration("Site"));
+
+  xml.StartDocument();
+  xml.StartElement("Site");
+  xml.Attribute("BuildName", buildname);
+  xml.BreakAttributes();
+  xml.Attribute("BuildStamp", stamp);
+  xml.Attribute("Name", site);
+  xml.Attribute("Generator",
+                     std::string("ctest-") + cmVersion::GetCMakeVersion());
+  if(append)
+    {
+    xml.Attribute("Append", "true");
+    }
+  xml.Attribute("CompilerName", this->GetCTestConfiguration("Compiler"));
+#ifdef _COMPILER_VERSION
+  xml.Attribute("CompilerVersion", _COMPILER_VERSION);
+#endif
+  xml.Attribute("OSName", info.GetOSName());
+  xml.Attribute("Hostname", info.GetHostname());
+  xml.Attribute("OSRelease", info.GetOSRelease());
+  xml.Attribute("OSVersion", info.GetOSVersion());
+  xml.Attribute("OSPlatform", info.GetOSPlatform());
+  xml.Attribute("Is64Bits", info.Is64Bits());
+  xml.Attribute("VendorString", info.GetVendorString());
+  xml.Attribute("VendorID", info.GetVendorID());
+  xml.Attribute("FamilyID", info.GetFamilyID());
+  xml.Attribute("ModelID", info.GetModelID());
+  xml.Attribute("ProcessorCacheSize", info.GetProcessorCacheSize());
+  xml.Attribute("NumberOfLogicalCPU", info.GetNumberOfLogicalCPU());
+  xml.Attribute("NumberOfPhysicalCPU", info.GetNumberOfPhysicalCPU());
+  xml.Attribute("TotalVirtualMemory", info.GetTotalVirtualMemory());
+  xml.Attribute("TotalPhysicalMemory", info.GetTotalPhysicalMemory());
+  xml.Attribute("LogicalProcessorsPerPhysical",
+                     info.GetLogicalProcessorsPerPhysical());
+  xml.Attribute("ProcessorClockFrequency", info.GetProcessorClockFrequency());
+  this->AddSiteProperties(xml);
+}
+
+//----------------------------------------------------------------------
 void cmCTest::AddSiteProperties(std::ostream& ostr)
 {
   cmCTestScriptHandler* ch =
@@ -1594,6 +1656,54 @@ void cmCTest::AddSiteProperties(std::ostream& ostr)
     }
 }
 
+//----------------------------------------------------------------------
+void cmCTest::AddSiteProperties(cmXMLWriter& xml)
+{
+  cmCTestScriptHandler* ch =
+    static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+  cmake* cm =  ch->GetCMake();
+  // if no CMake then this is the old style script and props like
+  // this will not work anyway.
+  if(!cm)
+    {
+    return;
+    }
+  // This code should go when cdash is changed to use labels only
+  const char* subproject = cm->GetState()
+                             ->GetGlobalProperty("SubProject");
+  if(subproject)
+    {
+    xml.StartElement("Subproject");
+    xml.Attribute("name", subproject);
+    const char* labels =
+      ch->GetCMake()->GetState()
+                    ->GetGlobalProperty("SubProjectLabels");
+    if(labels)
+      {
+      xml.StartElement("Labels");
+      std::string l = labels;
+      std::vector<std::string> args;
+      cmSystemTools::ExpandListArgument(l, args);
+      for(std::vector<std::string>::iterator i = args.begin();
+          i != args.end(); ++i)
+        {
+        xml.Element("Label", *i);
+        }
+      xml.EndElement();
+      }
+    xml.EndElement();
+    }
+
+  // This code should stay when cdash only does label based sub-projects
+  const char* label = cm->GetState()->GetGlobalProperty("Label");
+  if(label)
+    {
+    xml.StartElement("Labels");
+    xml.Element("Label", label);
+    xml.EndElement();
+    }
+}
+
 
 //----------------------------------------------------------------------
 void cmCTest::EndXML(std::ostream& ostr)
@@ -1602,6 +1712,13 @@ void cmCTest::EndXML(std::ostream& ostr)
 }
 
 //----------------------------------------------------------------------
+void cmCTest::EndXML(cmXMLWriter& xml)
+{
+  xml.EndElement(); // Site
+  xml.EndDocument();
+}
+
+//----------------------------------------------------------------------
 int cmCTest::GenerateCTestNotesOutput(std::ostream& os,
   const cmCTest::VectorOfStrings& files)
 {
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 3f033d9..47c337a 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -24,6 +24,7 @@ class cmGeneratedFileStream;
 class cmCTestCommand;
 class cmCTestScriptHandler;
 class cmCTestStartCommand;
+class cmXMLWriter;
 
 #define cmCTestLog(ctSelf, logType, msg) \
   do { \
@@ -274,9 +275,11 @@ public:
 
   //! Start CTest XML output file
   void StartXML(std::ostream& ostr, bool append);
+  void StartXML(cmXMLWriter& xml, bool append);
 
   //! End CTest XML output file
   void EndXML(std::ostream& ostr);
+  void EndXML(cmXMLWriter& xml);
 
   //! Run command specialized for make and configure. Returns process status
   // and retVal is return value or exception.
@@ -421,6 +424,7 @@ public:
   void SetStreams(std::ostream* out, std::ostream* err)
     { this->StreamOut = out; this->StreamErr = err; }
   void AddSiteProperties(std::ostream& );
+  void AddSiteProperties(cmXMLWriter& xml);
   bool GetLabelSummary() { return this->LabelSummary;}
 
   std::string GetCostDataFile();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f6413400a00362cf307d0fbb85daf96265091686
commit f6413400a00362cf307d0fbb85daf96265091686
Author:     Daniel Pfeifer <daniel at pfeifer-mail.de>
AuthorDate: Sat May 23 23:04:50 2015 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 26 11:09:20 2015 -0400

    Add cmXMLWriter class to consolidate XML generation
    
    Explicitly track XML generation state (indentation, element closure,
    etc.) so that clients can avoid manually/implicitly maintaining it.

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 9624401..a7adb51 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -347,6 +347,8 @@ set(SRCS
   cmXMLParser.h
   cmXMLSafe.cxx
   cmXMLSafe.h
+  cmXMLWriter.cxx
+  cmXMLWriter.h
   cmake.cxx
   cmake.h
 
diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx
new file mode 100644
index 0000000..f9b3b49
--- /dev/null
+++ b/Source/cmXMLWriter.cxx
@@ -0,0 +1,134 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Daniel Pfeifer <daniel at pfeifer-mail.de>
+
+  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 "cmXMLWriter.h"
+#include "cmXMLSafe.h"
+
+#include <cassert>
+#include <fstream>
+
+cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level)
+: Output(output)
+, Level(level)
+, ElementOpen(false)
+, BreakAttrib(false)
+, IsContent(false)
+{
+}
+
+cmXMLWriter::~cmXMLWriter()
+{
+  assert(this->Elements.empty());
+}
+
+void cmXMLWriter::StartDocument(const char* encoding)
+{
+  this->Output << "<?xml version=\"1.0\" encoding=\"" << encoding << "\"?>";
+}
+
+void cmXMLWriter::EndDocument()
+{
+  assert(this->Elements.empty());
+  this->Output << '\n';
+}
+
+void cmXMLWriter::StartElement(std::string const& name)
+{
+  this->CloseStartElement();
+  this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+  this->Output << '<' << name;
+  this->Elements.push(name);
+  this->ElementOpen = true;
+  this->BreakAttrib = false;
+}
+
+void cmXMLWriter::EndElement()
+{
+  assert(!this->Elements.empty());
+  if (this->ElementOpen)
+    {
+    this->Output << "/>";
+    }
+  else
+    {
+    this->ConditionalLineBreak(!this->IsContent, this->Elements.size() - 1);
+    this->IsContent = false;
+    this->Output << "</" << this->Elements.top() << '>';
+    }
+  this->Elements.pop();
+  this->ElementOpen = false;
+}
+
+void cmXMLWriter::BreakAttributes()
+{
+  this->BreakAttrib = true;
+}
+
+void cmXMLWriter::Comment(const char* comment)
+{
+  this->CloseStartElement();
+  this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+  this->Output << "<!-- " << comment << " -->";
+}
+
+void cmXMLWriter::CData(std::string const& data)
+{
+  this->PreContent();
+  this->Output << "<![CDATA[" << data << "]]>";
+}
+
+void cmXMLWriter::ProcessingInstruction(const char* target, const char* data)
+{
+  this->CloseStartElement();
+  this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+  this->Output << "<?" << target << ' ' << data << "?>";
+}
+
+void cmXMLWriter::FragmentFile(const char* fname)
+{
+  this->CloseStartElement();
+  std::ifstream fin(fname, std::ios::in | std::ios::binary);
+  this->Output << fin.rdbuf();
+}
+
+void cmXMLWriter::ConditionalLineBreak(bool condition, std::size_t indent)
+{
+  if (condition)
+    {
+    this->Output << '\n' << std::string(indent + this->Level, '\t');
+    }
+}
+
+void cmXMLWriter::PreAttribute()
+{
+  assert(this->ElementOpen);
+  this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size());
+  if (!this->BreakAttrib)
+    {
+    this->Output << ' ';
+    }
+}
+
+void cmXMLWriter::PreContent()
+{
+  this->CloseStartElement();
+  this->IsContent = true;
+}
+
+void cmXMLWriter::CloseStartElement()
+{
+  if (this->ElementOpen)
+    {
+    this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size());
+    this->Output << '>';
+    this->ElementOpen = false;
+    }
+}
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
new file mode 100644
index 0000000..c38c0de
--- /dev/null
+++ b/Source/cmXMLWriter.h
@@ -0,0 +1,120 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Daniel Pfeifer <daniel at pfeifer-mail.de>
+
+  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.
+============================================================================*/
+#ifndef cmXMLWiter_h
+#define cmXMLWiter_h
+
+#include "cmStandardIncludes.h"
+#include "cmXMLSafe.h"
+
+#include <ostream>
+#include <stack>
+#include <string>
+#include <vector>
+
+class cmXMLWriter
+{
+public:
+  cmXMLWriter(std::ostream& output, std::size_t level = 0);
+  ~cmXMLWriter();
+
+  void StartDocument(const char* encoding = "UTF-8");
+  void EndDocument();
+
+  void StartElement(std::string const& name);
+  void EndElement();
+
+  void BreakAttributes();
+
+  template <typename T>
+  void Attribute(const char* name, T const& value)
+    {
+    this->PreAttribute();
+    this->Output << name << "=\"" << SafeAttribute(value) << '"';
+    }
+
+  template <typename T>
+  void Element(std::string const& name, T const& value)
+    {
+    this->StartElement(name);
+    this->Content(value);
+    this->EndElement();
+    }
+
+  template <typename T>
+  void Content(T const& content)
+    {
+    this->PreContent();
+    this->Output << SafeContent(content);
+    }
+
+  void Comment(const char* comment);
+
+  void CData(std::string const& data);
+
+  void ProcessingInstruction(const char* target, const char* data);
+
+  void FragmentFile(const char* fname);
+
+private:
+  cmXMLWriter(const cmXMLWriter&);
+  cmXMLWriter& operator=(const cmXMLWriter&);
+
+  void ConditionalLineBreak(bool condition, std::size_t indent);
+
+  void PreAttribute();
+  void PreContent();
+
+  void CloseStartElement();
+
+private:
+  static cmXMLSafe SafeAttribute(const char* value)
+    {
+    return cmXMLSafe(value);
+    }
+
+  static cmXMLSafe SafeAttribute(std::string const& value)
+    {
+    return cmXMLSafe(value);
+    }
+
+  template <typename T>
+  static T SafeAttribute(T value)
+    {
+    return value;
+    }
+
+  static cmXMLSafe SafeContent(const char* value)
+    {
+    return cmXMLSafe(value).Quotes(false);
+    }
+
+  static cmXMLSafe SafeContent(std::string const& value)
+    {
+    return cmXMLSafe(value).Quotes(false);
+    }
+
+  template <typename T>
+  static T SafeContent(T value)
+    {
+    return value;
+    }
+
+private:
+  std::ostream& Output;
+  std::stack<std::string, std::vector<std::string> > Elements;
+  std::size_t Level;
+  bool ElementOpen;
+  bool BreakAttrib;
+  bool IsContent;
+};
+
+#endif

-----------------------------------------------------------------------

Summary of changes:
 Source/CMakeLists.txt                    |    2 +
 Source/CTest/cmCTestBuildHandler.cxx     |   99 ++++-----
 Source/CTest/cmCTestBuildHandler.h       |   10 +-
 Source/CTest/cmCTestCVS.cxx              |   12 +-
 Source/CTest/cmCTestCVS.h                |    4 +-
 Source/CTest/cmCTestConfigureHandler.cxx |   38 ++--
 Source/CTest/cmCTestCoverageHandler.cxx  |  305 ++++++++++++++--------------
 Source/CTest/cmCTestCoverageHandler.h    |    6 +-
 Source/CTest/cmCTestGlobalVC.cxx         |   18 +-
 Source/CTest/cmCTestGlobalVC.h           |    6 +-
 Source/CTest/cmCTestLaunch.cxx           |  123 +++++-------
 Source/CTest/cmCTestLaunch.h             |   12 +-
 Source/CTest/cmCTestMemCheckHandler.cxx  |   90 ++++-----
 Source/CTest/cmCTestMemCheckHandler.h    |    3 +-
 Source/CTest/cmCTestSVN.cxx              |    6 +-
 Source/CTest/cmCTestSVN.h                |    2 +-
 Source/CTest/cmCTestTestHandler.cxx      |  322 ++++++++++++++----------------
 Source/CTest/cmCTestTestHandler.h        |   11 +-
 Source/CTest/cmCTestUpdateHandler.cxx    |   63 +++---
 Source/CTest/cmCTestUploadHandler.cxx    |   46 +++--
 Source/CTest/cmCTestVC.cxx               |   38 ++--
 Source/CTest/cmCTestVC.h                 |    7 +-
 Source/cmCTest.cxx                       |  147 +++++++-------
 Source/cmCTest.h                         |    9 +-
 Source/cmXMLWriter.cxx                   |  134 +++++++++++++
 Source/cmXMLWriter.h                     |  120 +++++++++++
 26 files changed, 919 insertions(+), 714 deletions(-)
 create mode 100644 Source/cmXMLWriter.cxx
 create mode 100644 Source/cmXMLWriter.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list