<div dir="ltr">Hi Chandler,<div><br></div><div>I think this commit might be a bit heavy-handed. With this change, unless Clang/LLVM is linked against libncurses no colored output is available at all. I think this is too conservative.</div>
<div><br></div><div>You've essentially added a better mechanism for detecting the presence of color support, but in the case #ifndef HAVE_CURSES_H, I don't see why you can't just fall back to the same algorithm as before.</div>
<div><br></div><div>Granted it isn't perfect, but if isatty() returns true and TERM != "dumb", I think it's fair to assume color support (in the absence of curses).</div><div><br></div><div>What do you think? I'm really trying to push back against Clang/LLVM having a mandatory extra dependency just to have coloured output.</div>
<div><br></div><div>James</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 7 August 2013 09:47, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Wed Aug  7 03:47:36 2013<br>
New Revision: 187874<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=187874&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=187874&view=rev</a><br>
Log:<br>
Add support for linking against a curses library when available and<br>
using it to detect whether or not a terminal supports colors. This<br>
replaces a particularly egregious hack that merely compared the TERM<br>
environment variable to "dumb". That doesn't really translate to<br>
a reasonable experience for users that have actually ensured their<br>
terminal's capabilities are accurately reflected.<br>
<br>
This makes testing a terminal for color support somewhat more expensive,<br>
but it is called very rarely anyways. The important fast path when the<br>
output is being piped somewhere is already in place.<br>
<br>
The global lock may seem excessive, but the spec for calling into curses<br>
is *terrible*. The whole library is terrible, and I spent quite a bit of<br>
time looking for a better way of doing this before convincing myself<br>
that this was the fundamentally correct way to behave. The damage of the<br>
curses library is very narrowly confined, and we continue to use raw<br>
escape codes for actually manipulating the colors which is a much sane<br>
system than directly using curses here (IMO).<br>
<br>
If this causes trouble for folks, please let me know. I've tested it on<br>
Linux and will watch the bots carefully. I've also worked to account for<br>
the variances of curses interfaces that I could finde documentation for,<br>
but that may not have been sufficient.<br>
<br>
Modified:<br>
    llvm/trunk/CMakeLists.txt<br>
    llvm/trunk/autoconf/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
    llvm/trunk/cmake/config-ix.cmake<br>
    llvm/trunk/cmake/modules/LLVM-Config.cmake<br>
    llvm/trunk/cmake/modules/<a href="http://LLVMConfig.cmake.in" target="_blank">LLVMConfig.cmake.in</a><br>
    llvm/trunk/configure<br>
    llvm/trunk/include/llvm/Config/config.h.cmake<br>
    llvm/trunk/include/llvm/Config/<a href="http://config.h.in" target="_blank">config.h.in</a><br>
    llvm/trunk/lib/Support/Unix/Process.inc<br>
<br>
Modified: llvm/trunk/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/CMakeLists.txt?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/CMakeLists.txt (original)<br>
+++ llvm/trunk/CMakeLists.txt Wed Aug  7 03:47:36 2013<br>
@@ -123,6 +123,8 @@ set(FFI_INCLUDE_DIR "" CACHE PATH "Addit<br>
 set(LLVM_TARGET_ARCH "host"<br>
   CACHE STRING "Set target to use for LLVM JIT or use \"host\" for automatic detection.")<br>
<br>
+option(LLVM_ENABLE_CURSES "Use curses to detect terminal info if available." ON)<br>
+<br>
 option(LLVM_ENABLE_THREADS "Use threads if available." ON)<br>
<br>
 option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON)<br>
