Skip to content

Commit

Permalink
Disable colored output for non-interactive terminals (#3310)
Browse files Browse the repository at this point in the history
Disable colored output for non-interactive terminals
  • Loading branch information
taketwo authored Sep 10, 2019
2 parents ce16dba + 0410ddb commit 261f07e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
11 changes: 11 additions & 0 deletions common/include/pcl/console/print.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ namespace pcl
PCL_EXPORTS bool
isVerbosityLevelEnabled (VERBOSITY_LEVEL severity);

/** \brief Enable or disable colored text output, overriding the default behavior.
*
* By default, colored output is enabled for interactive terminals or when the environment
* variable PCL_CLICOLOR_FORCE is set.
*
* \param stream the output stream (stdout, stderr, etc)
* \param enable whether to emit color codes when calling any of the color related methods
*/
PCL_EXPORTS void
enableColoredOutput (FILE *stream, bool enable);

/** \brief Change the text color (on either stdout or stderr) with an attr:fg:bg
* \param stream the output stream (stdout, stderr, etc)
* \param attribute the text attribute
Expand Down
39 changes: 39 additions & 0 deletions common/src/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@
#include <algorithm>
#include <cstdlib>
#include <cctype> // for toupper
#include <map>
#include <string>
#include <boost/optional.hpp>

#if defined WIN32
# include <windows.h>
# include <io.h>

#ifndef _MSC_VER
# define COMMON_LVB_UNDERSCORE 0
Expand Down Expand Up @@ -81,12 +84,44 @@ convertAttributesColor (int attribute, int fg, int bg=0)
return wAttributes[attribute] | wFgColors[fg] | wBgColors[bg];
}

#else
# include <unistd.h>
# include <cstdio>
#endif

// Map to store, for each output stream, whether to use colored output
static std::map<FILE *, boost::optional<bool> > colored_output;

////////////////////////////////////////////////////////////////////////////////
inline bool
useColoredOutput (FILE *stream)
{
auto &colored = colored_output[stream];
if (!colored)
{
// Use colored output if PCL_CLICOLOR_FORCE is set or if the output is an interactive terminal
#ifdef WIN32
colored = getenv ("PCL_CLICOLOR_FORCE") || _isatty (_fileno (stream));
#else
colored = getenv ("PCL_CLICOLOR_FORCE") || isatty (fileno (stream));
#endif
}
return colored.get ();
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::enableColoredOutput (FILE *stream, bool enable)
{
colored_output[stream] = enable;
}

////////////////////////////////////////////////////////////////////////////////
void
pcl::console::change_text_color (FILE *stream, int attribute, int fg, int bg)
{
if (!useColoredOutput (stream)) return;

#ifdef WIN32
HANDLE h = GetStdHandle ((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
SetConsoleTextAttribute (h, convertAttributesColor (attribute, fg, bg));
Expand All @@ -102,6 +137,8 @@ pcl::console::change_text_color (FILE *stream, int attribute, int fg, int bg)
void
pcl::console::change_text_color (FILE *stream, int attribute, int fg)
{
if (!useColoredOutput (stream)) return;

#ifdef WIN32
HANDLE h = GetStdHandle ((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
SetConsoleTextAttribute (h, convertAttributesColor (attribute, fg));
Expand All @@ -117,6 +154,8 @@ pcl::console::change_text_color (FILE *stream, int attribute, int fg)
void
pcl::console::reset_text_color (FILE *stream)
{
if (!useColoredOutput (stream)) return;

#ifdef WIN32
HANDLE h = GetStdHandle ((stream == stdout) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
SetConsoleTextAttribute (h, convertAttributesColor (0, TT_WHITE, TT_BLACK));
Expand Down

0 comments on commit 261f07e

Please sign in to comment.