console.hpp
Go to the documentation of this file.
1 
12 #ifndef ecl_console_TERMCOLOR_HPP_
13 #define ecl_console_TERMCOLOR_HPP_
14 
15 // the following snippet of code detects the current OS and
16 // defines the appropriate macro that is used to wrap some
17 // platform specific things
18 #if defined(_WIN32) || defined(_WIN64)
19 # define OS_WINDOWS
20 #elif defined(__APPLE__)
21 # define OS_MACOS
22 #elif defined(linux) || defined(__linux)
23 # define OS_LINUX
24 #else
25 # error "unsupported platform"
26 #endif
27 
28 
29 // This headers provides the `isatty()`/`fileno()` functions,
30 // which are used for testing whether a standart stream refers
31 // to the terminal. As for Windows, we also need WinApi funcs
32 // for changing colors attributes of the terminal.
33 #if defined(OS_MACOS) || defined(OS_LINUX)
34 # include <unistd.h>
35 #elif defined(OS_WINDOWS)
36 # include <io.h>
37 # include <windows.h>
38 #endif
39 
40 #include <iostream>
41 #include <cstdio>
42 
43 namespace ecl
44 {
45  // Forward declaration of the `console` namespace.
46  // All comments are below.
47  namespace console
48  {
49  inline FILE* get_standard_stream(const std::ostream& stream);
50  inline bool is_atty(const std::ostream& stream);
51 
52  #if defined(OS_WINDOWS)
53  void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
54  #endif
55  }
56 
57 
58  inline
59  std::ostream& reset(std::ostream& stream)
60  {
61  if (console::is_atty(stream))
62  {
63  #if defined(OS_MACOS) || defined(OS_LINUX)
64  stream << "\033[00m";
65  #elif defined(OS_WINDOWS)
66  console::win_change_attributes(stream, -1, -1);
67  #endif
68  }
69  return stream;
70  }
71 
72 
73  inline
74  std::ostream& bold(std::ostream& stream)
75  {
76  if (console::is_atty(stream))
77  {
78  #if defined(OS_MACOS) || defined(OS_LINUX)
79  stream << "\033[1m";
80  #elif defined(OS_WINDOWS)
81  #endif
82  }
83  return stream;
84  }
85 
86 
87  inline
88  std::ostream& dark(std::ostream& stream)
89  {
90  if (console::is_atty(stream))
91  {
92  #if defined(OS_MACOS) || defined(OS_LINUX)
93  stream << "\033[2m";
94  #elif defined(OS_WINDOWS)
95  #endif
96  }
97  return stream;
98  }
99 
100 
101  inline
102  std::ostream& underline(std::ostream& stream)
103  {
104  if (console::is_atty(stream))
105  {
106  #if defined(OS_MACOS) || defined(OS_LINUX)
107  stream << "\033[4m";
108  #elif defined(OS_WINDOWS)
109  #endif
110  }
111  return stream;
112  }
113 
114 
115  inline
116  std::ostream& blink(std::ostream& stream)
117  {
118  if (console::is_atty(stream))
119  {
120  #if defined(OS_MACOS) || defined(OS_LINUX)
121  stream << "\033[5m";
122  #elif defined(OS_WINDOWS)
123  #endif
124  }
125  return stream;
126  }
127 
128 
129  inline
130  std::ostream& reverse(std::ostream& stream)
131  {
132  if (console::is_atty(stream))
133  {
134  #if defined(OS_MACOS) || defined(OS_LINUX)
135  stream << "\033[7m";
136  #elif defined(OS_WINDOWS)
137  #endif
138  }
139  return stream;
140  }
141 
142 
143  inline
144  std::ostream& concealed(std::ostream& stream)
145  {
146  if (console::is_atty(stream))
147  {
148  #if defined(OS_MACOS) || defined(OS_LINUX)
149  stream << "\033[8m";
150  #elif defined(OS_WINDOWS)
151  #endif
152  }
153  return stream;
154  }
155 
156 
157  inline
158  std::ostream& grey(std::ostream& stream)
159  {
160  if (console::is_atty(stream))
161  {
162  #if defined(OS_MACOS) || defined(OS_LINUX)
163  stream << "\033[30m";
164  #elif defined(OS_WINDOWS)
165  console::win_change_attributes(stream,
166  0 // grey (black)
167  );
168  #endif
169  }
170  return stream;
171  }
172 
173  inline
174  std::ostream& red(std::ostream& stream)
175  {
176  if (console::is_atty(stream))
177  {
178  #if defined(OS_MACOS) || defined(OS_LINUX)
179  stream << "\033[31m";
180  #elif defined(OS_WINDOWS)
181  console::win_change_attributes(stream,
182  FOREGROUND_RED
183  );
184  #endif
185  }
186  return stream;
187  }
188 
189  inline
190  std::ostream& green(std::ostream& stream)
191  {
192  if (console::is_atty(stream))
193  {
194  #if defined(OS_MACOS) || defined(OS_LINUX)
195  stream << "\033[32m";
196  #elif defined(OS_WINDOWS)
197  console::win_change_attributes(stream,
198  FOREGROUND_GREEN
199  );
200  #endif
201  }
202  return stream;
203  }
204 
205  inline
206  std::ostream& yellow(std::ostream& stream)
207  {
208  if (console::is_atty(stream))
209  {
210  #if defined(OS_MACOS) || defined(OS_LINUX)
211  stream << "\033[33m";
212  #elif defined(OS_WINDOWS)
213  console::win_change_attributes(stream,
214  FOREGROUND_GREEN | FOREGROUND_RED
215  );
216  #endif
217  }
218  return stream;
219  }
220 
221  inline
222  std::ostream& blue(std::ostream& stream)
223  {
224  if (console::is_atty(stream))
225  {
226  #if defined(OS_MACOS) || defined(OS_LINUX)
227  stream << "\033[34m";
228  #elif defined(OS_WINDOWS)
229  console::win_change_attributes(stream,
230  FOREGROUND_BLUE
231  );
232  #endif
233  }
234  return stream;
235  }
236 
237  inline
238  std::ostream& magenta(std::ostream& stream)
239  {
240  if (console::is_atty(stream))
241  {
242  #if defined(OS_MACOS) || defined(OS_LINUX)
243  stream << "\033[35m";
244  #elif defined(OS_WINDOWS)
245  console::win_change_attributes(stream,
246  FOREGROUND_BLUE | FOREGROUND_RED
247  );
248  #endif
249  }
250  return stream;
251  }
252 
253  inline
254  std::ostream& cyan(std::ostream& stream)
255  {
256  if (console::is_atty(stream))
257  {
258  #if defined(OS_MACOS) || defined(OS_LINUX)
259  stream << "\033[36m";
260  #elif defined(OS_WINDOWS)
261  console::win_change_attributes(stream,
262  FOREGROUND_BLUE | FOREGROUND_GREEN
263  );
264  #endif
265  }
266  return stream;
267  }
268 
269  inline
270  std::ostream& white(std::ostream& stream)
271  {
272  if (console::is_atty(stream))
273  {
274  #if defined(OS_MACOS) || defined(OS_LINUX)
275  stream << "\033[37m";
276  #elif defined(OS_WINDOWS)
277  console::win_change_attributes(stream,
278  FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
279  );
280  #endif
281  }
282  return stream;
283  }
284 
285 
286 
287  inline
288  std::ostream& on_grey(std::ostream& stream)
289  {
290  if (console::is_atty(stream))
291  {
292  #if defined(OS_MACOS) || defined(OS_LINUX)
293  stream << "\033[40m";
294  #elif defined(OS_WINDOWS)
295  console::win_change_attributes(stream, -1,
296  0 // grey (black)
297  );
298  #endif
299  }
300  return stream;
301  }
302 
303  inline
304  std::ostream& on_red(std::ostream& stream)
305  {
306  if (console::is_atty(stream))
307  {
308  #if defined(OS_MACOS) || defined(OS_LINUX)
309  stream << "\033[41m";
310  #elif defined(OS_WINDOWS)
311  console::win_change_attributes(stream, -1,
312  BACKGROUND_RED
313  );
314  #endif
315  }
316  return stream;
317  }
318 
319  inline
320  std::ostream& on_green(std::ostream& stream)
321  {
322  if (console::is_atty(stream))
323  {
324  #if defined(OS_MACOS) || defined(OS_LINUX)
325  stream << "\033[42m";
326  #elif defined(OS_WINDOWS)
327  console::win_change_attributes(stream, -1,
328  BACKGROUND_GREEN
329  );
330  #endif
331  }
332  return stream;
333  }
334 
335  inline
336  std::ostream& on_yellow(std::ostream& stream)
337  {
338  if (console::is_atty(stream))
339  {
340  #if defined(OS_MACOS) || defined(OS_LINUX)
341  stream << "\033[43m";
342  #elif defined(OS_WINDOWS)
343  console::win_change_attributes(stream, -1,
344  BACKGROUND_GREEN | BACKGROUND_RED
345  );
346  #endif
347  }
348  return stream;
349  }
350 
351  inline
352  std::ostream& on_blue(std::ostream& stream)
353  {
354  if (console::is_atty(stream))
355  {
356  #if defined(OS_MACOS) || defined(OS_LINUX)
357  stream << "\033[44m";
358  #elif defined(OS_WINDOWS)
359  console::win_change_attributes(stream, -1,
360  BACKGROUND_BLUE
361  );
362  #endif
363  }
364  return stream;
365  }
366 
367  inline
368  std::ostream& on_magenta(std::ostream& stream)
369  {
370  if (console::is_atty(stream))
371  {
372  #if defined(OS_MACOS) || defined(OS_LINUX)
373  stream << "\033[45m";
374  #elif defined(OS_WINDOWS)
375  console::win_change_attributes(stream, -1,
376  BACKGROUND_BLUE | BACKGROUND_RED
377  );
378  #endif
379  }
380  return stream;
381  }
382 
383  inline
384  std::ostream& on_cyan(std::ostream& stream)
385  {
386  if (console::is_atty(stream))
387  {
388  #if defined(OS_MACOS) || defined(OS_LINUX)
389  stream << "\033[46m";
390  #elif defined(OS_WINDOWS)
391  console::win_change_attributes(stream, -1,
392  BACKGROUND_GREEN | BACKGROUND_BLUE
393  );
394  #endif
395  }
396  return stream;
397  }
398 
399  inline
400  std::ostream& on_white(std::ostream& stream)
401  {
402  if (console::is_atty(stream))
403  {
404  #if defined(OS_MACOS) || defined(OS_LINUX)
405  stream << "\033[47m";
406  #elif defined(OS_WINDOWS)
407  console::win_change_attributes(stream, -1,
408  BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
409  );
410  #endif
411  }
412 
413  return stream;
414  }
415 
416 
417 
422  namespace console
423  {
427  inline
428  FILE* get_standard_stream(const std::ostream& stream)
429  {
430  if (&stream == &std::cout)
431  return stdout;
432  else if (&stream == &std::cerr)
433  return stderr;
434  return nullptr;
435  }
436 
437 
440  inline
441  bool is_atty(const std::ostream& stream)
442  {
443  // DJS : don't worry about strict checking so we can use this with
444  // stringstreams. Upstream issue at https://github.com/ikalnitsky/termcolor/issues/5
445  return true;
446 
447  FILE* std_stream = get_standard_stream(stream);
448 
449 
450  #if defined(OS_MACOS) || defined(OS_LINUX)
451  return ::isatty(fileno(std_stream));
452  #elif defined(OS_WINDOWS)
453  return ::_isatty(_fileno(std_stream));
454  #endif
455  }
456 
457 
458  #if defined(OS_WINDOWS)
459  void win_change_attributes(std::ostream& stream, int foreground, int background)
462  {
463  // yeah, i know.. it's ugly, it's windows.
464  static WORD defaultAttributes = 0;
465 
466  // get terminal handle
467  HANDLE hTerminal = INVALID_HANDLE_VALUE;
468  if (&stream == &std::cout)
469  hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
470  else if (&stream == &std::cerr)
471  hTerminal = GetStdHandle(STD_ERROR_HANDLE);
472 
473  // save default terminal attributes if it unsaved
474  if (!defaultAttributes)
475  {
476  CONSOLE_SCREEN_BUFFER_INFO info;
477  if (!GetConsoleScreenBufferInfo(hTerminal, &info))
478  return;
479  defaultAttributes = info.wAttributes;
480  }
481 
482  // restore all default settings
483  if (foreground == -1 && background == -1)
484  {
485  SetConsoleTextAttribute(hTerminal, defaultAttributes);
486  return;
487  }
488 
489  // get current settings
490  CONSOLE_SCREEN_BUFFER_INFO info;
491  if (!GetConsoleScreenBufferInfo(hTerminal, &info))
492  return;
493 
494  if (foreground != -1)
495  {
496  info.wAttributes &= ~(info.wAttributes & 0x0F);
497  info.wAttributes |= static_cast<WORD>(foreground);
498  }
499 
500  if (background != -1)
501  {
502  info.wAttributes &= ~(info.wAttributes & 0xF0);
503  info.wAttributes |= static_cast<WORD>(background);
504  }
505 
506  SetConsoleTextAttribute(hTerminal, info.wAttributes);
507  }
508  #endif // OS_WINDOWS
509 
510  } // namespace console
511 
512 } // namespace ecl
513 
514 
515 #undef OS_WINDOWS
516 #undef OS_MACOS
517 #undef OS_LINUX
518 
519 #endif // ecl_console_TERMCOLOR_HPP_
ecl


ecl_console
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:13:54