<br>
Modified: llvm/trunk/autoconf/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/autoconf/configure.ac?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/autoconf/<a href="http://configure.ac" target="_blank">configure.ac</a> (original)<br>
+++ llvm/trunk/autoconf/<a href="http://configure.ac" target="_blank">configure.ac</a> Wed Aug  7 03:47:36 2013<br>
@@ -1072,6 +1072,17 @@ AC_ARG_WITH(bug-report-url,<br>
 AC_DEFINE_UNQUOTED(BUG_REPORT_URL,"$withval",<br>
                    [Bug report URL.])<br>
<br>
+dnl --enable-curses: check whether the user wants to control use of curses:<br>
+AC_ARG_ENABLE(curses,AS_HELP_STRING(<br>
+  [--enable-curses],<br>
+  [Use curses for querying terminal infomation if available (default is YES)]),<br>
+  [case "$enableval" in<br>
+    yes) llvm_cv_enable_curses="yes" ;;<br>
+    no)  llvm_cv_enable_curses="no"  ;;<br>
+    *) AC_MSG_ERROR([Invalid setting for --enable-curses. Use "yes" or "no"]) ;;<br>
+  esac],<br>
+  llvm_cv_enable_curses="yes")<br>
+<br>
 dnl --enable-libffi : check whether the user wants to turn off libffi:<br>
 AC_ARG_ENABLE(libffi,AS_HELP_STRING(<br>
   --enable-libffi,[Check for the presence of libffi (default is NO)]),<br>
@@ -1378,6 +1389,14 @@ dnl macros to detect whether clock_getti<br>
 dnl right libraries to link with.<br>
 AC_SEARCH_LIBS(clock_gettime,rt)<br>
<br>
+dnl The curses library is optional; used for querying terminal info<br>
+if test "$llvm_cv_enable_curses" = "yes" ; then<br>
+  dnl We need the has_color functionality in curses for it to be useful.<br>
+  AC_SEARCH_LIBS(has_colors,curses ncurses ncursesw,<br>
+                 AC_DEFINE([HAVE_CURSES],[1],<br>
+                           [Define if curses provides the has_color() function on this platform.]))<br>
+fi<br>
+<br>
 dnl libffi is optional; used to call external functions from the interpreter<br>
 if test "$llvm_cv_enable_libffi" = "yes" ; then<br>
   AC_SEARCH_LIBS(ffi_call,ffi,AC_DEFINE([HAVE_FFI_CALL],[1],<br>
@@ -1554,6 +1573,11 @@ else<br>
   AC_SUBST(HAVE_LIBZ, 0)<br>
 fi<br>
<br>
+dnl Try to find a suitable curses header.<br>
+if test "$llvm_cv_enable_curses" = "yes" ; then<br>
+  AC_CHECK_HEADERS([curses.h ncurses.h ncursesw.h ncurses/curses.h ncursesw/curses.h])<br>
+fi<br>
+<br>
 dnl Try to find ffi.h.<br>
 if test "$llvm_cv_enable_libffi" = "yes" ; then<br>
   AC_CHECK_HEADERS([ffi.h ffi/ffi.h])<br>
<br>
Modified: llvm/trunk/cmake/config-ix.cmake<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/cmake/config-ix.cmake (original)<br>
+++ llvm/trunk/cmake/config-ix.cmake Wed Aug  7 03:47:36 2013<br>
@@ -74,6 +74,12 @@ check_symbol_exists(FE_INEXACT "fenv.h"<br>
 check_include_file(mach/mach.h HAVE_MACH_MACH_H)<br>
 check_include_file(mach-o/dyld.h HAVE_MACH_O_DYLD_H)<br>
<br>
+check_include_file(curses.h HAVE_CURSES_H)<br>
+check_include_file(ncurses.h HAVE_NCURSES_H)<br>
+check_include_file(ncursesw.h HAVE_NCURSESW_H)<br>
+check_include_file(ncurses/curses.h HAVE_NCURSES_CURSES_H)<br>
+check_include_file(ncursesw/curses.h HAVE_NCURSESW_CURSES_H)<br>
+<br>
 # library checks<br>
 if( NOT PURE_WINDOWS )<br>
   check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)<br>
@@ -97,6 +103,19 @@ if( NOT PURE_WINDOWS )<br>
   else()<br>
     set(HAVE_LIBZ 0)<br>
   endif()<br>
+  if(LLVM_ENABLE_CURSES)<br>
+    check_library_exists(curses has_colors "" HAVE_CURSES)<br>
+    if(NOT HAVE_CURSES)<br>
+      check_library_exists(ncurses has_colors "" HAVE_NCURSES)<br>
+      set(HAVE_CURSES ${HAVE_NCURSES})<br>
+      if(NOT HAVE_CURSES)<br>
+        check_library_exists(ncursesw has_colors "" HAVE_NCURSESW)<br>
+        set(HAVE_CURSES ${HAVE_NCURSESW})<br>
+      endif()<br>
+    endif()<br>
+  else()<br>
+    set(HAVE_CURSES 0)<br>
+  endif()<br>
 endif()<br>
<br>
 # function checks<br>
<br>
Modified: llvm/trunk/cmake/modules/LLVM-Config.cmake<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVM-Config.cmake?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVM-Config.cmake?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/cmake/modules/LLVM-Config.cmake (original)<br>
+++ llvm/trunk/cmake/modules/LLVM-Config.cmake Wed Aug  7 03:47:36 2013<br>
@@ -10,6 +10,15 @@ function(get_system_libs return_var)<br>
       if( HAVE_LIBDL )<br>
         set(system_libs ${system_libs} ${CMAKE_DL_LIBS})<br>
       endif()<br>
+      if(LLVM_ENABLE_CURSES)<br>
+        if(HAVE_NCURSESW)<br>
+          set(system_libs ${system_libs} ncursesw)<br>
+        elseif(HAVE_NCURSES)<br>
+          set(system_libs ${system_libs} ncurses)<br>
+        elseif(HAVE_CURSES)<br>
+          set(system_libs ${system_libs} curses)<br>
+        endif()<br>
+      endif()<br>
       if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )<br>
         set(system_libs ${system_libs} pthread)<br>
       endif()<br>
<br>
Modified: llvm/trunk/cmake/modules/<a href="http://LLVMConfig.cmake.in" target="_blank">LLVMConfig.cmake.in</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMConfig.cmake.in?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/modules/LLVMConfig.cmake.in?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/cmake/modules/<a href="http://LLVMConfig.cmake.in" target="_blank">LLVMConfig.cmake.in</a> (original)<br>
+++ llvm/trunk/cmake/modules/<a href="http://LLVMConfig.cmake.in" target="_blank">LLVMConfig.cmake.in</a> Wed Aug  7 03:47:36 2013<br>
@@ -20,6 +20,8 @@ set(TARGET_TRIPLE "@TARGET_TRIPLE@")<br>
<br>
 set(LLVM_TOOLS_BINARY_DIR @LLVM_TOOLS_BINARY_DIR@)<br>
<br>
+set(LLVM_ENABLE_CURSES @LLVM_ENABLE_CURSES@)<br>
+<br>
 set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@)<br>
<br>
 set(LLVM_ENABLE_ZLIB @LLVM_ENABLE_ZLIB@)<br>
<br>
Modified: llvm/trunk/configure<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/configure?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/configure (original)<br>
+++ llvm/trunk/configure Wed Aug  7 03:47:36 2013<br>
@@ -1453,6 +1453,8 @@ Optional Features:<br>
                           target1,target2,... (default=disable)<br>
   --enable-bindings       Build specific language bindings:<br>
                           all,auto,none,{binding-name} (default=auto)<br>
+  --enable-curses         Use curses for querying terminal infomation if<br>
+                          available (default is YES)<br>
   --enable-libffi         Check for the presence of libffi (default is NO)<br>
   --enable-ltdl-install   install libltdl<br>
<br>
@@ -6004,6 +6006,20 @@ cat >>confdefs.h <<_ACEOF<br>
 _ACEOF<br>
<br>
<br>
+# Check whether --enable-curses was given.<br>
+if test "${enable_curses+set}" = set; then<br>
+  enableval=$enable_curses; case "$enableval" in<br>
+    yes) llvm_cv_enable_curses="yes" ;;<br>
+    no)  llvm_cv_enable_curses="no"  ;;<br>
+    *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-curses. Use \"yes\" or \"no\"" >&5<br>
+echo "$as_me: error: Invalid setting for --enable-curses. Use \"yes\" or \"no\"" >&2;}<br>
+   { (exit 1); exit 1; }; } ;;<br>
+  esac<br>
+else<br>
+  llvm_cv_enable_curses="yes"<br>
+fi<br>
+<br>
+<br>
 # Check whether --enable-libffi was given.<br>
 if test "${enable_libffi+set}" = set; then<br>
   enableval=$enable_libffi; case "$enableval" in<br>
