From 26745696ef24b950d8ae1356f10a3d7dacb324e8 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 11 May 2009 18:05:52 +0000 Subject: [PATCH] Add terminal width detection to llvm::sys::Process. This is needed to fix Clang PRs 4148 and 4183. llvm-svn: 71448 --- autoconf/configure.ac | 2 +- cmake/config-ix.cmake | 3 ++ configure | 62 +++++++++++++++--------------- include/llvm/ADT/FoldingSet.h | 1 + include/llvm/Config/config.h.cmake | 5 ++- include/llvm/Config/config.h.in | 3 ++ include/llvm/System/Process.h | 13 +++++++ lib/System/Unix/Process.inc | 37 ++++++++++++++++++ lib/System/Win32/Process.inc | 16 ++++++++ 9 files changed, 110 insertions(+), 32 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 3c2cd3616a7..cebdc801822 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -826,7 +826,7 @@ AC_CHECK_HEADERS([dlfcn.h execinfo.h fcntl.h inttypes.h limits.h link.h]) AC_CHECK_HEADERS([malloc.h setjmp.h signal.h stdint.h unistd.h utime.h]) AC_CHECK_HEADERS([windows.h]) AC_CHECK_HEADERS([sys/mman.h sys/param.h sys/resource.h sys/time.h]) -AC_CHECK_HEADERS([sys/types.h malloc/malloc.h mach/mach.h]) +AC_CHECK_HEADERS([sys/types.h sys/ioctl.h malloc/malloc.h mach/mach.h]) if test "$ENABLE_THREADS" -eq 1 ; then AC_CHECK_HEADERS(pthread.h, AC_SUBST(HAVE_PTHREAD, 1), diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index 0d61f1e213e..7e4016fb34c 100755 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -26,6 +26,7 @@ check_include_file(stdlib.h HAVE_STDLIB_H) check_include_file(string.h HAVE_STRING_H) check_include_file(sys/dir.h HAVE_SYS_DIR_H) check_include_file(sys/dl.h HAVE_SYS_DL_H) +check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H) check_include_file(sys/mman.h HAVE_SYS_MMAN_H) check_include_file(sys/ndir.h HAVE_SYS_NDIR_H) check_include_file(sys/param.h HAVE_SYS_PARAM_H) @@ -43,9 +44,11 @@ check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) # function checks include(CheckSymbolExists) +include(CheckFunctionExists) check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE) check_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE) check_symbol_exists(setrlimit sys/resource.h HAVE_SETRLIMIT) +check_function_exists(isatty HAVE_ISATTY) check_symbol_exists(isinf cmath HAVE_ISINF_IN_CMATH) check_symbol_exists(isinf math.h HAVE_ISINF_IN_MATH_H) check_symbol_exists(isnan cmath HAVE_ISNAN_IN_CMATH) diff --git a/configure b/configure index a30e77a0654..fa1bc12ad95 100755 --- a/configure +++ b/configure @@ -897,10 +897,10 @@ F77 FFLAGS ac_ct_F77 LIBTOOL -LLVMGCC -LLVMGXX LLVMGCCCOMMAND LLVMGXXCOMMAND +LLVMGCC +LLVMGXX USE_UDIS86 HAVE_PTHREAD HUGE_VAL_SANITY @@ -5010,6 +5010,7 @@ if test "${with_llvmgxx+set}" = set; then WITH_LLVMGCCDIR="" fi + if test -n "$LLVMGCC"; then LLVMGCCCOMMAND="$LLVMGCC" fi @@ -10574,7 +10575,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext + echo '#line 12722 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -14436,11 +14437,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14425: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14440: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14429: \$? = $ac_status" >&5 + echo "$as_me:14444: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14704,11 +14705,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14693: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14708: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14697: \$? = $ac_status" >&5 + echo "$as_me:14712: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14808,11 +14809,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14797: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14812: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14801: \$? = $ac_status" >&5 + echo "$as_me:14816: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17260,7 +17261,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:19732: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:19721: \$? = $ac_status" >&5 + echo "$as_me:19736: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -19832,11 +19833,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:19821: $lt_compile\"" >&5) + (eval echo "\"\$as_me:19836: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:19825: \$? = $ac_status" >&5 + echo "$as_me:19840: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21402,11 +21403,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21391: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21406: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:21395: \$? = $ac_status" >&5 + echo "$as_me:21410: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -21506,11 +21507,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:21495: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21510: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:21499: \$? = $ac_status" >&5 + echo "$as_me:21514: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -23741,11 +23742,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23730: $lt_compile\"" >&5) + (eval echo "\"\$as_me:23745: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:23734: \$? = $ac_status" >&5 + echo "$as_me:23749: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24009,11 +24010,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23998: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24013: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:24002: \$? = $ac_status" >&5 + echo "$as_me:24017: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -24113,11 +24114,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:24102: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24117: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:24106: \$? = $ac_status" >&5 + echo "$as_me:24121: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -26821,12 +26822,12 @@ _ACEOF fi + if test "$WITH_LLVMGCCDIR" = "default" ; then LLVMGCC="llvm-gcc${EXEEXT}" LLVMGXX="llvm-g++${EXEEXT}" LLVMGCCCOMMAND="$LLVMGCC" LLVMGXXCOMMAND="$LLVMGXX" - LLVMGCCCOMMAND=$LLVMGCCCOMMAND LLVMGXXCOMMAND=$LLVMGXXCOMMAND @@ -29474,7 +29475,8 @@ done -for ac_header in sys/types.h malloc/malloc.h mach/mach.h + +for ac_header in sys/types.h sys/ioctl.h malloc/malloc.h mach/mach.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -34909,10 +34911,10 @@ F77!$F77$ac_delim FFLAGS!$FFLAGS$ac_delim ac_ct_F77!$ac_ct_F77$ac_delim LIBTOOL!$LIBTOOL$ac_delim -LLVMGCC!$LLVMGCC$ac_delim -LLVMGXX!$LLVMGXX$ac_delim LLVMGCCCOMMAND!$LLVMGCCCOMMAND$ac_delim LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim +LLVMGCC!$LLVMGCC$ac_delim +LLVMGXX!$LLVMGXX$ac_delim USE_UDIS86!$USE_UDIS86$ac_delim HAVE_PTHREAD!$HAVE_PTHREAD$ac_delim HUGE_VAL_SANITY!$HUGE_VAL_SANITY$ac_delim diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index d03d64b9ca4..e31e112d0e6 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -19,6 +19,7 @@ #include "llvm/Support/DataTypes.h" #include "llvm/ADT/SmallVector.h" #include +#include namespace llvm { class APFloat; diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index dac1856ea0b..443afb17873 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -164,7 +164,7 @@ #cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} /* Define to 1 if you have the `isatty' function. */ -#undef HAVE_ISATTY +#cmakedefine HAVE_ISATTY 1 /* Set to 1 if the isinf function is found in */ #cmakedefine HAVE_ISINF_IN_CMATH ${HAVE_ISINF_IN_CMATH} @@ -388,6 +388,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_DL_H ${HAVE_SYS_DL_H} +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_IOCTL_H ${HAVE_SYS_IOCTL_H} + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_MMAN_H ${} diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 805a07aff6e..f0522e51f1a 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -391,6 +391,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H diff --git a/include/llvm/System/Process.h b/include/llvm/System/Process.h index f98a3612c6c..ce19eb29819 100644 --- a/include/llvm/System/Process.h +++ b/include/llvm/System/Process.h @@ -94,6 +94,19 @@ namespace sys { /// the user rather than being put on a pipe or stored in a file. static bool StandardErrIsDisplayed(); + /// This function determines the number of columns in the window + /// if standard output is connected to a "tty" or "console" + /// window. If standard output is not connected to a tty or + /// console, or if the number of columns cannot be determined, + /// this routine returns zero. + static unsigned StandardOutColumns(); + + /// This function determines the number of columns in the window + /// if standard error is connected to a "tty" or "console" + /// window. If standard error is not connected to a tty or + /// console, or if the number of columns cannot be determined, + /// this routine returns zero. + static unsigned StandardErrColumns(); /// @} }; } diff --git a/lib/System/Unix/Process.inc b/lib/System/Unix/Process.inc index 8a2598bda4e..b1286b7bfcd 100644 --- a/lib/System/Unix/Process.inc +++ b/lib/System/Unix/Process.inc @@ -24,6 +24,9 @@ #ifdef HAVE_MALLOC_MALLOC_H #include #endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif //===----------------------------------------------------------------------===// //=== WARNING: Implementation here must contain only generic UNIX code that @@ -190,3 +193,37 @@ bool Process::StandardErrIsDisplayed() { // If we don't have isatty, just return false. return false; } + +static unsigned getColumns(int FileID) { + // If COLUMNS is defined in the environment, wrap to that many columns. + if (const char *ColumnsStr = std::getenv("COLUMNS")) { + int Columns = std::atoi(ColumnsStr); + if (Columns > 0) + return Columns; + } + + unsigned Columns = 0; + +#ifdef HAVE_SYS_IOCTL_H + // Try to determine the width of the terminal. + struct winsize ws; + if (ioctl(FileID, TIOCGWINSZ, &ws) == 0) + Columns = ws.ws_col; +#endif + + return Columns; +} + +unsigned Process::StandardOutColumns() { + if (!StandardOutIsDisplayed()) + return 0; + + return getColumns(1); +} + +unsigned Process::StandardErrColumns() { + if (!StandardErrIsDisplayed()) + return 0; + + return getColumns(2); +} diff --git a/lib/System/Win32/Process.inc b/lib/System/Win32/Process.inc index 157483a07ca..e1d7a9222f7 100644 --- a/lib/System/Win32/Process.inc +++ b/lib/System/Win32/Process.inc @@ -131,4 +131,20 @@ bool Process::StandardErrIsDisplayed() { return GetFileType((HANDLE)_get_osfhandle(2)) == FILE_TYPE_CHAR; } +unsigned Process::StandardOutColumns() { + unsigned Columns = 0; + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + Columns = csbi.dwSize.X; + return Columns; +} + +unsigned Process::StandardErrColumns() { + unsigned Columns = 0; + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi)) + Columns = csbi.dwSize.X; + return Columns; +} + }