HAL
progress_printer.cpp
Go to the documentation of this file.
2 
4 
5 #include <iostream>
6 #include <sstream>
7 #include <sys/ioctl.h> //ioctl() and TIOCGWINSZ
8 #include <unistd.h> // for STDOUT_FILENO
9 
11 
12 namespace hal
13 {
14  namespace dataflow
15  {
16  ProgressPrinter::ProgressPrinter(u32 max_message_size) : m_gui_message("dataflow analysis …"),
17  m_bar_width(0), m_max_message_size(max_message_size),
18  m_last_percentage(0), m_terminal_width(get_terminal_width())
19  {
20  if (m_terminal_width <= 8)
21  {
22  return;
23  }
24 
25  m_bar_width = m_terminal_width - 7;
26  if (max_message_size != 0)
27  {
28  m_bar_width -= max_message_size + 1;
29  }
30  reset();
31  }
32 
34  {
35  m_gui_message = message;
37  }
38 
40  {
42  if (percent < 0) percent = m_last_percentage;
43  if (percent > 99) percent = 99;
45  }
46 
47  void ProgressPrinter::print_progress_to_stderr(float progress, const std::string& message)
48  {
49  progress = std::clamp(progress, 0.f, 1.f);
50  m_last_percentage = (u32)(progress * 100.0f);
51 
52  if (m_terminal_width <= 8)
53  {
54  return;
55  }
56 
57  u32 pos = (u32)(m_bar_width * progress);
58 
59  if (pos <= m_printed_progress && m_last_message == message)
60  {
61  return;
62  }
63 
64  m_last_message = message;
65  m_printed_progress = pos;
66 
67  std::string bar;
68  if (pos)
69  {
70  bar += std::string(pos, '=');
71  }
72  if (pos < m_bar_width)
73  {
74  bar += '>';
75  }
76  if (pos + 1 < m_bar_width)
77  {
78  bar += std::string(m_bar_width - pos - 1, ' ');
79  }
80 
81  auto print_message = message;
82  if (print_message.size() > m_max_message_size)
83  {
84  if (m_max_message_size <= 3)
85  {
86  print_message = std::string(m_max_message_size, '.');
87  }
88  else
89  {
90  print_message = print_message.substr(0, m_max_message_size - 3) + "...";
91  }
92  }
93 
94  std::stringstream str;
95  str << "[" << bar << "] ";
96 
97  str << std::right << std::setw(3) << m_last_percentage << '%';
98 
99  if (!print_message.empty())
100  {
101  str << " " << print_message;
102  }
103 
104  auto output = str.str();
105 
106  std::cerr << output;
107  if (output.size() < (u32)m_terminal_width)
108  {
109  std::cerr << std::string(m_terminal_width - output.size(), ' ');
110  }
111 
112  std::cerr << "\r" << std::flush;
113  }
114 
116  {
117  if (m_terminal_width <= 8)
118  {
119  return;
120  }
121  std::cerr << std::string(m_terminal_width, ' ') << "\r" << std::flush;
122  }
123 
125  {
126  m_printed_progress = 0;
127  m_last_message = "$^äü+";
128  }
129 
130  int ProgressPrinter::get_terminal_width()
131  {
132  struct winsize size;
133  int retval = ioctl(STDERR_FILENO, TIOCGWINSZ, &size);
134  if (retval < 0)
135  {
136  return -1;
137  }
139  {
140  return -1;
141  }
142  return size.ws_col;
143  }
144  } // namespace dataflow
145 } // namespace hal
static std::function< void(int, const std::string &)> s_progress_indicator_function
ProgressPrinter(u32 max_message_size=0)
void print_message_to_gui(const std::string &message)
void print_progress_to_gui(int percent=-1)
void print_progress_to_stderr(float progress, const std::string &message="")
quint32 u32
message(VERBOSE "Qt5Widgets_LIBRARIES: ${Qt5Widgets_LIBRARIES}") elseif(NOT Qt5Widgets_FOUND) set(Missing_package "TRUE") if(APPLE AND CMAKE_HOST_APPLE) message(STATUS "To install qt5 on MacOS using homebrew run following command
Definition: CMakeLists.txt:15
const int dont_believe_in_terminal_width_bigger_than_this_value