@@ -10545,7 +10561,7 @@ else<br>
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2<br>
   lt_status=$lt_dlunknown<br>
   cat > conftest.$ac_ext <<EOF<br>
-#line 10548 "configure"<br>
+#line 10564 "configure"<br>
 #include "confdefs.h"<br>
<br>
 #if HAVE_DLFCN_H<br>
@@ -12252,6 +12268,112 @@ if test "$ac_res" != no; then<br>
 fi<br>
<br>
<br>
+if test "$llvm_cv_enable_curses" = "yes" ; then<br>
+    { echo "$as_me:$LINENO: checking for library containing has_colors" >&5<br>
+echo $ECHO_N "checking for library containing has_colors... $ECHO_C" >&6; }<br>
+if test "${ac_cv_search_has_colors+set}" = set; then<br>
+  echo $ECHO_N "(cached) $ECHO_C" >&6<br>
+else<br>
+  ac_func_search_save_LIBS=$LIBS<br>
+cat >conftest.$ac_ext <<_ACEOF<br>
+/* confdefs.h.  */<br>
+_ACEOF<br>
+cat confdefs.h >>conftest.$ac_ext<br>
+cat >>conftest.$ac_ext <<_ACEOF<br>
+/* end confdefs.h.  */<br>
+<br>
+/* Override any GCC internal prototype to avoid an error.<br>
+   Use char because int might match the return type of a GCC<br>
+   builtin and then its argument prototype would still apply.  */<br>
+#ifdef __cplusplus<br>
+extern "C"<br>
+#endif<br>
+char has_colors ();<br>
+int<br>
+main ()<br>
+{<br>
+return has_colors ();<br>
+  ;<br>
+  return 0;<br>
+}<br>
+_ACEOF<br>
+for ac_lib in '' curses ncurses ncursesw; do<br>
+  if test -z "$ac_lib"; then<br>
+    ac_res="none required"<br>
+  else<br>
+    ac_res=-l$ac_lib<br>
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"<br>
+  fi<br>
+  rm -f conftest.$ac_objext conftest$ac_exeext<br>
+if { (ac_try="$ac_link"<br>
+case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_link") 2>conftest.er1<br>
+  ac_status=$?<br>
+  grep -v '^ *+' conftest.er1 >conftest.err<br>
+  rm -f conftest.er1<br>
+  cat conftest.err >&5<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); } &&<br>
+        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'<br>
+  { (case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_try") 2>&5<br>
+  ac_status=$?<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); }; } &&<br>
+        { ac_try='test -s conftest$ac_exeext'<br>
+  { (case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_try") 2>&5<br>
+  ac_status=$?<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); }; }; then<br>
+  ac_cv_search_has_colors=$ac_res<br>
+else<br>
+  echo "$as_me: failed program was:" >&5<br>
+sed 's/^/| /' conftest.$ac_ext >&5<br>
+<br>
+<br>
+fi<br>
+<br>
+rm -f core conftest.err conftest.$ac_objext \<br>
+      conftest$ac_exeext<br>
+  if test "${ac_cv_search_has_colors+set}" = set; then<br>
+  break<br>
+fi<br>
+done<br>
+if test "${ac_cv_search_has_colors+set}" = set; then<br>
+  :<br>
+else<br>
+  ac_cv_search_has_colors=no<br>
+fi<br>
+rm conftest.$ac_ext<br>
+LIBS=$ac_func_search_save_LIBS<br>
+fi<br>
+{ echo "$as_me:$LINENO: result: $ac_cv_search_has_colors" >&5<br>
+echo "${ECHO_T}$ac_cv_search_has_colors" >&6; }<br>
+ac_res=$ac_cv_search_has_colors<br>
+if test "$ac_res" != no; then<br>
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"<br>
+<br>
+cat >>confdefs.h <<\_ACEOF<br>
+#define HAVE_CURSES 1<br>
+_ACEOF<br>
+<br>
+fi<br>
+<br>
+fi<br>
+<br>
 if test "$llvm_cv_enable_libffi" = "yes" ; then<br>
   { echo "$as_me:$LINENO: checking for library containing ffi_call" >&5<br>
 echo $ECHO_N "checking for library containing ffi_call... $ECHO_C" >&6; }<br>
