REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestStringOutput.cxx
1#include "TRestStringOutput.h"
2
3#include "TRestStringHelper.h"
4
5using namespace std;
6
7#ifdef WIN32
8#include <Windows.h>
9#include <conio.h>
10#endif // WIN32
11
12#ifdef __APPLE__
13#include <unistd.h>
14#endif
15
16int Console::GetWidth() {
17#ifdef WIN32
18 CONSOLE_SCREEN_BUFFER_INFO csbi;
19 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
20 return csbi.srWindow.Right - csbi.srWindow.Left + 1;
21#else
22 if (isatty(fileno(stdout))) {
23 struct winsize w;
24 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
25 return w.ws_col;
26 }
27 return -1;
28#endif // WIN32
29}
30
31int Console::GetHeight() {
32#ifdef WIN32
33 CONSOLE_SCREEN_BUFFER_INFO csbi;
34 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
35 return csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
36#else
37 if (isatty(fileno(stdout))) {
38 struct winsize w;
39 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
40 return w.ws_row;
41 }
42 return -1;
43#endif // WIN32
44}
45
46bool Console::kbhit() {
47#ifdef WIN32
48 return _kbhit();
49#else
50 struct termios oldt, newt;
51 int ch;
52 int oldf;
53 tcgetattr(STDIN_FILENO, &oldt);
54 newt = oldt;
55 newt.c_lflag &= ~(ICANON | ECHO);
56 tcsetattr(STDIN_FILENO, TCSANOW, &newt);
57 oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
58 fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
59 ch = getchar();
60 tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
61 fcntl(STDIN_FILENO, F_SETFL, oldf);
62 if (ch != EOF) {
63 ungetc(ch, stdin);
64 return true;
65 }
66 return false;
67
68// int byteswaiting;
69// ioctl(0, FIONREAD, &byteswaiting);
70// return byteswaiting > 0;
71#endif
72}
73
74int Console::Read() { return getchar(); }
75
76int Console::ReadKey() {
77#ifdef WIN32
78 return _getch();
79#else
80 struct termios tm, tm_old;
81 int fd = 0, ch;
82
83 if (tcgetattr(fd, &tm) < 0) {
84 return -1;
85 }
86
87 tm_old = tm;
88 cfmakeraw(&tm);
89 if (tcsetattr(fd, TCSANOW, &tm) < 0) {
90 return -1;
91 }
92
93 ch = getchar();
94 if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {
95 return -1;
96 }
97
98 return ch;
99#endif
100}
101
102string Console::ReadLine() {
103 char a[500];
104 cin.getline(a, 500);
105 return string(a);
106}
107
108void Console::WriteLine(string content) {
109 printf("%s", content.c_str());
110 fflush(stdout);
111}
112
113void Console::CursorUp(int n) {
114 printf("\033[%dA", n);
115 fflush(stdout);
116}
117
118void Console::CursorDown(int n) {
119 printf("\033[%dB", n);
120 fflush(stdout);
121}
122
123void Console::CursorRight(int n) {
124 printf("\033[%dC", n);
125 fflush(stdout);
126}
127
128void Console::CursorLeft(int n) {
129 printf("\033[%dD", n);
130 fflush(stdout);
131}
132
133void Console::CursorToXY(int x, int y) {
134 printf("\033[%d%dH", x, y);
135 fflush(stdout);
136}
137
138void Console::ClearScreen() {
139 printf("\033[2J");
140 fflush(stdout);
141}
142
143void Console::ClearCurrentLine() {
144#ifdef WIN32
145 printf("\r");
146 fflush(stdout);
147#else
148 printf("\033[K");
149 fflush(stdout);
150#endif // WIN32
151}
152
153void Console::ClearLinesAfterCursor() {
154 printf("\033[s");
155 for (int i = 0; i < 50; i++) {
156 printf("\033[K");
157 CursorDown(1);
158 }
159 printf("\033[u");
160 fflush(stdout);
161}
162
163char mirrorchar(char c) {
164 switch (c) {
165 default:
166 return c;
167 case '<':
168 return '>';
169 case '>':
170 return '<';
171 case '[':
172 return ']';
173 case ']':
174 return '[';
175 case '{':
176 return '}';
177 case '}':
178 return '{';
179 case '(':
180 return ')';
181 case ')':
182 return '(';
183 case '\\':
184 return '/';
185 case '/':
186 return '\\';
187 case 'd':
188 return 'b';
189 case 'b':
190 return 'd';
191 case 'q':
192 return 'p';
193 case 'p':
194 return 'q';
195 }
196}
197
198#define TRestStringOutput_BestLength 100
199TRestStringOutput::TRestStringOutput(COLORCODE_TYPE _color, string formatter,
200 REST_Display_Orientation _orientation) {
201 iserror = false;
202 color = _color;
203 orientation = _orientation;
204 // check if is border expression
205 useborder = true;
206 if (formatter.size() < 2) {
207 useborder = false;
208 }
209 for (unsigned int i = 0; i < formatter.size() / 2; i++) {
210 if (mirrorchar(formatter[i]) != formatter[formatter.size() - i - 1]) {
211 useborder = false;
212 break;
213 }
214 }
215 if (formatter[formatter.size() / 2] != ' ') {
216 useborder = false;
217 }
218
219 if (useborder) {
220 formatstring = formatter.substr(0, formatter.size() / 2);
221 formatstring = Replace(formatstring, " ", "");
222 } else {
223 formatstring = formatter;
224 }
225
226 setlength(TRestStringOutput_BestLength);
227 resetstring();
228 if (length > 500 || length < 20) // unsupported console, we will fall back to compatibility modes
229 {
230 length = -1;
231 REST_Display_CompatibilityMode = true;
232 }
233
235}
236
237void TRestStringOutput::resetstring() {
238 buf.clear();
239 buf.str("");
240}
241
242string TRestStringOutput::FormattingPrintString(string input) {
243 if (input == "") return "";
244
245 // input: "=abc=", output "=============abc============="(length)
246 if (input[0] == input[input.size() - 1] &&
247 (input[0] == '=' || input[0] == '-' || input[0] == '*' || input[0] == '+')) {
248 return string(length, input[0]);
249 }
250
251 if (useborder) {
252 string output(length, ' ');
253
254 int Lstr = input.size();
255 int Lfmt = formatstring.size();
256
257 int startblank;
258 if (useborder || orientation == TRestStringOutput::REST_Display_Orientation::kMiddle) {
259 startblank = (length - Lstr) / 2;
260 } else {
261 startblank = Lfmt;
262 }
263 if (startblank < 0) {
264 startblank = 0;
265 }
266
267 string& border = formatstring;
268 for (int i = 0; i < Lfmt && i < length; i++) {
269 output[i] = border[i];
270 output[length - i - 1] = mirrorchar(border[i]);
271 }
272
273 for (int i = 0; i < Lstr; i++) {
274 if (startblank + i > length - 1) {
275 output[length - 3] = '.';
276 output[length - 2] = '.';
277 output[length - 1] = '.';
278 return output;
279 }
280 output[startblank + i] = input[i];
281 }
282
283 return output;
284 } else {
285 return formatstring + input;
286 }
287}
288
289void TRestStringOutput::setlength(int n) {
290 if (!REST_Display_CompatibilityMode) {
291 if (n >= Console::GetWidth() - 2) {
292 length = Console::GetWidth() - 2;
293 } else if (n <= 0) {
294 length = Console::GetWidth() - 2;
295 } else {
296 length = n;
297 }
298 } else {
299 length = n;
300 }
301}
302
303#ifdef WIN32
304// use >> 4 << 4 to extract first 4 bytes from COLOR_RESET, which means the background color
305#define SET_COLOR(color) \
306 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (COLOR_RESET >> 4 << 4) + color);
307#define RESET_COLOR() SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), COLOR_RESET);
308#else
309#define SET_COLOR(color) std::cout << color;
310#define RESET_COLOR() std::cout << COLOR_RESET;
311#endif // WIN32
312
313void TRestStringOutput::flushstring() {
314 if (REST_Display_CompatibilityMode) // this means we are using condor
315 {
316 std::cout << buf.str() << std::endl;
317 } else {
318 Console::ClearCurrentLine();
319 if (orientation == TRestStringOutput::REST_Display_Orientation::kMiddle) {
320 // we always reset the length of TRestStringOutput in case the console is resized
321 setlength(TRestStringOutput_BestLength);
322 int blankwidth = (Console::GetWidth() - 2 - length) / 2;
323
324 SET_COLOR(color);
325 std::cout << string(blankwidth, ' ') << FormattingPrintString(buf.str())
326 << string(blankwidth, ' ');
327 RESET_COLOR()
328 std::cout << std::endl;
329 } else {
330 SET_COLOR(color);
331 std::cout << FormattingPrintString(buf.str());
332 RESET_COLOR()
333 std::cout << std::endl;
334 }
335 }
336 resetstring();
337}
338
339TRestStringOutput& TRestStringOutput::operator<<(void (*pfunc)(TRestStringOutput&)) {
340 if (gVerbose >= verbose) {
341 ((*pfunc)(*this));
342 }
343 return *this;
344}
@ REST_Essential
+show some essential information, as well as warnings
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any occurences of thisSring by byThisString inside string in.