Explorar el Código

StdIo: Replace uses of KWSys Terminal with StdIo::Print

The latter:

* uses a type-safe representation of text attributes,

* works with `StdIo::Console` to print arbitrary UTF-8 text in color, and

* writes VT100 sequences to Windows Consoles when supported, eliminating
  racy console text attribute changes in parallel `make` output.

Fixes: #22450, #26689, #26924
Brad King hace 5 meses
padre
commit
509c424472

+ 12 - 4
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -6,6 +6,7 @@
 #include <cassert>
 #include <cassert>
 #include <cstdio>
 #include <cstdio>
 #include <functional>
 #include <functional>
+#include <iostream>
 #include <utility>
 #include <utility>
 
 
 #include <cm/memory>
 #include <cm/memory>
@@ -16,7 +17,6 @@
 #include <cmext/string_view>
 #include <cmext/string_view>
 
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/FStream.hxx"
-#include "cmsys/Terminal.h"
 
 
 #include "cmCMakePath.h"
 #include "cmCMakePath.h"
 #include "cmCustomCommand.h" // IWYU pragma: keep
 #include "cmCustomCommand.h" // IWYU pragma: keep
@@ -41,6 +41,8 @@
 #include "cmState.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
+#include "cmStdIoStream.h"
+#include "cmStdIoTerminal.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 #include "cmTargetDepend.h"
 #include "cmTargetDepend.h"
@@ -1377,9 +1379,15 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
   this->CheckMultipleOutputs(verbose);
   this->CheckMultipleOutputs(verbose);
 
 
   auto echoColor = [color](std::string const& m) {
   auto echoColor = [color](std::string const& m) {
-    cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
-                                       cmsysTerminal_Color_ForegroundBold,
-                                     m.c_str(), true, color);
+    cm::StdIo::TermAttrSet attrs;
+    if (color) {
+      attrs = {
+        cm::StdIo::TermAttr::ForegroundMagenta,
+        cm::StdIo::TermAttr::ForegroundBold,
+      };
+    }
+    Print(cm::StdIo::Out(), attrs, m);
+    std::cout << std::endl;
   };
   };
 
 
   std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);
   std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);

+ 2 - 2
Source/cmMessageMetadata.h

@@ -2,10 +2,10 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #pragma once
 #pragma once
 
 
-#include "cmsys/Terminal.h"
+#include "cmStdIoTerminal.h"
 
 
 struct cmMessageMetadata
 struct cmMessageMetadata
 {
 {
   char const* title = nullptr;
   char const* title = nullptr;
-  int desiredColor = cmsysTerminal_Color_Normal;
+  cm::StdIo::TermAttrSet attrs = cm::StdIo::TermAttr::Normal;
 };
 };

+ 6 - 7
Source/cmMessenger.cxx

@@ -5,6 +5,7 @@
 #include "cmDocumentationFormatter.h"
 #include "cmDocumentationFormatter.h"
 #include "cmMessageMetadata.h"
 #include "cmMessageMetadata.h"
 #include "cmMessageType.h"
 #include "cmMessageType.h"
+#include "cmStdIoTerminal.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 
 
@@ -17,8 +18,6 @@
 #include <sstream>
 #include <sstream>
 #include <utility>
 #include <utility>
 
 
-#include "cmsys/Terminal.h"
-
 #ifdef CMake_ENABLE_DEBUGGER
 #ifdef CMake_ENABLE_DEBUGGER
 #  include "cmDebuggerAdapter.h"
 #  include "cmDebuggerAdapter.h"
 #endif
 #endif
@@ -47,18 +46,18 @@ char const* getMessageTypeStr(MessageType t)
   return "Warning";
   return "Warning";
 }
 }
 
 
-int getMessageColor(MessageType t)
+cm::StdIo::TermAttr getMessageColor(MessageType t)
 {
 {
   switch (t) {
   switch (t) {
     case MessageType::INTERNAL_ERROR:
     case MessageType::INTERNAL_ERROR:
     case MessageType::FATAL_ERROR:
     case MessageType::FATAL_ERROR:
     case MessageType::AUTHOR_ERROR:
     case MessageType::AUTHOR_ERROR:
-      return cmsysTerminal_Color_ForegroundRed;
+      return cm::StdIo::TermAttr::ForegroundRed;
     case MessageType::AUTHOR_WARNING:
     case MessageType::AUTHOR_WARNING:
     case MessageType::WARNING:
     case MessageType::WARNING:
-      return cmsysTerminal_Color_ForegroundYellow;
+      return cm::StdIo::TermAttr::ForegroundYellow;
     default:
     default:
-      return cmsysTerminal_Color_Normal;
+      return cm::StdIo::TermAttr::Normal;
   }
   }
 }
 }
 
 