@@ -16421,6 +16543,182 @@ else<br>
<br>
 fi<br>
<br>
+if test "$llvm_cv_enable_curses" = "yes" ; then<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+for ac_header in curses.h ncurses.h ncursesw.h ncurses/curses.h ncursesw/curses.h<br>
+do<br>
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`<br>
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then<br>
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5<br>
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }<br>
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then<br>
+  echo $ECHO_N "(cached) $ECHO_C" >&6<br>
+fi<br>
+ac_res=`eval echo '${'$as_ac_Header'}'`<br>
+              { echo "$as_me:$LINENO: result: $ac_res" >&5<br>
+echo "${ECHO_T}$ac_res" >&6; }<br>
+else<br>
+  # Is the header compilable?<br>
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5<br>
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }<br>
+cat >conftest.$ac_ext <<_ACEOF<br>
+/* confdefs.h.  */<br>
+_ACEOF<br>
+cat confdefs.h >>conftest.$ac_ext<br>
+cat >>conftest.$ac_ext <<_ACEOF<br>
+/* end confdefs.h.  */<br>
+$ac_includes_default<br>
+#include <$ac_header><br>
+_ACEOF<br>
+rm -f conftest.$ac_objext<br>
+if { (ac_try="$ac_compile"<br>
+case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_compile") 2>conftest.er1<br>
+  ac_status=$?<br>
+  grep -v '^ *+' conftest.er1 >conftest.err<br>
+  rm -f conftest.er1<br>
+  cat conftest.err >&5<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); } &&<br>
+        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'<br>
+  { (case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_try") 2>&5<br>
+  ac_status=$?<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); }; } &&<br>
+        { ac_try='test -s conftest.$ac_objext'<br>
+  { (case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_try") 2>&5<br>
+  ac_status=$?<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); }; }; then<br>
+  ac_header_compiler=yes<br>
+else<br>
+  echo "$as_me: failed program was:" >&5<br>
+sed 's/^/| /' conftest.$ac_ext >&5<br>
+<br>
+       ac_header_compiler=no<br>
+fi<br>
+<br>
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext<br>
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5<br>
+echo "${ECHO_T}$ac_header_compiler" >&6; }<br>
+<br>
+# Is the header present?<br>
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5<br>
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }<br>
+cat >conftest.$ac_ext <<_ACEOF<br>
+/* confdefs.h.  */<br>
+_ACEOF<br>
+cat confdefs.h >>conftest.$ac_ext<br>
+cat >>conftest.$ac_ext <<_ACEOF<br>
+/* end confdefs.h.  */<br>
+#include <$ac_header><br>
+_ACEOF<br>
+if { (ac_try="$ac_cpp conftest.$ac_ext"<br>
+case "(($ac_try" in<br>
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;<br>
+  *) ac_try_echo=$ac_try;;<br>
+esac<br>
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5<br>
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1<br>
+  ac_status=$?<br>
+  grep -v '^ *+' conftest.er1 >conftest.err<br>
+  rm -f conftest.er1<br>
+  cat conftest.err >&5<br>
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5<br>
+  (exit $ac_status); } >/dev/null; then<br>
+  if test -s conftest.err; then<br>
+    ac_cpp_err=$ac_c_preproc_warn_flag<br>
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag<br>
+  else<br>
+    ac_cpp_err=<br>
+  fi<br>
+else<br>
+  ac_cpp_err=yes<br>
+fi<br>
+if test -z "$ac_cpp_err"; then<br>
+  ac_header_preproc=yes<br>
+else<br>
+  echo "$as_me: failed program was:" >&5<br>
+sed 's/^/| /' conftest.$ac_ext >&5<br>
+<br>
+  ac_header_preproc=no<br>
+fi<br>
+<br>
+rm -f conftest.err conftest.$ac_ext<br>
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5<br>
+echo "${ECHO_T}$ac_header_preproc" >&6; }<br>
+<br>
+# So?  What about this header?<br>
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in<br>
+  yes:no: )<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5<br>
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5<br>
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}<br>
+    ac_header_preproc=yes<br>
+    ;;<br>
+  no:yes:* )<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5<br>
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5<br>
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5<br>
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5<br>
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5<br>
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}<br>
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5<br>
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}<br>
+    ( cat <<\_ASBOX<br>
+## ------------------------------------ ##<br>
+## Report this to <a href="http://llvm.org/bugs/" target="_blank">http://llvm.org/bugs/</a> ##<br>
+## ------------------------------------ ##<br>
+_ASBOX<br>
+     ) | sed "s/^/$as_me: WARNING:     /" >&2<br>
+    ;;<br>
+esac<br>
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5<br>
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }<br>
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then<br>
+  echo $ECHO_N "(cached) $ECHO_C" >&6<br>
+else<br>
+  eval "$as_ac_Header=\$ac_header_preproc"<br>
+fi<br>
+ac_res=`eval echo '${'$as_ac_Header'}'`<br>
+              { echo "$as_me:$LINENO: result: $ac_res" >&5<br>
+echo "${ECHO_T}$ac_res" >&6; }<br>
+<br>
+fi<br>
+if test `eval echo '${'$as_ac_Header'}'` = yes; then<br>
+  cat >>confdefs.h <<_ACEOF<br>
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1<br>
+_ACEOF<br>
+<br>
+fi<br>
+<br>
+done<br>
+<br>
+fi<br>
+<br>
 if test "$llvm_cv_enable_libffi" = "yes" ; then<br>
<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/Config/config.h.cmake<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.cmake?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/Config/config.h.cmake (original)<br>
+++ llvm/trunk/include/llvm/Config/config.h.cmake Wed Aug  7 03:47:36 2013<br>
@@ -48,6 +48,12 @@<br>
 /* Define to 1 if you have the `closedir' function. */<br>
 #cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}<br>
