]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
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 | ||
7 | #ifndef BOOST_HISTOGRAM_DETAIL_TERM_INFO_HPP | |
8 | #define BOOST_HISTOGRAM_DETAIL_TERM_INFO_HPP | |
9 | ||
10 | #include <algorithm> | |
11 | ||
12 | #if defined __has_include | |
13 | #if __has_include(<sys/ioctl.h>) && __has_include(<unistd.h>) | |
14 | #include <sys/ioctl.h> | |
15 | #include <unistd.h> | |
16 | #endif | |
17 | #endif | |
18 | #include <boost/config.hpp> | |
19 | #include <cstdlib> | |
20 | #include <cstring> | |
21 | ||
22 | namespace boost { | |
23 | namespace histogram { | |
24 | namespace detail { | |
25 | ||
26 | namespace term_info { | |
27 | class env_t { | |
28 | public: | |
29 | env_t(const char* key) { | |
30 | #if defined(BOOST_MSVC) // msvc complains about using std::getenv | |
31 | _dupenv_s(&data_, &size_, key); | |
32 | #else | |
33 | data_ = std::getenv(key); | |
34 | if (data_) size_ = std::strlen(data_); | |
35 | #endif | |
36 | } | |
37 | ||
38 | ~env_t() { | |
39 | #if defined(BOOST_MSVC) | |
40 | std::free(data_); | |
41 | #endif | |
42 | } | |
43 | ||
44 | bool contains(const char* s) { | |
45 | const std::size_t n = std::strlen(s); | |
46 | if (size_ < n) return false; | |
47 | return std::strstr(data_, s); | |
48 | } | |
49 | ||
50 | operator bool() { return size_ > 0; } | |
51 | ||
52 | explicit operator int() { return size_ ? std::atoi(data_) : 0; } | |
53 | ||
54 | const char* data() const { return data_; } | |
55 | ||
56 | private: | |
57 | char* data_; | |
58 | std::size_t size_ = 0; | |
59 | }; | |
60 | ||
61 | inline bool utf8() { | |
62 | // return false only if LANG exists and does not contain the string UTF | |
63 | env_t env("LANG"); | |
64 | bool b = true; | |
65 | if (env) b = env.contains("UTF") || env.contains("utf"); | |
66 | return b; | |
67 | } | |
68 | ||
69 | inline int width() { | |
70 | int w = 0; | |
71 | #if defined TIOCGWINSZ | |
72 | struct winsize ws; | |
73 | ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); | |
74 | w = (std::max)(static_cast<int>(ws.ws_col), 0); // not sure if ws_col can be less than 0 | |
75 | #endif | |
76 | env_t env("COLUMNS"); | |
77 | const int col = (std::max)(static_cast<int>(env), 0); | |
78 | // if both t and w are set, COLUMNS may be used to restrict width | |
79 | return w == 0 ? col : (std::min)(col, w); | |
80 | } | |
81 | } // namespace term_info | |
82 | ||
83 | } // namespace detail | |
84 | } // namespace histogram | |
85 | } // namespace boost | |
86 | ||
87 | #endif |