@@ -99,7 +98,7 @@ void displayMessage(MessageType t, std::ostringstream& msg)
 
 
   // Output the message.
   // Output the message.
   cmMessageMetadata md;
   cmMessageMetadata md;
-  md.desiredColor = getMessageColor(t);
+  md.attrs = getMessageColor(t);
   if (t == MessageType::FATAL_ERROR || t == MessageType::INTERNAL_ERROR ||
   if (t == MessageType::FATAL_ERROR || t == MessageType::INTERNAL_ERROR ||
       t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) {
       t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) {
     cmSystemTools::SetErrorOccurred();
     cmSystemTools::SetErrorOccurred();

+ 3 - 15
Source/cmakemain.cxx

@@ -7,7 +7,6 @@
 #include <cassert>
 #include <cassert>
 #include <cctype>
 #include <cctype>
 #include <climits>
 #include <climits>
-#include <cstdio>
 #include <cstring>
 #include <cstring>
 #include <functional>
 #include <functional>
 #include <iostream>
 #include <iostream>
@@ -34,6 +33,8 @@
 #include "cmState.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
 #include "cmStdIoConsole.h"
 #include "cmStdIoConsole.h"
+#include "cmStdIoStream.h"
+#include "cmStdIoTerminal.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 #include "cmValue.h"
 #include "cmValue.h"
@@ -46,7 +47,6 @@
 
 
 #include "cmsys/Encoding.hxx"
 #include "cmsys/Encoding.hxx"
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/RegularExpression.hxx"
-#include "cmsys/Terminal.h"
 
 
 namespace {
 namespace {
 #ifndef CMAKE_BOOTSTRAP
 #ifndef CMAKE_BOOTSTRAP
@@ -174,20 +174,8 @@ std::string cmakemainGetStack(cmake* cm)
 void cmakemainMessageCallback(std::string const& m,
 void cmakemainMessageCallback(std::string const& m,
                               cmMessageMetadata const& md, cmake* cm)
                               cmMessageMetadata const& md, cmake* cm)
 {
 {
-#if defined(_WIN32)
-  // FIXME: On Windows we replace cerr's streambuf with a custom
-  // implementation that converts our internal UTF-8 encoding to the
-  // console's encoding.  It also does *not* replace LF with CRLF.
-  // Since stderr does not convert encoding and does convert LF, we
-  // cannot use it to print messages.  Another implementation will
-  // be needed to print colored messages on Windows.
-  static_cast<void>(md);
-  std::cerr << m << cmakemainGetStack(cm) << std::endl;
-#else
-  cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str());
-  fflush(stderr); // stderr is buffered in some cases.
+  Print(cm::StdIo::Err(), md.attrs, m);
   std::cerr << cmakemainGetStack(cm) << std::endl;
   std::cerr << cmakemainGetStack(cm) << std::endl;
-#endif
 }
 }
 
 
 void cmakemainProgressCallback(std::string const& m, float prog, cmake* cm)
 void cmakemainProgressCallback(std::string const& m, float prog, cmake* cm)

+ 21 - 16
Source/cmcmd.cxx

@@ -3,6 +3,7 @@
 #include "cmcmd.h"
 #include "cmcmd.h"
 
 
 #include <functional>
 #include <functional>
+#include <iomanip>
 #include <iterator>
 #include <iterator>
 
 
 #include <cm/optional>
 #include <cm/optional>
@@ -26,6 +27,8 @@
 #include "cmStateDirectory.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
 #include "cmStateSnapshot.h"
 #include "cmStdIoConsole.h"
 #include "cmStdIoConsole.h"
+#include "cmStdIoStream.h"
+#include "cmStdIoTerminal.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 #include "cmTransformDepfile.h"
 #include "cmTransformDepfile.h"
@@ -73,7 +76,6 @@
 #include "cmsys/Directory.hxx"
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/RegularExpression.hxx"
-#include "cmsys/Terminal.h"
 
 
 int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
 int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
                               std::vector<std::string>::const_iterator argEnd);
                               std::vector<std::string>::const_iterator argEnd);
@@ -1859,8 +1861,8 @@ static void cmcmdProgressReport(std::string const& dir, std::string const& num)
   int fileNum =
   int fileNum =
     static_cast<int>(cmsys::Directory::GetNumberOfFilesInDirectory(dirName));
     static_cast<int>(cmsys::Directory::GetNumberOfFilesInDirectory(dirName));
   if (count > 0) {
   if (count > 0) {
-    // print the progress
-    fprintf(stdout, "[%3i%%] ", ((fileNum - 3) * 100) / count);
+    int const percent = ((fileNum - 3) * 100) / count;
+    std::cout << '[' << std::setw(3) << percent << "%] ";
   }
   }
 }
 }
 
 