<br>
+/* Define if curses provides the has_color() function on this platform. */<br>
+#cmakedefine HAVE_CURSES<br>
+<br>
+/* Define to 1 if you have the <curses.h> header file. */<br>
+#cmakedefine HAVE_CURSES_H<br>
+<br>
 /* Define to 1 if you have the <cxxabi.h> header file. */<br>
 #cmakedefine HAVE_CXXABI_H ${HAVE_CXXABI_H}<br>
<br>
@@ -256,6 +262,18 @@<br>
 /* Define if mmap() can map files into memory */<br>
 #undef HAVE_MMAP_FILE<br>
<br>
+/* Define to 1 if you have the <ncursesw/curses.h> header file. */<br>
+#cmakedefine HAVE_NCURSESW_CURSES_H<br>
+<br>
+/* Define to 1 if you have the <ncursesw.h> header file. */<br>
+#cmakedefine HAVE_NCURSESW_H<br>
+<br>
+/* Define to 1 if you have the <ncurses/curses.h> header file. */<br>
+#cmakedefine HAVE_NCURSES_CURSES_H<br>
+<br>
+/* Define to 1 if you have the <ncurses.h> header file. */<br>
+#cmakedefine HAVE_NCURSES_H<br>
+<br>
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */<br>
 #cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H}<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/Config/<a href="http://config.h.in" target="_blank">config.h.in</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.in?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Config/config.h.in?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/Config/<a href="http://config.h.in" target="_blank">config.h.in</a> (original)<br>
