From 7577a542dfa0aac045b97bfe4440241583c62e3a Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Thu, 15 May 2014 10:19:29 -0400
Subject: cmCTestBuildAndTestHandler: Refactor output capture

Use an RAII class to add and remove callbacks.
---
 Source/CTest/cmCTestBuildAndTestHandler.cxx | 41 ++++++++++++++++-------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index ac2196c..9a6b40e 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -161,28 +161,29 @@ void CMakeStdoutCallback(const char* m, int len, void* s)
   std::string* out = (std::string*)s;
   out->append(m, len);
 }
-struct cmSetupOutputCaptureCleanup
+
+//----------------------------------------------------------------------
+class cmCTestBuildAndTestCaptureRAII
 {
-  ~cmSetupOutputCaptureCleanup()
-  {
-    cmSystemTools::SetErrorCallback(0, 0);
+  cmake& CM;
+public:
+  cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s): CM(cm)
+    {
+    cmSystemTools::SetErrorCallback(CMakeMessageCallback, &s);
+    cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &s);
+    this->CM.SetProgressCallback(CMakeProgressCallback, &s);
+    }
+  ~cmCTestBuildAndTestCaptureRAII()
+    {
+    this->CM.SetProgressCallback(0, 0);
     cmSystemTools::SetStdoutCallback(0, 0);
-  }
+    cmSystemTools::SetErrorCallback(0, 0);
+    }
 };
 
 //----------------------------------------------------------------------
 int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
 {
-  std::string cmakeOutString;
-  cmSystemTools::SetErrorCallback(CMakeMessageCallback, &cmakeOutString);
-  cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &cmakeOutString);
-  // make sure SetStdoutCallback and SetErrorCallback are set to null
-  // after this function exits so that they do not point at a destroyed
-  // string cmakeOutString
-  cmSetupOutputCaptureCleanup cleanup;
-  static_cast<void>(cleanup);
-  cmOStringStream out;
-
   // if the generator and make program are not specified then it is an error
   if (!this->BuildGenerator.size())
     {
@@ -196,6 +197,12 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
     return 1;
     }
 
+  cmake cm;
+  std::string cmakeOutString;
+  cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString);
+  static_cast<void>(captureRAII);
+  cmOStringStream out;
+
   if ( this->CTest->GetConfigType().size() == 0 &&
        this->ConfigSample.size())
     {
@@ -232,10 +239,6 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
     }
   cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());
 
-  // should we cmake?
-  cmake cm;
-  cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString);
-
   if(this->BuildNoCMake)
     {
     // Make the generator available for the Build call below.
-- 
cgit v0.12