@@ -1871,7 +1873,8 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args)
   //   args[1] == cmake_echo_color
   //   args[1] == cmake_echo_color
 
 
   bool enabled = true;
   bool enabled = true;
-  int color = cmsysTerminal_Color_Normal;
+  static cm::StdIo::TermAttrSet const noAttrs;
+  cm::StdIo::TermAttrSet attrs = cm::StdIo::TermAttr::Normal;
   bool newline = true;
   bool newline = true;
   std::string progressDir;
   std::string progressDir;
   for (auto const& arg : cmMakeRange(args).advance(2)) {
   for (auto const& arg : cmMakeRange(args).advance(2)) {
@@ -1889,32 +1892,34 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args)
         cmcmdProgressReport(progressDir, progressNum);
         cmcmdProgressReport(progressDir, progressNum);
       }
       }
     } else if (arg == "--normal") {
     } else if (arg == "--normal") {
-      color = cmsysTerminal_Color_Normal;
+      attrs = cm::StdIo::TermAttr::Normal;
     } else if (arg == "--black") {
     } else if (arg == "--black") {
-      color = cmsysTerminal_Color_ForegroundBlack;
+      attrs = cm::StdIo::TermAttr::ForegroundBlack;
     } else if (arg == "--red") {
     } else if (arg == "--red") {
-      color = cmsysTerminal_Color_ForegroundRed;
+      attrs = cm::StdIo::TermAttr::ForegroundRed;
     } else if (arg == "--green") {
     } else if (arg == "--green") {
-      color = cmsysTerminal_Color_ForegroundGreen;
+      attrs = cm::StdIo::TermAttr::ForegroundGreen;
     } else if (arg == "--yellow") {
     } else if (arg == "--yellow") {
-      color = cmsysTerminal_Color_ForegroundYellow;
+      attrs = cm::StdIo::TermAttr::ForegroundYellow;
     } else if (arg == "--blue") {
     } else if (arg == "--blue") {
-      color = cmsysTerminal_Color_ForegroundBlue;
+      attrs = cm::StdIo::TermAttr::ForegroundBlue;
     } else if (arg == "--magenta") {
     } else if (arg == "--magenta") {
-      color = cmsysTerminal_Color_ForegroundMagenta;
+      attrs = cm::StdIo::TermAttr::ForegroundMagenta;
     } else if (arg == "--cyan") {
     } else if (arg == "--cyan") {
-      color = cmsysTerminal_Color_ForegroundCyan;
+      attrs = cm::StdIo::TermAttr::ForegroundCyan;
     } else if (arg == "--white") {
     } else if (arg == "--white") {
-      color = cmsysTerminal_Color_ForegroundWhite;
+      attrs = cm::StdIo::TermAttr::ForegroundWhite;
     } else if (arg == "--bold") {
     } else if (arg == "--bold") {
-      color |= cmsysTerminal_Color_ForegroundBold;
+      attrs |= cm::StdIo::TermAttr::ForegroundBold;
     } else if (arg == "--no-newline") {
     } else if (arg == "--no-newline") {
       newline = false;
       newline = false;
     } else if (arg == "--newline") {
     } else if (arg == "--newline") {
       newline = true;
       newline = true;
     } else {
     } else {
-      // Color is enabled.  Print with the current color.
-      cmSystemTools::MakefileColorEcho(color, arg.c_str(), newline, enabled);
+      Print(cm::StdIo::Out(), enabled ? attrs : noAttrs, arg);
+      if (newline) {
+        std::cout << std::endl;
+      }
     }
     }
   }
   }