+++ llvm/trunk/include/llvm/Config/<a href="http://config.h.in" target="_blank">config.h.in</a> Wed Aug  7 03:47:36 2013<br>
@@ -69,6 +69,12 @@<br>
 /* can use __crashreporter_info__ */<br>
 #undef HAVE_CRASHREPORTER_INFO<br>
<br>
+/* Define if curses provides the has_color() function on this platform. */<br>
+#undef HAVE_CURSES<br>
+<br>
+/* Define to 1 if you have the <curses.h> header file. */<br>
+#undef HAVE_CURSES_H<br>
+<br>
 /* Define to 1 if you have the <cxxabi.h> header file. */<br>
 #undef HAVE_CXXABI_H<br>
<br>
@@ -282,6 +288,18 @@<br>
 /* Define if mmap() can map files into memory */<br>
 #undef HAVE_MMAP_FILE<br>
<br>
+/* Define to 1 if you have the <ncursesw/curses.h> header file. */<br>
+#undef HAVE_NCURSESW_CURSES_H<br>
+<br>
+/* Define to 1 if you have the <ncursesw.h> header file. */<br>
+#undef HAVE_NCURSESW_H<br>
+<br>
+/* Define to 1 if you have the <ncurses/curses.h> header file. */<br>
+#undef HAVE_NCURSES_CURSES_H<br>
+<br>
+/* Define to 1 if you have the <ncurses.h> header file. */<br>
+#undef HAVE_NCURSES_H<br>
+<br>
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */<br>
 #undef HAVE_NDIR_H<br>
