Browse Source

cmCTestBuildAndTestHandler: Refactor output capture

Use an RAII class to add and remove callbacks.
Brad King 11 years ago
parent
commit
7577a542df
1 changed files with 22 additions and 19 deletions
  1. 22 19
      Source/CTest/cmCTestBuildAndTestHandler.cxx

+ 22 - 19
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.