Teonet library  0.4.7
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
rlutil.h
Go to the documentation of this file.
1 #pragma once
2 
22 #if 0
26 #define RLUTIL_USE_ANSI
27 #endif
28 
33 #if 0
34 #define RLUTIL_STRING_T char*
35 #endif
36 
37 #ifdef __cplusplus
38  #include <iostream>
40  #include <string>
41  #include <sstream>
43  namespace rlutil {
44  static void locate(int x, int y);
45  }
46 #else
47  static void locate(int x, int y); // Forward declare for C to avoid warnings
48 #endif // __cplusplus
49 
50 #ifndef RLUTIL_INLINE
51  #ifdef _MSC_VER
52  #define RLUTIL_INLINE __inline
53  #else
54  #define RLUTIL_INLINE __inline__
55  #endif
56 #endif
57 
58 // #include "fillio.h"
59  #include "sys/socket.h"
60 
61 #ifdef _WIN32
62  #include <windows.h> // for WinAPI and Sleep()
63  #define _NO_OLDNAMES // for MinGW compatibility
64  #include <conio.h> // for getch() and kbhit()
65  #define getch _getch
66  #define kbhit _kbhit
67 #else
68  #ifdef __cplusplus
69  #include <cstdio> // for getch()
70  #else // __cplusplus
71  #include <stdio.h> // for getch()
72  #endif // __cplusplus
73  #include <termios.h> // for getch() and kbhit()
74  #include <unistd.h> // for getch(), kbhit() and (u)sleep()
75  #include <sys/ioctl.h> // for getkey()
76  #include <sys/types.h> // for kbhit()
77  #include <sys/time.h> // for kbhit()
78 
82 static RLUTIL_INLINE int getch(void) {
83  // Here be magic.
84  struct termios oldt, newt;
85  int ch;
86  tcgetattr(STDIN_FILENO, &oldt);
87  newt = oldt;
88  newt.c_lflag &= ~(ICANON | ECHO);
89  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
90  ch = getchar();
91  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
92  return ch;
93 }
94 
98 static RLUTIL_INLINE int kbhit(void) {
99  // Here be dragons.
100  static struct termios oldt, newt;
101  int cnt = 0;
102  tcgetattr(STDIN_FILENO, &oldt);
103  newt = oldt;
104  newt.c_lflag &= ~(ICANON | ECHO);
105  newt.c_iflag = 0; // input mode
106  newt.c_oflag = 0; // output mode
107  newt.c_cc[VMIN] = 1; // minimum time to wait
108  newt.c_cc[VTIME] = 1; // minimum characters to wait for
109  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
110  ioctl(0, FIONREAD, &cnt); // Read count
111  struct timeval tv;
112  tv.tv_sec = 0;
113  tv.tv_usec = 100;
114  select(STDIN_FILENO+1, NULL, NULL, NULL, &tv); // A small time delay
115  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
116  return cnt; // Return number of characters
117 }
118 #endif // _WIN32
119 
120 #ifndef gotoxy
121 static RLUTIL_INLINE void gotoxy(int x, int y) {
124  #ifdef __cplusplus
125  rlutil::
126  #endif
127  locate(x,y);
128 }
129 #endif // gotoxy
130 
131 #ifdef __cplusplus
132 namespace rlutil {
137 #endif
138 
145 #ifdef __cplusplus
146  #ifndef RLUTIL_STRING_T
147  typedef std::string RLUTIL_STRING_T;
148  #endif // RLUTIL_STRING_T
149 
150  inline void RLUTIL_PRINT(RLUTIL_STRING_T st) { std::cout << st; }
151 
152 #else // __cplusplus
153  #ifndef RLUTIL_STRING_T
154  typedef char* RLUTIL_STRING_T;
155  #endif // RLUTIL_STRING_T
156 
157  #define RLUTIL_PRINT(st) printf("%s", st)
158 #endif // __cplusplus
159 
180 enum {
198 };
199 
200 #define _ANSI_NONE "\033[0m"
201 #define _ANSI_CLS "\033[2J"
202 #define _ANSI_BLACK "\033[22;30m"
203 #define _ANSI_RED "\033[22;31m"
204 #define _ANSI_GREEN "\033[22;32m"
205 #define _ANSI_BROWN "\033[22;33m"
206 #define _ANSI_BLUE "\033[22;34m"
207 #define _ANSI_MAGENTA "\033[22;35m"
208 #define _ANSI_CYAN "\033[22;36m"
209 #define _ANSI_GREY "\033[22;37m"
210 #define _ANSI_DARKGREY "\033[01;30m"
211 #define _ANSI_LIGHTRED "\033[01;31m"
212 #define _ANSI_LIGHTGREEN "\033[01;32m"
213 #define _ANSI_YELLOW "\033[01;33m"
214 #define _ANSI_LIGHTBLUE "\033[01;34m"
215 #define _ANSI_LIGHTMAGENTA "\033[01;35m"
216 #define _ANSI_LIGHTCYAN "\033[01;36m"
217 #define _ANSI_WHITE "\033[01;37m"
218 
240 static const RLUTIL_STRING_T ANSI_NONE = "\033[0m";
241 static const RLUTIL_STRING_T ANSI_CLS = "\033[2J";
242 static const RLUTIL_STRING_T ANSI_BLACK = "\033[22;30m";
243 static const RLUTIL_STRING_T ANSI_RED = "\033[22;31m";
244 static const RLUTIL_STRING_T ANSI_GREEN = "\033[22;32m";
245 static const RLUTIL_STRING_T ANSI_BROWN = "\033[22;33m";
246 static const RLUTIL_STRING_T ANSI_BLUE = "\033[22;34m";
247 static const RLUTIL_STRING_T ANSI_MAGENTA = "\033[22;35m";
248 static const RLUTIL_STRING_T ANSI_CYAN = "\033[22;36m";
249 static const RLUTIL_STRING_T ANSI_GREY = "\033[22;37m";
250 static const RLUTIL_STRING_T ANSI_DARKGREY = "\033[01;30m";
251 static const RLUTIL_STRING_T ANSI_LIGHTRED = "\033[01;31m";
252 static const RLUTIL_STRING_T ANSI_LIGHTGREEN = "\033[01;32m";
253 static const RLUTIL_STRING_T ANSI_YELLOW = "\033[01;33m";
254 static const RLUTIL_STRING_T ANSI_LIGHTBLUE = "\033[01;34m";
255 static const RLUTIL_STRING_T ANSI_LIGHTMAGENTA = "\033[01;35m";
256 static const RLUTIL_STRING_T ANSI_LIGHTCYAN = "\033[01;36m";
257 static const RLUTIL_STRING_T ANSI_WHITE = "\033[01;37m";
258 
299 static const int KEY_ESCAPE = 0;
300 static const int KEY_ENTER = 1;
301 static const int KEY_SPACE = 32;
302 
303 static const int KEY_INSERT = 2;
304 static const int KEY_HOME = 3;
305 static const int KEY_PGUP = 4;
306 static const int KEY_DELETE = 5;
307 static const int KEY_END = 6;
308 static const int KEY_PGDOWN = 7;
309 
310 static const int KEY_UP = 14;
311 static const int KEY_DOWN = 15;
312 static const int KEY_LEFT = 16;
313 static const int KEY_RIGHT = 17;
314 
315 static const int KEY_F1 = 18;
316 static const int KEY_F2 = 19;
317 static const int KEY_F3 = 20;
318 static const int KEY_F4 = 21;
319 static const int KEY_F5 = 22;
320 static const int KEY_F6 = 23;
321 static const int KEY_F7 = 24;
322 static const int KEY_F8 = 25;
323 static const int KEY_F9 = 26;
324 static const int KEY_F10 = 27;
325 static const int KEY_F11 = 28;
326 static const int KEY_F12 = 29;
327 
328 static const int KEY_NUMDEL = 30;
329 static const int KEY_NUMPAD0 = 31;
330 static const int KEY_NUMPAD1 = 127;
331 static const int KEY_NUMPAD2 = 128;
332 static const int KEY_NUMPAD3 = 129;
333 static const int KEY_NUMPAD4 = 130;
334 static const int KEY_NUMPAD5 = 131;
335 static const int KEY_NUMPAD6 = 132;
336 static const int KEY_NUMPAD7 = 133;
337 static const int KEY_NUMPAD8 = 134;
338 static const int KEY_NUMPAD9 = 135;
339 
347 static RLUTIL_INLINE int getkey(void) {
348  #ifndef _WIN32
349  int cnt = kbhit(); // for ANSI escapes processing
350  #endif
351  int k = getch();
352  switch(k) {
353  case 0: {
354  int kk;
355  switch (kk = getch()) {
356  case 71: return KEY_NUMPAD7;
357  case 72: return KEY_NUMPAD8;
358  case 73: return KEY_NUMPAD9;
359  case 75: return KEY_NUMPAD4;
360  case 77: return KEY_NUMPAD6;
361  case 79: return KEY_NUMPAD1;
362  case 80: return KEY_NUMPAD4;
363  case 81: return KEY_NUMPAD3;
364  case 82: return KEY_NUMPAD0;
365  case 83: return KEY_NUMDEL;
366  default: return kk-59+KEY_F1; // Function keys
367  }}
368  case 224: {
369  int kk;
370  switch (kk = getch()) {
371  case 71: return KEY_HOME;
372  case 72: return KEY_UP;
373  case 73: return KEY_PGUP;
374  case 75: return KEY_LEFT;
375  case 77: return KEY_RIGHT;
376  case 79: return KEY_END;
377  case 80: return KEY_DOWN;
378  case 81: return KEY_PGDOWN;
379  case 82: return KEY_INSERT;
380  case 83: return KEY_DELETE;
381  default: return kk-123+KEY_F1; // Function keys
382  }}
383  case 13: return KEY_ENTER;
384 #ifdef _WIN32
385  case 27: return KEY_ESCAPE;
386 #else // _WIN32
387  case 155: // single-character CSI
388  case 27: {
389  // Process ANSI escape sequences
390  if (cnt >= 3 && getch() == '[') {
391  switch (k = getch()) {
392  case 'A': return KEY_UP;
393  case 'B': return KEY_DOWN;
394  case 'C': return KEY_RIGHT;
395  case 'D': return KEY_LEFT;
396  }
397  } else return KEY_ESCAPE;
398  }
399 #endif // _WIN32
400  default: return k;
401  }
402 }
403 
406 static RLUTIL_INLINE int nb_getch(void) {
407  if (kbhit()) return getch();
408  else return 0;
409 }
410 
415 static RLUTIL_INLINE RLUTIL_STRING_T getANSIColor(const int c) {
416  switch (c) {
417  case BLACK : return ANSI_BLACK;
418  case BLUE : return ANSI_BLUE; // non-ANSI
419  case GREEN : return ANSI_GREEN;
420  case CYAN : return ANSI_CYAN; // non-ANSI
421  case RED : return ANSI_RED; // non-ANSI
422  case MAGENTA : return ANSI_MAGENTA;
423  case BROWN : return ANSI_BROWN;
424  case GREY : return ANSI_GREY;
425  case DARKGREY : return ANSI_DARKGREY;
426  case LIGHTBLUE : return ANSI_LIGHTBLUE; // non-ANSI
427  case LIGHTGREEN: return ANSI_LIGHTGREEN;
428  case LIGHTCYAN: return ANSI_LIGHTCYAN; // non-ANSI;
429  case LIGHTRED: return ANSI_LIGHTRED; // non-ANSI;
430  case LIGHTMAGENTA: return ANSI_LIGHTMAGENTA;
431  case YELLOW: return ANSI_YELLOW; // non-ANSI
432  case WHITE: return ANSI_WHITE;
433  case NONE: return ANSI_NONE;
434  default: return "";
435  }
436 }
437 
442 static RLUTIL_INLINE void setColor(int c) {
443 #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
444  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
445  SetConsoleTextAttribute(hConsole, (WORD)c);
446 #else
447  RLUTIL_PRINT(getANSIColor(c));
448 #endif
449 }
450 
453 static RLUTIL_INLINE void cls(void) {
454 #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
455  system("cls");
457 #else
458  RLUTIL_PRINT("\033[2J\033[H");
459 #endif
460 }
461 
464 static RLUTIL_INLINE void locate(int x, int y) {
465 #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
466  COORD coord;
467  coord.X = (SHORT)x-1;
468  coord.Y = (SHORT)y-1; // Windows uses 0-based coordinates
469  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
470 #else // _WIN32 || USE_ANSI
471  #ifdef __cplusplus
472  std::ostringstream oss;
473  oss << "\033[" << y << ";" << x << "H";
474  RLUTIL_PRINT(oss.str());
475  #else // __cplusplus
476  char buf[32];
477  sprintf(buf, "\033[%d;%df", y, x);
478  RLUTIL_PRINT(buf);
479  #endif // __cplusplus
480 #endif // _WIN32 || USE_ANSI
481 }
482 
485 static RLUTIL_INLINE void hidecursor(void) {
486 #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
487  HANDLE hConsoleOutput;
488  CONSOLE_CURSOR_INFO structCursorInfo;
489  hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
490  GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
491  structCursorInfo.bVisible = FALSE;
492  SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
493 #else // _WIN32 || USE_ANSI
494  RLUTIL_PRINT("\033[?25l");
495 #endif // _WIN32 || USE_ANSI
496 }
497 
500 static RLUTIL_INLINE void showcursor(void) {
501 #if defined(_WIN32) && !defined(RLUTIL_USE_ANSI)
502  HANDLE hConsoleOutput;
503  CONSOLE_CURSOR_INFO structCursorInfo;
504  hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
505  GetConsoleCursorInfo( hConsoleOutput, &structCursorInfo ); // Get current cursor size
506  structCursorInfo.bVisible = TRUE;
507  SetConsoleCursorInfo( hConsoleOutput, &structCursorInfo );
508 #else // _WIN32 || USE_ANSI
509  RLUTIL_PRINT("\033[?25h");
510 #endif // _WIN32 || USE_ANSI
511 }
512 
513 extern int usleep (__useconds_t __useconds);
514 
517 static RLUTIL_INLINE void msleep(unsigned int ms) {
518 #ifdef _WIN32
519  Sleep(ms);
520 #else
521  // usleep argument must be under 1 000 000
522  if (ms > 1000) sleep(ms/1000000);
523  #pragma GCC diagnostic push
524  //#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
525  usleep((ms % 1000000) * 1000);
526  //#pragma GCC diagnostic pop
527 #endif
528 }
529 
532 static RLUTIL_INLINE int trows(void) {
533 #ifdef _WIN32
534  CONSOLE_SCREEN_BUFFER_INFO csbi;
535  if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
536  return -1;
537  else
538  return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; // Window height
539  // return csbi.dwSize.Y; // Buffer height
540 #else
541 #ifdef TIOCGSIZE
542  struct ttysize ts;
543  ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
544  return ts.ts_lines;
545 #elif defined(TIOCGWINSZ)
546  struct winsize ts;
547  ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
548  return ts.ws_row;
549 #else // TIOCGSIZE
550  return -1;
551 #endif // TIOCGSIZE
552 #endif // _WIN32
553 }
554 
557 static RLUTIL_INLINE int tcols(void) {
558 #ifdef _WIN32
559  CONSOLE_SCREEN_BUFFER_INFO csbi;
560  if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
561  return -1;
562  else
563  return csbi.srWindow.Right - csbi.srWindow.Left + 1; // Window width
564  // return csbi.dwSize.X; // Buffer width
565 #else
566 #ifdef TIOCGSIZE
567  struct ttysize ts;
568  ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
569  return ts.ts_cols;
570 #elif defined(TIOCGWINSZ)
571  struct winsize ts;
572  ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
573  return ts.ws_col;
574 #else // TIOCGSIZE
575  return -1;
576 #endif // TIOCGSIZE
577 #endif // _WIN32
578 }
579 
581 
584 static RLUTIL_INLINE void anykey(void) {
585  getch();
586 }
587 
588 #ifndef min
589 #ifdef __cplusplus
592 template <class T> const T& min ( const T& a, const T& b ) { return (a<b)?a:b; }
593 #else
594 #define min(a,b) (((a)<(b))?(a):(b))
595 #endif // __cplusplus
596 #endif // min
597 
598 #ifndef max
599 #ifdef __cplusplus
602 template <class T> const T& max ( const T& a, const T& b ) { return (b<a)?a:b; }
603 #else
604 #define max(a,b) (((b)<(a))?(a):(b))
605 #endif // __cplusplus
606 #endif // max
607 
608 // Classes are here at the end so that documentation is pretty.
609 
610 #ifdef __cplusplus
611 struct CursorHider {
616  CursorHider() { hidecursor(); }
617  ~CursorHider() { showcursor(); }
618 };
619 
620 } // namespace rlutil
621 #endif
Definition: rlutil.h:187
Definition: rlutil.h:197
Definition: rlutil.h:193
Definition: rlutil.h:181
#define ECHO
Definition: lexer-filter.c:560
Definition: rlutil.h:192
Definition: rlutil.h:184
Definition: rlutil.h:194
char * RLUTIL_STRING_T
Defs: Internal typedefs and macros RLUTIL_STRING_T - String type depending on which one of C or C++ i...
Definition: rlutil.h:154
Definition: rlutil.h:183
#define RLUTIL_INLINE
Definition: rlutil.h:54
#define FALSE
Definition: conf.h:49
Definition: rlutil.h:195
#define RLUTIL_PRINT(st)
Definition: rlutil.h:157
Definition: rlutil.h:185
#define WORD
Definition: grammar-filter.c:140
int usleep(__useconds_t __useconds)
Definition: rlutil.h:189
Definition: rlutil.h:190
Definition: rlutil.h:188
Definition: rlutil.h:182
Definition: rlutil.h:186
#define max(a, b)
Function: max Returns the greater of the two arguments.
Definition: rlutil.h:604
#define TRUE
Definition: conf.h:48
#define min(a, b)
Function: min Returns the lesser of the two arguments.
Definition: rlutil.h:594
Definition: rlutil.h:196
Definition: rlutil.h:191