<br>
<br>
Modified: llvm/trunk/lib/Support/Unix/Process.inc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Process.inc?rev=187874&r1=187873&r2=187874&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Process.inc?rev=187874&r1=187873&r2=187874&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Support/Unix/Process.inc (original)<br>
+++ llvm/trunk/lib/Support/Unix/Process.inc Wed Aug  7 03:47:36 2013<br>
@@ -13,6 +13,8 @@<br>
<br>
 #include "Unix.h"<br>
 #include "llvm/ADT/Hashing.h"<br>
+#include "llvm/Support/Mutex.h"<br>
+#include "llvm/Support/MutexGuard.h"<br>
 #include "llvm/Support/TimeValue.h"<br>
 #ifdef HAVE_SYS_TIME_H<br>
 #include <sys/time.h><br>
@@ -36,6 +38,25 @@<br>
 #  include <termios.h><br>
 #endif<br>
<br>
+// See if we can use curses to detect information about a terminal when<br>
+// connected to one.<br>
+#ifdef HAVE_CURSES<br>
+# if defined(HAVE_CURSES_H)<br>
+#  include <curses.h><br>
+# elif defined(HAVE_NCURSES_H)<br>
+#  include <ncurses.h><br>
+# elif defined(HAVE_NCURSESW_H)<br>
+#  include <ncursesw.h><br>
+# elif defined(HAVE_NCURSES_CURSES_H)<br>
+#  include <ncurses/curses.h><br>
+# elif defined(HAVE_NCURSESW_CURSES_H)<br>
+#  include <ncursesw/curses.h><br>
+# else<br>
+#  error Have a curses library but unable to find a curses header!<br>
+# endif<br>
+# include <term.h><br>
+#endif<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 //=== WARNING: Implementation here must contain only generic UNIX code that<br>
 //===          is guaranteed to work on *all* UNIX variants.<br>
@@ -245,22 +266,32 @@ unsigned Process::StandardErrColumns() {<br>
   return getColumns(2);<br>
 }<br>
<br>
-static bool terminalHasColors() {<br>
-  if (const char *term = std::getenv("TERM")) {<br>
-    // Most modern terminals support ANSI escape sequences for colors.<br>
-    // We could check terminfo, or have a list of known terms that support<br>
-    // colors, but that would be overkill.<br>
-    // The user can always ask for no colors by setting TERM to dumb, or<br>
-    // using a commandline flag.<br>
-    return strcmp(term, "dumb") != 0;<br>
-  }<br>
+static bool terminalHasColors(int fd) {<br>
+#ifdef HAVE_CURSES<br>
+  // First, acquire a global lock because the curses C routines are thread<br>
+  // hostile.<br>
+  static sys::Mutex M;<br>
+  MutexGuard G(M);<br>
+<br>
+  int errret = 0;<br>
+  if (setupterm((char *)0, fd, &errret) != OK)<br>
+    // Regardless of why, if we can't get terminfo, we shouldn't try to print<br>
+    // colors.<br>
+    return false;<br>
+<br>
+  // Test whether the terminal as set up supports color output.<br>
+  if (has_colors() == TRUE)<br>
+    return true;<br>
+#endif<br>
+<br>
+  // Otherwise, be conservative.<br>
   return false;<br>
 }<br>
<br>
 bool Process::FileDescriptorHasColors(int fd) {<br>
   // A file descriptor has colors if it is displayed and the terminal has<br>
   // colors.<br>
-  return FileDescriptorIsDisplayed(fd) && terminalHasColors();<br>
+  return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);<br>
 }<br>
<br>
 bool Process::StandardOutHasColors() {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>