Browse Source

Merge topic 'fix-test-output-truncation'

e73bf1c CTest: Do not truncate UTF-8 test output too early (#10656)
Brad King 15 years ago
parent
commit
333e707d95
1 changed files with 28 additions and 47 deletions
  1. 28 47
      Source/CTest/cmCTestTestHandler.cxx

+ 28 - 47
Source/CTest/cmCTestTestHandler.cxx

@@ -26,6 +26,7 @@
 #include "cmCommand.h"
 #include "cmSystemTools.h"
 #include "cmXMLSafe.h"
+#include "cm_utf8.h"
 
 #include <stdlib.h>
 #include <math.h>
@@ -1980,65 +1981,45 @@ void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
     }
 }
 
-//----------------------------------------------------------------------
-bool cmCTestTestHandler::CleanTestOutput(std::string& output,
-  size_t remove_threshold)
+//----------------------------------------------------------------------------
+bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
 {
-  if ( remove_threshold == 0 )
+  if(!length || length >= output.size() ||
+     output.find("CTEST_FULL_OUTPUT") != output.npos)
     {
     return true;
     }
-  if ( output.find("CTEST_FULL_OUTPUT") != output.npos )
+
+  // Truncate at given length but do not break in the middle of a multi-byte
+  // UTF-8 encoding.
+  char const* const begin = output.c_str();
+  char const* const end = begin + output.size();
+  char const* const truncate = begin + length;
+  char const* current = begin;
+  while(current < truncate)
     {
-    return true;
-    }
-  cmOStringStream ostr;
-  std::string::size_type cc;
-  std::string::size_type skipsize = 0;
-  int inTag = 0;
-  int skipped = 0;
-  for ( cc = 0; cc < output.size(); cc ++ )
-    {
-    int ch = output[cc];
-    if ( ch < 0 || ch > 255 )
-      {
-      break;
-      }
-    if ( ch == '<' )
-      {
-      inTag = 1;
-      }
-    if ( !inTag )
+    unsigned int ch;
+    if(const char* next = cm_utf8_decode_character(current, end, &ch))
       {
-      int notskip = 0;
-      // Skip
-      if ( skipsize < remove_threshold )
-        {
-        ostr << static_cast<char>(ch);
-        notskip = 1;
-        }
-      skipsize ++;
-      if ( notskip && skipsize >= remove_threshold )
+      if(next > truncate)
         {
-        skipped = 1;
+        break;
         }
+      current = next;
       }
-    else
-      {
-      ostr << static_cast<char>(ch);
-      }
-    if ( ch == '>' )
+    else // Bad byte will be handled by cmXMLSafe.
       {
-      inTag = 0;
+      ++current;
       }
     }
-  if ( skipped )
-    {
-    ostr << "..." << std::endl << "The rest of the test output was removed "
-      "since it exceeds the threshold of "
-      << remove_threshold << " characters." << std::endl;
-    }
-  output = ostr.str();
+  output = output.substr(0, current - begin);
+
+  // Append truncation message.
+  cmOStringStream msg;
+  msg << "...\n"
+    "The rest of the test output was removed since it exceeds the threshold "
+    "of " << length << " bytes.\n";
+  output += msg.str();
   return true;
 }