term_info.hpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2021 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_HISTOGRAM_DETAIL_TERM_INFO_HPP
  7. #define BOOST_HISTOGRAM_DETAIL_TERM_INFO_HPP
  8. #include <algorithm>
  9. #if defined __has_include
  10. #if __has_include(<sys/ioctl.h>) && __has_include(<unistd.h>)
  11. #include <sys/ioctl.h>
  12. #include <unistd.h>
  13. #endif
  14. #endif
  15. #include <boost/config.hpp>
  16. #include <cstdlib>
  17. #include <cstring>
  18. namespace boost {
  19. namespace histogram {
  20. namespace detail {
  21. namespace term_info {
  22. class env_t {
  23. public:
  24. env_t(const char* key) {
  25. #if defined(BOOST_MSVC) // msvc complains about using std::getenv
  26. _dupenv_s(&data_, &size_, key);
  27. #else
  28. data_ = std::getenv(key);
  29. if (data_) size_ = std::strlen(data_);
  30. #endif
  31. }
  32. ~env_t() {
  33. #if defined(BOOST_MSVC)
  34. std::free(data_);
  35. #endif
  36. }
  37. bool contains(const char* s) {
  38. const std::size_t n = std::strlen(s);
  39. if (size_ < n) return false;
  40. return std::strstr(data_, s);
  41. }
  42. operator bool() { return size_ > 0; }
  43. explicit operator int() { return size_ ? std::atoi(data_) : 0; }
  44. const char* data() const { return data_; }
  45. private:
  46. char* data_;
  47. std::size_t size_ = 0;
  48. };
  49. inline bool utf8() {
  50. // return false only if LANG exists and does not contain the string UTF
  51. env_t env("LANG");
  52. bool b = true;
  53. if (env) b = env.contains("UTF") || env.contains("utf");
  54. return b;
  55. }
  56. inline int width() {
  57. int w = 0;
  58. #if defined TIOCGWINSZ
  59. struct winsize ws;
  60. ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
  61. w = (std::max)(static_cast<int>(ws.ws_col), 0); // not sure if ws_col can be less than 0
  62. #endif
  63. env_t env("COLUMNS");
  64. const int col = (std::max)(static_cast<int>(env), 0);
  65. // if both t and w are set, COLUMNS may be used to restrict width
  66. return w == 0 ? col : (std::min)(col, w);
  67. }
  68. } // namespace term_info
  69. } // namespace detail
  70. } // namespace histogram
  71. } // namespace boost
  72. #endif