Rizin
unix-like reverse engineering framework and cli tools
cons.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2008-2020 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2008-2020 Jody Frankowski <jody.frankowski@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_cons.h>
6 #include <rz_util.h>
7 #include <rz_util/rz_print.h>
8 #include <rz_windows.h>
9 #include <limits.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <stdarg.h>
14 
15 #define COUNT_LINES 1
16 #define CTX(x) I.context->x
17 
18 RZ_LIB_VERSION(rz_cons);
19 
20 static RzConsContext rz_cons_context_default = { { { { 0 } } } };
21 static RzCons rz_cons_instance = { 0 };
22 #define I rz_cons_instance
23 
24 // this structure goes into cons_stack when rz_cons_push/pop
25 typedef struct {
26  char *buf;
27  int buf_len;
28  int buf_size;
30  bool noflush;
31 } RzConsStack;
32 
33 typedef struct {
34  bool breaked;
38 
39 static void cons_grep_reset(RzConsGrep *grep);
40 
41 static void ctx_rowcol_calc_reset(void) {
42  CTX(row) = 0;
43  CTX(col) = 0;
44  CTX(rowcol_calc_start) = 0;
45 }
46 
47 static void break_stack_free(void *ptr) {
49  free(b);
50 }
51 
52 static void cons_stack_free(void *ptr) {
53  RzConsStack *s = (RzConsStack *)ptr;
54  free(s->buf);
55  if (s->grep) {
56  RZ_FREE(s->grep->str);
57  CTX(grep.str) = NULL;
58  }
59  free(s->grep);
60  free(s);
61 }
62 
63 static RzConsStack *cons_stack_dump(bool recreate) {
65  if (data) {
66  if (CTX(buffer)) {
67  data->buf = CTX(buffer);
68  data->buf_len = CTX(buffer_len);
69  data->buf_size = CTX(buffer_sz);
70  }
71  data->noflush = CTX(noflush);
72  data->grep = RZ_NEW0(RzConsGrep);
73  if (data->grep) {
74  memcpy(data->grep, &CTX(grep), sizeof(RzConsGrep));
75  if (CTX(grep).str) {
76  data->grep->str = strdup(CTX(grep).str);
77  }
78  }
79  if (recreate && CTX(buffer_sz) > 0) {
80  CTX(buffer) = malloc(CTX(buffer_sz));
82  if (!CTX(buffer)) {
83  CTX(buffer) = data->buf;
84  free(data);
85  return NULL;
86  }
87  } else {
88  CTX(buffer) = NULL;
89  }
90  }
91  return data;
92 }
93 
94 static void cons_stack_load(RzConsStack *data, bool free_current) {
95  rz_return_if_fail(data);
96  if (free_current) {
97  free(CTX(buffer));
98  }
99  CTX(buffer) = data->buf;
100  data->buf = NULL;
101  CTX(buffer_len) = data->buf_len;
102  CTX(buffer_sz) = data->buf_size;
103  if (data->grep) {
104  free(CTX(grep).str);
105  memcpy(&CTX(grep), data->grep, sizeof(RzConsGrep));
106  }
107  CTX(noflush) = data->noflush;
109 }
110 
112  context->breaked = false;
113  context->cmd_depth = RZ_CONS_CMD_DEPTH + 1;
114  context->buffer = NULL;
115  context->buffer_sz = 0;
116  context->lastEnabled = true;
117  context->buffer_len = 0;
118  context->is_interactive = false;
119  context->cons_stack = rz_stack_newf(6, cons_stack_free);
120  context->break_stack = rz_stack_newf(6, break_stack_free);
121  context->event_interrupt = NULL;
122  context->event_interrupt_data = NULL;
123  context->pageable = true;
124  context->log_callback = NULL;
125  context->noflush = false;
126 
127  if (parent) {
128  context->color_mode = parent->color_mode;
129  rz_cons_pal_copy(context, parent);
130  } else {
131  context->color_mode = COLOR_MODE_DISABLED;
133  }
134 
135  cons_grep_reset(&context->grep);
136 }
137 
139  rz_stack_free(context->cons_stack);
140  context->cons_stack = NULL;
141  rz_stack_free(context->break_stack);
142  context->break_stack = NULL;
144 }
145 
146 static void __break_signal(int sig) {
148 }
149 
150 static inline void __cons_write_ll(const char *buf, int len) {
151 #if __WINDOWS__
152  if (I.vtmode != RZ_VIRT_TERM_MODE_DISABLE) {
153  rz_xwrite(I.fdout, buf, len);
154  } else {
155  if (I.fdout == 1) {
156  rz_cons_w32_print(buf, len, false);
157  } else {
158  rz_xwrite(I.fdout, buf, len);
159  }
160  }
161 #else
162  if (I.fdout < 1) {
163  I.fdout = 1;
164  }
165  rz_xwrite(I.fdout, buf, len);
166 #endif
167 }
168 
169 static inline void __cons_write(const char *obuf, int olen) {
170  const size_t bucket = 64 * 1024;
171  size_t i;
172  if (olen < 0) {
173  olen = strlen(obuf);
174  }
175  for (i = 0; (i + bucket) < olen; i += bucket) {
176  __cons_write_ll(obuf + i, bucket);
177  }
178  if (i < olen) {
179  __cons_write_ll(obuf + i, olen - i);
180  }
181 }
182 
184  RzColor rcolor = { 0 };
185  if (CTX(color_mode) > COLOR_MODE_16) {
186  rcolor.r = rz_num_rand(0xff);
187  rcolor.g = rz_num_rand(0xff);
188  rcolor.b = rz_num_rand(0xff);
189  rcolor.a = alpha;
190  return rcolor;
191  }
192  int r = rz_num_rand(16);
193  switch (r) {
194  case 0:
195  case 1: rcolor = (RzColor)RzColor_RED; break;
196  case 2:
197  case 3: rcolor = (RzColor)RzColor_WHITE; break;
198  case 4:
199  case 5: rcolor = (RzColor)RzColor_GREEN; break;
200  case 6:
201  case 7: rcolor = (RzColor)RzColor_MAGENTA; break;
202  case 8:
203  case 9: rcolor = (RzColor)RzColor_YELLOW; break;
204  case 10:
205  case 11: rcolor = (RzColor)RzColor_CYAN; break;
206  case 12:
207  case 13: rcolor = (RzColor)RzColor_BLUE; break;
208  case 14:
209  case 15: rcolor = (RzColor)RzColor_GRAY; break;
210  }
211  if (r & 1) {
213  }
214  return rcolor;
215 }
216 
217 RZ_API void rz_cons_color(int fg, int r, int g, int b) {
218  int k;
219  r = RZ_DIM(r, 0, 255);
220  g = RZ_DIM(g, 0, 255);
221  b = RZ_DIM(b, 0, 255);
222  if (r == g && g == b) { // b&w
223  k = 232 + (int)(((r + g + b) / 3) / 10.3);
224  } else {
225  r = (int)(r / 42.6);
226  g = (int)(g / 42.6);
227  b = (int)(b / 42.6);
228  k = 16 + (r * 36) + (g * 6) + b;
229  }
230  rz_cons_printf("\x1b[%d;5;%dm", fg ? 48 : 38, k);
231 }
232 
233 RZ_API void rz_cons_println(const char *str) {
234  rz_cons_print(str);
235  rz_cons_newline();
236 }
237 
238 RZ_API void rz_cons_strcat_justify(const char *str, int j, char c) {
239  int i, o, len;
240  for (o = i = len = 0; str[i]; i++, len++) {
241  if (str[i] == '\n') {
242  rz_cons_memset(' ', j);
243  if (c) {
244  rz_cons_memset(c, 1);
245  rz_cons_memset(' ', 1);
246  }
247  rz_cons_memcat(str + o, len);
248  if (str[o + len] == '\n') {
249  rz_cons_newline();
250  }
251  o = i + 1;
252  len = 0;
253  }
254  }
255  if (len > 1) {
256  rz_cons_memcat(str + o, len);
257  }
258 }
259 
260 RZ_API void rz_cons_strcat_at(const char *_str, int x, char y, int w, int h) {
261  int i, o, len;
262  int cols = 0;
263  int rows = 0;
264  if (x < 0 || y < 0) {
265  int H, W = rz_cons_get_size(&H);
266  if (x < 0) {
267  x += W;
268  }
269  if (y < 0) {
270  y += H;
271  }
272  }
273  char *str = rz_str_ansi_crop(_str, 0, 0, w + 1, h);
275  for (o = i = len = 0; str[i]; i++, len++) {
276  if (w < 0 || rows > w) {
277  break;
278  }
279  if (str[i] == '\n') {
280  rz_cons_gotoxy(x, y + rows);
281  int ansilen = rz_str_ansi_len(str + o);
282  cols = RZ_MIN(w, ansilen);
283  const char *end = rz_str_ansi_chrn(str + o, cols);
284  cols = end - str + o;
285  rz_cons_memcat(str + o, RZ_MIN(len, cols));
286  o = i + 1;
287  len = 0;
288  rows++;
289  }
290  }
291  if (len > 1) {
292  rz_cons_gotoxy(x, y + rows);
293  rz_cons_memcat(str + o, len);
294  }
297  free(str);
298 }
299 
301  return &I;
302 }
303 
305  CTX(breaked) = false;
306 }
307 
308 RZ_API void rz_cons_context_break_push(RzConsContext *context, RzConsBreak cb, void *user, bool sig) {
309  if (!context->break_stack) {
310  return;
311  }
312 
313  // if we don't have any element in the stack start the signal
315  if (!b) {
316  return;
317  }
318  if (rz_stack_is_empty(context->break_stack)) {
319 #if __UNIX__
320  if (sig && rz_cons_context_is_main()) {
321  rz_sys_signal(SIGINT, __break_signal);
322  }
323 #endif
324  context->breaked = false;
325  }
326  // save the actual state
327  b->event_interrupt = context->event_interrupt;
328  b->event_interrupt_data = context->event_interrupt_data;
329  rz_stack_push(context->break_stack, b);
330  // configure break
331  context->event_interrupt = cb;
332  context->event_interrupt_data = user;
333 }
334 
336  if (!context->break_stack) {
337  return;
338  }
339  // restore old state
341  b = rz_stack_pop(context->break_stack);
342  if (b) {
343  context->event_interrupt = b->event_interrupt;
344  context->event_interrupt_data = b->event_interrupt_data;
346  } else {
347  // there is not more elements in the stack
348 #if __UNIX__
349  if (sig && rz_cons_context_is_main()) {
350  rz_sys_signal(SIGINT, SIG_IGN);
351  }
352 #endif
353  context->breaked = false;
354  }
355 }
356 
357 RZ_API void rz_cons_break_push(RzConsBreak cb, void *user) {
358  rz_cons_context_break_push(I.context, cb, user, true);
359 }
360 
362  rz_cons_context_break_pop(I.context, true);
363 }
364 
366  return CTX(is_interactive);
367 }
368 
371 }
372 
374  if (I.cb_break) {
375  I.cb_break(I.user);
376  }
377  if (I.timeout) {
378  if (rz_time_now_mono() > I.timeout) {
379  CTX(breaked) = true;
380  eprintf("\nTimeout!\n");
381  I.timeout = 0;
382  }
383  }
384  return CTX(breaked);
385 }
386 
388  int curline = 0;
389 #if __WINDOWS__
390  CONSOLE_SCREEN_BUFFER_INFO info;
391  if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info)) {
392  return 0;
393  }
394  curline = info.dwCursorPosition.Y - info.srWindow.Top;
395 #endif
396 #if __UNIX__
397  char buf[8];
398  struct termios save, raw;
399  // flush the Arrow keys escape keys which was messing up the output
400  fflush(stdout);
401  (void)tcgetattr(0, &save);
402  cfmakeraw(&raw);
403  (void)tcsetattr(0, TCSANOW, &raw);
404  if (isatty(fileno(stdin))) {
406  if (read(0, buf, sizeof(buf)) != sizeof(buf)) {
407  if (isdigit(buf[2])) {
408  curline = (buf[2] - '0');
409  }
410  if (isdigit(buf[3])) {
411  curline = curline * 10 + (buf[3] - '0');
412  }
413  }
414  }
415  }
416  (void)tcsetattr(0, TCSANOW, &save);
417 #endif
418  return curline;
419 }
420 
422  I.timeout = (timeout && !I.timeout)
423  ? rz_time_now_mono() + ((ut64)timeout << 20)
424  : 0;
425 }
426 
428  CTX(breaked) = false;
429  I.timeout = 0;
430 #if __UNIX__
431  rz_sys_signal(SIGINT, SIG_IGN);
432 #endif
433  if (!rz_stack_is_empty(CTX(break_stack))) {
434  // free all the stack
435  rz_stack_free(CTX(break_stack));
436  // create another one
437  CTX(break_stack) = rz_stack_newf(6, break_stack_free);
438  CTX(event_interrupt_data) = NULL;
439  CTX(event_interrupt) = NULL;
440  }
441 }
442 
444  if (!I.cb_sleep_begin) {
445  return NULL;
446  }
447  return I.cb_sleep_begin(I.user);
448 }
449 
450 RZ_API void rz_cons_sleep_end(void *user) {
451  if (I.cb_sleep_end) {
452  I.cb_sleep_end(I.user, user);
453  }
454 }
455 
456 #if __WINDOWS__
457 static BOOL __w32_control(DWORD type) {
458  if (type == CTRL_C_EVENT) {
459  __break_signal(2); // SIGINT
460  eprintf("{ctrl+c} pressed.\n");
461  return true;
462  }
463  return false;
464 }
465 #elif __UNIX__
466 volatile sig_atomic_t sigwinchFlag;
467 static void resize(int sig) {
468  sigwinchFlag = 1;
469 }
470 #endif
471 void resizeWin(void) {
472  if (I.event_resize) {
473  I.event_resize(I.event_data);
474  }
475 }
476 
477 RZ_API void rz_cons_set_click(int x, int y) {
478  I.click_x = x;
479  I.click_y = y;
480  I.click_set = true;
481  I.mouse_event = 1;
482 }
483 
484 RZ_API bool rz_cons_get_click(int *x, int *y) {
485  if (x) {
486  *x = I.click_x;
487  }
488  if (y) {
489  *y = I.click_y;
490  }
491  bool set = I.click_set;
492  I.click_set = false;
493  return set;
494 }
495 
496 RZ_API void rz_cons_enable_highlight(const bool enable) {
497  I.enable_highlight = enable;
498 }
499 
500 RZ_API bool rz_cons_enable_mouse(const bool enable) {
501  if ((I.mouse && enable) || (!I.mouse && !enable)) {
502  return I.mouse;
503  }
504 #if __WINDOWS__
505  if (I.vtmode == RZ_VIRT_TERM_MODE_COMPLETE) {
506 #endif
507  const char *click = enable
508  ? "\x1b[?1000;1006;1015h"
509  : "\x1b[?1000;1006;1015l";
510  // const char *old = enable ? "\x1b[?1001s" "\x1b[?1000h" : "\x1b[?1001r" "\x1b[?1000l";
511  bool enabled = I.mouse;
512  const size_t click_len = strlen(click);
513  if (write(2, click, click_len) != click_len) {
514  return false;
515  }
516  I.mouse = enable;
517  return enabled;
518 #if __WINDOWS__
519  }
520  DWORD mode;
521  HANDLE h;
522  bool enabled = I.mouse;
523  h = GetStdHandle(STD_INPUT_HANDLE);
524  GetConsoleMode(h, &mode);
526  mode = enable
527  ? (mode | ENABLE_MOUSE_INPUT) & ~ENABLE_QUICK_EDIT_MODE
528  : (mode & ~ENABLE_MOUSE_INPUT) | ENABLE_QUICK_EDIT_MODE;
529  if (SetConsoleMode(h, mode)) {
530  I.mouse = enable;
531  }
532  return enabled;
533 #else
534  return false;
535 #endif
536 }
537 
538 #if __WINDOWS__
539 static void set_console_codepage_to_utf8(void) {
540  if (IsValidCodePage(CP_UTF8)) {
541  if (!SetConsoleOutputCP(CP_UTF8)) {
542  rz_sys_perror("SetConsoleCP");
543  }
544  if (!SetConsoleCP(CP_UTF8)) {
545  rz_sys_perror("SetConsoleCP");
546  }
547  } else {
548  RZ_LOG_INFO("UTF-8 Codepage not installed.\n");
549  }
550 }
551 
552 static void save_console_state(void) {
553  if (rz_cons_isatty()) {
554  if (!(I.old_ocp = GetConsoleOutputCP())) {
555  rz_sys_perror("GetConsoleOutputCP");
556  }
557  if (!(I.old_cp = GetConsoleCP())) {
558  rz_sys_perror("GetConsoleCP");
559  }
560  if (!GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &I.old_output_mode)) {
561  rz_sys_perror("GetConsoleMode");
562  }
563  if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &I.old_input_mode)) {
564  rz_sys_perror("GetConsoleCP");
565  }
566  }
567 }
568 
569 static void restore_console_state(void) {
570  if (rz_cons_isatty()) {
571  if (!SetConsoleCP(I.old_cp)) {
572  rz_sys_perror("SetConsoleCP");
573  }
574  if (!SetConsoleOutputCP(I.old_ocp)) {
575  rz_sys_perror("SetConsoleOutputCP");
576  }
577  if (!SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), I.old_output_mode)) {
578  rz_sys_perror("SetConsoleMode");
579  }
580  if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), I.old_input_mode)) {
581  rz_sys_perror("SetConsoleMode");
582  }
583  }
584 }
585 #endif
586 
587 // Stub function that cb_main_output gets pointed to in util/log.c by rz_cons_new
588 // This allows Cutter to set per-task logging redirection
590  I.refcnt++;
591  if (I.refcnt != 1) {
592  return &I;
593  }
594  I.rgbstr = rz_cons_rgb_str_off;
595  I.line = rz_line_new();
596  I.enable_highlight = true;
597  I.highlight = NULL;
598  I.is_wine = -1;
599  I.blankline = true;
600  I.teefile = NULL;
601  I.fix_columns = 0;
602  I.fix_rows = 0;
603  I.mouse_event = 0;
604  I.force_rows = 0;
605  I.force_columns = 0;
606  I.event_resize = NULL;
607  I.event_data = NULL;
608  I.linesleep = 0;
609  I.fdin = stdin;
610  I.fdout = 1;
611  I.break_lines = false;
612  I.lines = 0;
613 
614  I.input = RZ_NEW0(RzConsInputContext);
615  I.input->bufactive = true;
616  I.context = &rz_cons_context_default;
617  cons_context_init(I.context, NULL);
618 
619  rz_cons_get_size(&I.pagesize);
620  I.num = NULL;
621  I.null = 0;
622 #if __WINDOWS__
623  save_console_state();
624  I.vtmode = rz_cons_detect_vt_mode();
625  set_console_codepage_to_utf8();
626 #else
627  I.vtmode = RZ_VIRT_TERM_MODE_COMPLETE;
628 #endif
629 #if EMSCRIPTEN
630  /* do nothing here :? */
631 #elif __UNIX__
632  tcgetattr(0, &I.term_buf);
633  memcpy(&I.term_raw, &I.term_buf, sizeof(I.term_raw));
634  I.term_raw.c_iflag &= ~(BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
635  I.term_raw.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
636  I.term_raw.c_cflag &= ~(CSIZE | PARENB);
637  I.term_raw.c_cflag |= CS8;
638  I.term_raw.c_cc[VMIN] = 1; // Solaris stuff hehe
639  rz_sys_signal(SIGWINCH, resize);
640 #elif __WINDOWS__
641  I.term_buf = I.old_input_mode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT;
642  I.term_raw = ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
643  if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)__w32_control, TRUE)) {
644  eprintf("rz_cons: Cannot set control console handler\n");
645  }
646 #endif
647  I.pager = NULL; /* no pager by default */
648  I.mouse = 0;
649  I.show_vals = false;
650  rz_cons_reset();
652 
654 
655  return &I;
656 }
657 
659  if (I.refcnt <= 0) {
660  return NULL;
661  }
662  I.refcnt--;
663  if (I.refcnt != 0) {
664  return &I;
665  }
666 #if __WINDOWS__
667  restore_console_state();
668 #endif
669  if (I.line) {
670  rz_line_free();
671  I.line = NULL;
672  }
673  RZ_FREE(I.input->readbuffer);
674  RZ_FREE(I.input);
675  RZ_FREE(CTX(buffer));
676  RZ_FREE(I.break_word);
677  cons_context_deinit(I.context);
678  RZ_FREE(CTX(lastOutput));
679  CTX(lastLength) = 0;
680  RZ_FREE(I.pager);
681  return NULL;
682 }
683 
684 #define MOAR (4096 * 8)
685 static bool palloc(int moar) {
686  void *temp;
687  if (moar <= 0) {
688  return false;
689  }
690  if (!CTX(buffer)) {
691  int new_sz;
692  if ((INT_MAX - MOAR) < moar) {
693  return false;
694  }
695  new_sz = moar + MOAR;
696  temp = calloc(1, new_sz);
697  if (temp) {
698  CTX(buffer_sz) = new_sz;
699  CTX(buffer) = temp;
700  (CTX(buffer))[0] = '\0';
701  }
702  } else if (moar + CTX(buffer_len) > CTX(buffer_sz)) {
703  char *new_buffer;
704  int old_buffer_sz = CTX(buffer_sz);
705  if ((INT_MAX - MOAR - moar) < CTX(buffer_sz)) {
706  return false;
707  }
708  CTX(buffer_sz) += moar + MOAR;
709  new_buffer = realloc(CTX(buffer), CTX(buffer_sz));
710  if (new_buffer) {
711  CTX(buffer) = new_buffer;
712  } else {
713  CTX(buffer_sz) = old_buffer_sz;
714  return false;
715  }
716  }
717  return true;
718 }
719 
720 RZ_API int rz_cons_eof(void) {
721  return feof(I.fdin);
722 }
723 
724 RZ_API void rz_cons_gotoxy(int x, int y) {
725 #if __WINDOWS__
726  rz_cons_w32_gotoxy(1, x, y);
727 #else
728  rz_cons_printf("\x1b[%d;%dH", y, x);
729 #endif
730 }
731 
733  rz_cons_gotoxy(0, 0);
735 }
736 
738  char *p, white[1024];
739  int cols = I.columns - 1;
740  if (cols < 1) {
741  return;
742  }
743  p = (cols >= sizeof(white))
744  ? malloc(cols + 1)
745  : white;
746  if (p) {
747  memset(p, ' ', cols);
748  p[cols] = 0;
749  rz_cons_strcat(p);
750  if (white != p) {
751  free(p);
752  }
753  }
754 }
755 
756 RZ_API void rz_cons_clear_line(int std_err) {
757 #if __WINDOWS__
758  if (I.vtmode != RZ_VIRT_TERM_MODE_DISABLE) {
759  fprintf(std_err ? stderr : stdout, "%s", RZ_CONS_CLEAR_LINE);
760  } else {
761  char white[1024];
762  memset(&white, ' ', sizeof(white));
763  if (I.columns > 0 && I.columns < sizeof(white)) {
764  white[I.columns - 1] = 0;
765  } else if (I.columns == 0) {
766  white[0] = 0;
767  } else {
768  white[sizeof(white) - 1] = 0; // HACK
769  }
770  fprintf(std_err ? stderr : stdout, "\r%s\r", white);
771  }
772 #else
773  fprintf(std_err ? stderr : stdout, "%s", RZ_CONS_CLEAR_LINE);
774 #endif
775  fflush(std_err ? stderr : stdout);
776 }
777 
779  rz_cons_clear();
780  rz_cons_gotoxy(0, 0);
781 }
782 
785 }
786 
787 RZ_API void rz_cons_clear(void) {
788  I.lines = 0;
789 #if __WINDOWS__
790  rz_cons_w32_clear();
791 #else
793 #endif
794 }
795 
796 static void cons_grep_reset(RzConsGrep *grep) {
797  RZ_FREE(grep->str);
798  ZERO_FILL(*grep);
799  grep->line = -1;
800  grep->sort = -1;
801  grep->sort_invert = false;
802 }
803 
804 RZ_API void rz_cons_reset(void) {
805  if (CTX(buffer)) {
806  (CTX(buffer))[0] = '\0';
807  }
808  CTX(buffer_len) = 0;
809  I.lines = 0;
810  I.lastline = CTX(buffer);
811  cons_grep_reset(&CTX(grep));
812  CTX(pageable) = true;
814 }
815 
819 RZ_API const char *rz_cons_get_buffer(void) {
820  // check len otherwise it will return trash
821  return CTX(buffer_len) ? CTX(buffer) : NULL;
822 }
823 
828  const char *s = rz_cons_get_buffer();
829  return s ? strdup(s) : NULL;
830 }
831 
833  return CTX(buffer_len);
834 }
835 
836 RZ_API void rz_cons_filter(void) {
837  /* grep */
838  if (I.filter || CTX(grep).nstrings > 0 || CTX(grep).tokens_used || CTX(grep).less || CTX(grep).json) {
839  (void)rz_cons_grepbuf();
840  I.filter = false;
841  }
842  /* html */
843  if (I.is_html) {
844  int newlen = 0;
845  char *input = rz_str_ndup(CTX(buffer), CTX(buffer_len));
846  char *res = rz_cons_html_filter(input, &newlen);
847  free(CTX(buffer));
848  CTX(buffer) = res;
849  CTX(buffer_len) = newlen;
850  CTX(buffer_sz) = newlen;
852  free(input);
853  }
854  if (I.was_html) {
855  I.is_html = true;
856  I.was_html = false;
857  }
858 }
859 
860 RZ_API void rz_cons_push(void) {
861  if (!CTX(cons_stack)) {
862  return;
863  }
864  RzConsStack *data = cons_stack_dump(true);
865  if (!data) {
866  return;
867  }
868  rz_stack_push(CTX(cons_stack), data);
869  CTX(buffer_len) = 0;
870  if (CTX(buffer)) {
871  memset(CTX(buffer), 0, CTX(buffer_sz));
872  }
873  CTX(noflush) = true;
874 }
875 
876 RZ_API void rz_cons_pop(void) {
877  if (!CTX(cons_stack)) {
878  return;
879  }
880  RzConsStack *data = (RzConsStack *)rz_stack_pop(CTX(cons_stack));
881  if (!data) {
882  return;
883  }
884  cons_stack_load(data, true);
885  cons_stack_free((void *)data);
886 }
887 
890  if (!context) {
891  return NULL;
892  }
893  cons_context_init(context, parent);
894  return context;
895 }
896 
898  if (!context) {
899  return;
900  }
902  free(context);
903 }
904 
906  I.context = context;
907 }
908 
910  I.context = &rz_cons_context_default;
911 }
912 
914  return I.context == &rz_cons_context_default;
915 }
916 
918  if (!context) {
920  }
921  context->breaked = true;
922  if (context->event_interrupt) {
923  context->event_interrupt(context->event_interrupt_data);
924  }
925 }
926 
927 RZ_API void rz_cons_last(void) {
928  if (!CTX(lastEnabled)) {
929  return;
930  }
931  CTX(lastMode) = true;
932  rz_cons_memcat(CTX(lastOutput), CTX(lastLength));
933 }
934 
935 static bool lastMatters(void) {
936  return (CTX(buffer_len) > 0) && (CTX(lastEnabled) && !I.filter && CTX(grep).nstrings < 1 && !CTX(grep).tokens_used && !CTX(grep).less && !CTX(grep).json && !I.is_html);
937 }
938 
939 RZ_API void rz_cons_echo(const char *msg) {
940  static RzStrBuf *echodata = NULL; // TODO: move into RzConsInstance? maybe nope
941  if (msg) {
942  if (echodata) {
943  rz_strbuf_append(echodata, msg);
944  rz_strbuf_append(echodata, "\n");
945  } else {
946  echodata = rz_strbuf_new(msg);
947  }
948  } else {
949  if (echodata) {
950  char *data = rz_strbuf_drain(echodata);
951  rz_cons_strcat(data);
952  rz_cons_newline();
953  echodata = NULL;
954  free(data);
955  }
956  }
957 }
958 
959 RZ_API void rz_cons_flush(void) {
960  const char *tee = I.teefile;
961  if (CTX(noflush)) {
962  return;
963  }
964  if (I.null) {
965  rz_cons_reset();
966  return;
967  }
968  if (lastMatters() && !CTX(lastMode)) {
969  // snapshot of the output
970  if (CTX(buffer_len) > CTX(lastLength)) {
971  free(CTX(lastOutput));
972  CTX(lastOutput) = malloc(CTX(buffer_len) + 1);
973  }
974  CTX(lastLength) = CTX(buffer_len);
975  memcpy(CTX(lastOutput), CTX(buffer), CTX(buffer_len));
976  } else {
977  CTX(lastMode) = false;
978  }
979  rz_cons_filter();
980  if (rz_cons_is_interactive() && I.fdout == 1) {
981  /* Use a pager if the output doesn't fit on the terminal window. */
982  if (CTX(pageable) && CTX(buffer) && I.pager && *I.pager && CTX(buffer_len) > 0 && rz_str_char_count(CTX(buffer), '\n') >= I.rows) {
983  (CTX(buffer))[CTX(buffer_len) - 1] = 0;
984  if (!strcmp(I.pager, "..")) {
985  char *str = rz_str_ndup(CTX(buffer), CTX(buffer_len));
986  CTX(pageable) = false;
988  rz_cons_reset();
989  free(str);
990  return;
991  } else {
993  rz_cons_reset();
994  }
995  } else if (CTX(buffer_len) > CONS_MAX_USER) {
996 #if COUNT_LINES
997  int i, lines = 0;
998  for (i = 0; CTX(buffer)[i]; i++) {
999  if (CTX(buffer)[i] == '\n') {
1000  lines++;
1001  }
1002  }
1003  if (lines > 0 && !rz_cons_yesno('n', "Do you want to print %d lines? (y/N)", lines)) {
1004  rz_cons_reset();
1005  return;
1006  }
1007 #else
1008  char buf[8];
1009  rz_num_units(buf, sizeof(buf), CTX(buffer_len));
1010  if (!rz_cons_yesno('n', "Do you want to print %s chars? (y/N)", buf)) {
1011  rz_cons_reset();
1012  return;
1013  }
1014 #endif
1015  // fix | more | less problem
1016  rz_cons_set_raw(true);
1017  }
1018  }
1019  if (tee && *tee) {
1020  FILE *d = rz_sys_fopen(tee, "a+");
1021  if (d) {
1022  if (CTX(buffer_len) != fwrite(CTX(buffer), 1, CTX(buffer_len), d)) {
1023  eprintf("rz_cons_flush: fwrite: error (%s)\n", tee);
1024  }
1025  fclose(d);
1026  } else {
1027  eprintf("Cannot write on '%s'\n", tee);
1028  }
1029  }
1030  rz_cons_highlight(I.highlight);
1031 
1032  // is_html must be a filter, not a write endpoint
1033  if (rz_cons_is_interactive()) {
1034  if (I.linesleep > 0 && I.linesleep < 1000) {
1035  int i = 0;
1036  int pagesize = RZ_MAX(1, I.pagesize);
1037  char *ptr = CTX(buffer);
1038  char *nl = strchr(ptr, '\n');
1039  int len = CTX(buffer_len);
1040  (CTX(buffer))[CTX(buffer_len)] = 0;
1042  while (nl && !rz_cons_is_breaked()) {
1043  __cons_write(ptr, nl - ptr + 1);
1044  if (I.linesleep && !(i % pagesize)) {
1045  rz_sys_usleep(I.linesleep * 1000);
1046  }
1047  ptr = nl + 1;
1048  nl = strchr(ptr, '\n');
1049  i++;
1050  }
1051  __cons_write(ptr, CTX(buffer) + len - ptr);
1053  } else {
1054  __cons_write(CTX(buffer), CTX(buffer_len));
1055  }
1056  } else {
1057  __cons_write(CTX(buffer), CTX(buffer_len));
1058  }
1059 
1060  rz_cons_reset();
1061  if (I.newline) {
1062  eprintf("\n");
1063  I.newline = false;
1064  }
1065 }
1066 
1068  if (CTX(noflush)) {
1069  return;
1070  }
1071  rz_cons_highlight(I.highlight);
1072  if (!I.null) {
1073 /* TODO: this ifdef must go in the function body */
1074 #if __WINDOWS__
1075  if (I.vtmode != RZ_VIRT_TERM_MODE_DISABLE) {
1077  } else {
1078  rz_cons_w32_print(CTX(buffer), CTX(buffer_len), true);
1079  }
1080 #else
1082 #endif
1083  }
1084  rz_cons_reset();
1085 }
1086 
1087 static int real_strlen(const char *ptr, int len) {
1088  int utf8len = rz_str_len_utf8(ptr);
1089  int ansilen = rz_str_ansi_len(ptr);
1090  int diff = len - utf8len;
1091  if (diff > 0) {
1092  diff--;
1093  }
1094  return ansilen - diff;
1095 }
1096 
1098  char white[1024];
1099  int cols = I.columns;
1100  int alen, plen, lines = I.rows;
1101  bool break_lines = I.break_lines;
1102  const char *endptr;
1103  char *nl, *ptr = buffer, *pptr;
1104 
1105  if (I.null) {
1106  return;
1107  }
1108  memset(&white, ' ', sizeof(white));
1109  while ((nl = strchr(ptr, '\n'))) {
1110  int len = ((int)(size_t)(nl - ptr)) + 1;
1111  int lines_needed = 0;
1112 
1113  *nl = 0;
1114  alen = real_strlen(ptr, len);
1115  *nl = '\n';
1116  pptr = ptr > buffer ? ptr - 1 : ptr;
1117  plen = ptr > buffer ? len : len - 1;
1118 
1119  if (break_lines) {
1120  lines_needed = alen / cols + (alen % cols == 0 ? 0 : 1);
1121  }
1122  if ((break_lines && lines < lines_needed && lines > 0) || (!break_lines && alen > cols)) {
1123  int olen = len;
1124  endptr = rz_str_ansi_chrn(ptr, (break_lines ? cols * lines : cols) + 1);
1125  endptr++;
1126  len = endptr - ptr;
1127  plen = ptr > buffer ? len : len - 1;
1128  if (lines > 0) {
1129  __cons_write(pptr, plen);
1130  if (len != olen) {
1133  }
1134  }
1135  } else {
1136  if (lines > 0) {
1137  int w = cols - (alen % cols == 0 ? cols : alen % cols);
1138  __cons_write(pptr, plen);
1139  if (I.blankline && w > 0) {
1140  if (w > sizeof(white) - 1) {
1141  w = sizeof(white) - 1;
1142  }
1143  __cons_write(white, w);
1144  }
1145  }
1146  // TRICK to empty columns.. maybe buggy in w32
1147  if (rz_mem_mem((const ut8 *)ptr, len, (const ut8 *)"\x1b[0;0H", 6)) {
1148  lines = I.rows;
1149  __cons_write(pptr, plen);
1150  }
1151  }
1152  if (break_lines) {
1153  lines -= lines_needed;
1154  } else {
1155  lines--; // do not use last line
1156  }
1157  ptr = nl + 1;
1158  }
1159  /* fill the rest of screen */
1160  if (lines > 0) {
1161  if (cols > sizeof(white)) {
1162  cols = sizeof(white);
1163  }
1164  while (--lines >= 0) {
1165  __cons_write(white, cols);
1166  }
1167  }
1168 }
1169 
1170 RZ_API void rz_cons_printf_list(const char *format, va_list ap) {
1171  size_t size, written;
1172  va_list ap2, ap3;
1173 
1174  va_copy(ap2, ap);
1175  va_copy(ap3, ap);
1176  if (I.null || !format) {
1177  va_end(ap2);
1178  va_end(ap3);
1179  return;
1180  }
1181  if (strchr(format, '%')) {
1182  if (palloc(MOAR + strlen(format) * 20)) {
1183  club:
1184  size = CTX(buffer_sz) - CTX(buffer_len); /* remaining space in CTX(buffer) */
1185  written = vsnprintf(CTX(buffer) + CTX(buffer_len), size, format, ap3);
1186  if (written >= size) { /* not all bytes were written */
1187  if (palloc(written + 1)) { /* + 1 byte for \0 termination */
1188  va_end(ap3);
1189  va_copy(ap3, ap2);
1190  goto club;
1191  }
1192  }
1193  CTX(buffer_len) += written;
1194  }
1195  } else {
1196  rz_cons_strcat(format);
1197  }
1198  va_end(ap2);
1199  va_end(ap3);
1200 }
1201 
1202 RZ_API int rz_cons_printf(const char *format, ...) {
1203  va_list ap;
1204  if (!format || !*format) {
1205  return -1;
1206  }
1207  va_start(ap, format);
1208  rz_cons_printf_list(format, ap);
1209  va_end(ap);
1210 
1211  return 0;
1212 }
1213 
1215  char *line = strrchr(CTX(buffer), '\n');
1216  if (!line) {
1217  line = CTX(buffer);
1218  }
1219  (CTX(buffer))[CTX(buffer_len)] = 0;
1220  return rz_str_ansi_len(line);
1221 }
1222 
1223 /* final entrypoint for adding stuff in the buffer screen */
1224 RZ_API int rz_cons_memcat(const char *str, int len) {
1225  if (len < 0) {
1226  return -1;
1227  }
1228  if (I.echo) {
1229  // Here to silent pedantic meson flags ...
1230  int rlen;
1231  if ((rlen = write(2, str, len)) != len) {
1232  return rlen;
1233  }
1234  }
1235  if (str && len > 0 && !I.null) {
1236  if (palloc(len + 1)) {
1237  memcpy(CTX(buffer) + CTX(buffer_len), str, len);
1238  CTX(buffer_len) += len;
1239  (CTX(buffer))[CTX(buffer_len)] = 0;
1240  }
1241  }
1242  if (I.flush) {
1243  rz_cons_flush();
1244  }
1245  if (I.break_word && str && len > 0) {
1246  if (rz_mem_mem((const ut8 *)str, len, (const ut8 *)I.break_word, I.break_word_len)) {
1247  CTX(breaked) = true;
1248  }
1249  }
1250  return len;
1251 }
1252 
1253 RZ_API void rz_cons_memset(char ch, int len) {
1254  if (!I.null && len > 0) {
1255  if (palloc(len + 1)) {
1256  memset(CTX(buffer) + CTX(buffer_len), ch, len);
1257  CTX(buffer_len) += len;
1258  (CTX(buffer))[CTX(buffer_len)] = 0;
1259  }
1260  }
1261 }
1262 
1263 RZ_API void rz_cons_strcat(const char *str) {
1264  int len;
1265  if (!str || I.null) {
1266  return;
1267  }
1268  len = strlen(str);
1269  if (len > 0) {
1271  }
1272 }
1273 
1275  if (!I.null) {
1276  rz_cons_strcat("\n");
1277  }
1278 #if 0
1279 This place is wrong to manage the color reset, can interfire with rzpipe output sending resetchars
1280 and break json output appending extra chars.
1281 this code now is managed into output.c:118 at function rz_cons_w32_print
1282 now the console color is reset with each \n (same stuff do it here but in correct place ... i think)
1283 
1284 #if __WINDOWS__
1286 #else
1288 #endif
1289  if (I.is_html) rz_cons_strcat ("<br />\n");
1290 #endif
1291 }
1292 
1299  rz_return_val_if_fail(rows, 0);
1300  int col = CTX(col);
1301  int row = CTX(row);
1302  if (CTX(rowcol_calc_start) > CTX(buffer_len)) {
1304  CTX(rowcol_calc_start) = 0;
1305  }
1306  if (!CTX(buffer)) {
1307  *rows = 0;
1308  return 0;
1309  }
1310  const char *last_line = CTX(buffer) + CTX(rowcol_calc_start);
1311  const char *ptr;
1312  while ((ptr = strchr(last_line, '\n'))) {
1313  last_line = ++ptr;
1314  row++;
1315  };
1316  const char *last_escape = last_line;
1317  while ((ptr = strchr(last_escape, '\x1b'))) {
1318  // ignore ansi chars, copypasta from rz_str_ansi_len
1319  col += ptr - last_escape;
1320  char ch2 = *++ptr;
1321  if (ch2 == '\\') {
1322  ptr++;
1323  } else if (ch2 == ']') {
1324  if (!strncmp(ptr + 2 + 5, "rgb:", 4)) {
1325  ptr += 18;
1326  }
1327  } else if (ch2 == '[') {
1328  for (++ptr; *ptr && *ptr != 'J' && *ptr != 'm' && *ptr != 'H'; ptr++) {
1329  ;
1330  }
1331  }
1332  last_escape = ptr;
1333  }
1334  *rows = row;
1335  CTX(row) = row;
1336  CTX(col) = col;
1337  CTX(rowcol_calc_start) = CTX(buffer_len);
1338  return col;
1339 }
1340 
1342 #if __UNIX__
1343  struct winsize win = { 0 };
1344  const char *tty;
1345  struct stat sb;
1346 
1347  if (!isatty(1)) {
1348  return false;
1349  }
1350  if (ioctl(1, TIOCGWINSZ, &win)) {
1351  return false;
1352  }
1353  if (!win.ws_col || !win.ws_row) {
1354  return false;
1355  }
1356  tty = ttyname(1);
1357  if (!tty) {
1358  return false;
1359  }
1360  if (stat(tty, &sb) || !S_ISCHR(sb.st_mode)) {
1361  return false;
1362  }
1363  return true;
1364 #elif __WINDOWS__
1365  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
1366  if (GetFileType(hOut) == FILE_TYPE_CHAR) {
1367  return true;
1368  }
1369 #endif
1370  /* non-UNIX do not have ttys */
1371  return false;
1372 }
1373 
1374 #if __WINDOWS__
1375 static int __xterm_get_cur_pos(int *xpos) {
1376  int ypos = 0;
1377  const char *get_pos = RZ_CONS_GET_CURSOR_POSITION;
1378  if (write(I.fdout, get_pos, sizeof(get_pos)) < 1) {
1379  return 0;
1380  }
1381  int ch;
1382  char pos[16];
1383  size_t i;
1384  bool is_reply;
1385  do {
1386  is_reply = true;
1387  ch = rz_cons_readchar();
1388  if (ch != 0x1b) {
1389  while ((ch = rz_cons_readchar_timeout(25))) {
1390  if (ch < 1) {
1391  return 0;
1392  }
1393  if (ch == 0x1b) {
1394  break;
1395  }
1396  }
1397  }
1398  (void)rz_cons_readchar();
1399  for (i = 0; i < RZ_ARRAY_SIZE(pos) - 1; i++) {
1400  ch = rz_cons_readchar();
1401  if ((!i && !IS_DIGIT(ch)) || // dumps arrow keys etc.
1402  (i == 1 && ch == '~')) { // dumps PgUp, PgDn etc.
1403  is_reply = false;
1404  break;
1405  }
1406  if (ch == ';') {
1407  pos[i] = 0;
1408  break;
1409  }
1410  pos[i] = ch;
1411  }
1412  } while (!is_reply);
1413  pos[RZ_ARRAY_SIZE(pos) - 1] = 0;
1414  ypos = atoi(pos);
1415  for (i = 0; i < RZ_ARRAY_SIZE(pos) - 1; i++) {
1416  if ((ch = rz_cons_readchar()) == 'R') {
1417  pos[i] = 0;
1418  break;
1419  }
1420  pos[i] = ch;
1421  }
1422  pos[RZ_ARRAY_SIZE(pos) - 1] = 0;
1423  *xpos = atoi(pos);
1424 
1425  return ypos;
1426 }
1427 
1428 static bool __xterm_get_size(void) {
1429  if (write(I.fdout, RZ_CONS_CURSOR_SAVE, sizeof(RZ_CONS_CURSOR_SAVE)) < 1) {
1430  return false;
1431  }
1432  int rows, columns;
1433  rz_xwrite(I.fdout, "\x1b[999;999H", sizeof("\x1b[999;999H"));
1434  rows = __xterm_get_cur_pos(&columns);
1435  if (rows) {
1436  I.rows = rows;
1437  I.columns = columns;
1438  } // otherwise reuse previous values
1440  return true;
1441 }
1442 
1443 #endif
1444 
1445 // XXX: if this function returns <0 in rows or cols expect MAYHEM
1446 RZ_API int rz_cons_get_size(int *rows) {
1447 #if __WINDOWS__
1448  CONSOLE_SCREEN_BUFFER_INFO csbi;
1449  bool ret = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
1450  if (ret) {
1451  I.columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
1452  I.rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
1453  } else {
1454  if (I.term_xterm) {
1455  ret = __xterm_get_size();
1456  }
1457  if (!ret || (I.columns == -1 && I.rows == 0)) {
1458  // Stdout is probably redirected so we set default values
1459  I.columns = 80;
1460  I.rows = 23;
1461  }
1462  }
1463 #elif EMSCRIPTEN
1464  I.columns = 80;
1465  I.rows = 23;
1466 #elif __UNIX__
1467  struct winsize win = { 0 };
1468  if (isatty(0) && !ioctl(0, TIOCGWINSZ, &win)) {
1469  if ((!win.ws_col) || (!win.ws_row)) {
1470  const char *tty = isatty(1) ? ttyname(1) : NULL;
1471  int fd = open(tty ? tty : "/dev/tty", O_RDONLY);
1472  if (fd != -1) {
1473  int ret = ioctl(fd, TIOCGWINSZ, &win);
1474  if (ret || !win.ws_col || !win.ws_row) {
1475  win.ws_col = 80;
1476  win.ws_row = 23;
1477  }
1478  close(fd);
1479  }
1480  }
1481  I.columns = win.ws_col;
1482  I.rows = win.ws_row;
1483  } else {
1484  I.columns = 80;
1485  I.rows = 23;
1486  }
1487 #else
1488  char *str = rz_sys_getenv("COLUMNS");
1489  if (str) {
1490  I.columns = atoi(str);
1491  I.rows = 23; // XXX. windows must get console size
1492  free(str);
1493  } else {
1494  I.columns = 80;
1495  I.rows = 23;
1496  }
1497 #endif
1498 #if SIMULATE_ADB_SHELL
1499  I.rows = 0;
1500  I.columns = 0;
1501 #endif
1502 #if SIMULATE_MAYHEM
1503  // expect tons of crashes
1504  I.rows = -1;
1505  I.columns = -1;
1506 #endif
1507  if (I.rows < 0) {
1508  I.rows = 0;
1509  }
1510  if (I.columns < 0) {
1511  I.columns = 0;
1512  }
1513  if (I.force_columns) {
1514  I.columns = I.force_columns;
1515  }
1516  if (I.force_rows) {
1517  I.rows = I.force_rows;
1518  }
1519  if (I.fix_columns) {
1520  I.columns += I.fix_columns;
1521  }
1522  if (I.fix_rows) {
1523  I.rows += I.fix_rows;
1524  }
1525  if (rows) {
1526  *rows = I.rows;
1527  }
1528  I.rows = RZ_MAX(0, I.rows);
1529  return RZ_MAX(0, I.columns);
1530 }
1531 
1532 #if __WINDOWS__
1533 RZ_API RzVirtTermMode rz_cons_detect_vt_mode(void) {
1534  DWORD major;
1535  DWORD minor;
1536  DWORD release = 0;
1537  char *wt_session = rz_sys_getenv("WT_SESSION");
1538  if (wt_session) {
1539  free(wt_session);
1541  }
1542  char *alacritty = rz_sys_getenv("ALACRITTY_LOG");
1543  if (alacritty) {
1544  free(alacritty);
1546  }
1547  char *term = rz_sys_getenv("TERM");
1548  if (term) {
1549  if (strstr(term, "xterm")) {
1550  I.term_xterm = 1;
1551  free(term);
1552  return 2;
1553  }
1554  I.term_xterm = 0;
1555  free(term);
1556  }
1557  char *ansicon = rz_sys_getenv("ANSICON");
1558  if (ansicon) {
1559  free(ansicon);
1561  }
1563  RSysInfo *info = rz_sys_info();
1564  if (info && info->version) {
1565  char *dot = strtok(info->version, ".");
1566  major = atoi(dot);
1567  dot = strtok(NULL, ".");
1568  minor = atoi(dot);
1569  if (info->release) {
1570  release = atoi(info->release);
1571  }
1572  if (major > 10 || (major == 10 && minor > 0) || (major == 10 && minor == 0 && release >= 1703)) {
1573  win_support = RZ_VIRT_TERM_MODE_OUTPUT_ONLY;
1574  }
1575  }
1577  return win_support;
1578 }
1579 #endif
1580 
1581 RZ_API void rz_cons_show_cursor(int cursor) {
1582 #if __WINDOWS__
1583  if (I.vtmode != RZ_VIRT_TERM_MODE_DISABLE) {
1584 #endif
1585  rz_xwrite(1, cursor ? "\x1b[?25h" : "\x1b[?25l", 6);
1586 #if __WINDOWS__
1587  } else {
1588  static HANDLE hStdout = NULL;
1589  static DWORD size = -1;
1590  CONSOLE_CURSOR_INFO cursor_info;
1591  if (!hStdout) {
1592  hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
1593  }
1594  if (size == -1) {
1595  GetConsoleCursorInfo(hStdout, &cursor_info);
1596  size = cursor_info.dwSize;
1597  }
1598  cursor_info.dwSize = size;
1599  cursor_info.bVisible = cursor ? TRUE : FALSE;
1600  SetConsoleCursorInfo(hStdout, &cursor_info);
1601  }
1602 #endif
1603 }
1604 
1617 RZ_API void rz_cons_set_raw(bool is_raw) {
1618  static int oldraw = -1;
1619  if (oldraw != -1) {
1620  if (is_raw == oldraw) {
1621  return;
1622  }
1623  }
1624 #if EMSCRIPTEN
1625  /* do nothing here */
1626 #elif __UNIX__
1627  // enforce echo off
1628  if (is_raw) {
1629  I.term_raw.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
1630  tcsetattr(0, TCSANOW, &I.term_raw);
1631  } else {
1632  tcsetattr(0, TCSANOW, &I.term_buf);
1633  }
1634 #elif __WINDOWS__
1635  DWORD mode;
1636  HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
1637  GetConsoleMode(h, &mode);
1638  if (is_raw) {
1639  if (I.term_xterm) {
1640  rz_sys_xsystem("stty raw -echo");
1641  } else {
1642  SetConsoleMode(h, mode & I.term_raw);
1643  }
1644  } else {
1645  if (I.term_xterm) {
1646  rz_sys_xsystem("stty -raw echo");
1647  } else {
1648  SetConsoleMode(h, mode | I.term_buf);
1649  }
1650  }
1651 #else
1652 #warning No raw console supported for this platform
1653 #endif
1654  fflush(stdout);
1655  oldraw = is_raw;
1656 }
1657 
1659  I.use_utf8 = b;
1660 }
1661 
1662 RZ_API void rz_cons_invert(int set, int color) {
1663  rz_cons_strcat(RZ_CONS_INVERT(set, color));
1664 }
1665 
1666 /*
1667  Enable/Disable scrolling in terminal:
1668  FMI: cd librz/cons/t ; make ti ; ./ti
1669  smcup: disable terminal scrolling (fullscreen mode)
1670  rmcup: enable terminal scrolling (normal mode)
1671 */
1672 RZ_API bool rz_cons_set_cup(bool enable) {
1673 #if __UNIX__
1674  const char *code = enable
1675  ? "\x1b[?1049h"
1676  "\x1b"
1677  "7\x1b[?47h"
1678  : "\x1b[?1049l"
1679  "\x1b[?47l"
1680  "\x1b"
1681  "8";
1682  const size_t code_len = strlen(code);
1683  if (write(2, code, code_len) != code_len) {
1684  return false;
1685  }
1686  fflush(stdout);
1687 #elif __WINDOWS__
1688  if (I.vtmode != RZ_VIRT_TERM_MODE_DISABLE) {
1689  if (enable) {
1690  const char *code = enable // xterm + xterm-color
1691  ? "\x1b[?1049h\x1b"
1692  "7\x1b[?47h"
1693  : "\x1b[?1049l\x1b[?47l"
1694  "\x1b"
1695  "8";
1696  const size_t code_len = strlen(code);
1697  if (write(2, code, code_len) != code_len) {
1698  return false;
1699  }
1700  }
1701  fflush(stdout);
1702  }
1703 #endif
1704  return true;
1705 }
1706 
1708  char *b = malloc(CTX(buffer_len) + 1);
1709  if (!b) {
1710  return;
1711  }
1712  memcpy(b, CTX(buffer), CTX(buffer_len));
1713  b[CTX(buffer_len)] = 0;
1714  rz_cons_reset();
1715  // align current buffer N chars right
1716  rz_cons_strcat_justify(b, c, 0);
1717  rz_cons_gotoxy(0, 0);
1718  free(b);
1719 }
1720 
1721 // XXX deprecate must be push/pop context state
1722 static bool lasti = false; /* last interactive mode */
1723 
1727 }
1728 
1731 }
1732 
1733 RZ_API void rz_cons_set_title(const char *str) {
1734 #if __WINDOWS__
1735 #if defined(_UNICODE)
1736  wchar_t *wstr = rz_utf8_to_utf16_l(str, strlen(str));
1737  if (wstr) {
1738  SetConsoleTitleW(wstr);
1739  RZ_FREE(wstr);
1740  }
1741 #else // defined(_UNICODE)
1742  SetConsoleTitle(str);
1743 #endif // defined(_UNICODE)
1744 #else
1745  rz_cons_printf("\x1b]0;%s\007", str);
1746 #endif
1747 }
1748 
1749 RZ_API void rz_cons_zero(void) {
1750  if (I.line) {
1751  I.line->zerosep = true;
1752  }
1753  rz_xwrite(1, "", 1);
1754 }
1755 
1756 RZ_API void rz_cons_highlight(const char *word) {
1757  int l, *cpos = NULL;
1758  char *rword = NULL, *res, *clean = NULL;
1759  char *inv[2] = {
1760  RZ_CONS_INVERT(true, true),
1761  RZ_CONS_INVERT(false, true)
1762  };
1763  int linv[2] = {
1764  strlen(inv[0]),
1765  strlen(inv[1])
1766  };
1767 
1768  if (!I.enable_highlight) {
1770  return;
1771  }
1772  if (word && *word && CTX(buffer)) {
1773  int word_len = strlen(word);
1774  char *orig;
1775  clean = rz_str_ndup(CTX(buffer), CTX(buffer_len));
1776  l = rz_str_ansi_filter(clean, &orig, &cpos, -1);
1777  free(CTX(buffer));
1778  CTX(buffer) = orig;
1779  if (I.highlight) {
1780  if (strcmp(word, I.highlight)) {
1781  free(I.highlight);
1782  I.highlight = strdup(word);
1783  }
1784  } else {
1785  I.highlight = strdup(word);
1786  }
1787  rword = malloc(word_len + linv[0] + linv[1] + 1);
1788  if (!rword) {
1789  free(cpos);
1790  free(clean);
1791  return;
1792  }
1793  strcpy(rword, inv[0]);
1794  strcpy(rword + linv[0], word);
1795  strcpy(rword + linv[0] + word_len, inv[1]);
1796  res = rz_str_replace_thunked(CTX(buffer), clean, cpos,
1797  l, word, rword, 1);
1798  if (res) {
1799  CTX(buffer) = res;
1800  CTX(buffer_len) = CTX(buffer_sz) = strlen(res);
1801  }
1802  free(rword);
1803  free(clean);
1804  free(cpos);
1806  /* don't free orig - it's assigned
1807  * to CTX(buffer) and possibly realloc'd */
1808  } else {
1809  RZ_FREE(I.highlight);
1810  }
1811 }
1812 
1814  char *b = CTX(buffer) + CTX(buffer_len);
1815  while (b > CTX(buffer)) {
1816  if (*b == '\n') {
1817  b++;
1818  break;
1819  }
1820  b--;
1821  }
1822  if (len) {
1823  int delta = b - CTX(buffer);
1824  *len = CTX(buffer_len) - delta;
1825  }
1826  return b;
1827 }
1828 
1829 // same as rz_cons_lastline(), but len will be the number of
1830 // utf-8 characters excluding ansi escape sequences as opposed to just bytes
1832  if (!len) {
1833  return rz_cons_lastline(0);
1834  }
1835 
1836  char *b = CTX(buffer) + CTX(buffer_len);
1837  int l = 0;
1838  int last_possible_ansi_end = 0;
1839  char ch = '\0';
1840  char ch2;
1841  while (b > CTX(buffer)) {
1842  ch2 = ch;
1843  ch = *b;
1844 
1845  if (ch == '\n') {
1846  b++;
1847  l--;
1848  break;
1849  }
1850 
1851  // utf-8
1852  if ((ch & 0xc0) != 0x80) {
1853  l++;
1854  }
1855 
1856  // ansi
1857  if (ch == 'J' || ch == 'm' || ch == 'H') {
1858  last_possible_ansi_end = l - 1;
1859  } else if (ch == '\x1b' && ch2 == '[') {
1860  l = last_possible_ansi_end;
1861  }
1862 
1863  b--;
1864  }
1865 
1866  *len = l;
1867  return b;
1868 }
1869 
1870 /* swap color from foreground to background, returned value must be freed */
1871 RZ_API char *rz_cons_swap_ground(const char *col) {
1872  if (!col) {
1873  return NULL;
1874  }
1875  if (!strncmp(col, "\x1b[48;5;", 7)) {
1876  /* rgb background */
1877  return rz_str_newf("\x1b[38;5;%s", col + 7);
1878  } else if (!strncmp(col, "\x1b[38;5;", 7)) {
1879  /* rgb foreground */
1880  return rz_str_newf("\x1b[48;5;%s", col + 7);
1881  } else if (!strncmp(col, "\x1b[4", 3)) {
1882  /* is background */
1883  return rz_str_newf("\x1b[3%s", col + 3);
1884  } else if (!strncmp(col, "\x1b[3", 3)) {
1885  /* is foreground */
1886  return rz_str_newf("\x1b[4%s", col + 3);
1887  }
1888  return strdup(col);
1889 }
1890 
1891 RZ_API bool rz_cons_drop(int n) {
1892  if (n > CTX(buffer_len)) {
1893  CTX(buffer_len) = 0;
1894  return false;
1895  }
1896  CTX(buffer_len) -= n;
1897  return true;
1898 }
1899 
1900 RZ_API void rz_cons_chop(void) {
1901  while (CTX(buffer_len) > 0) {
1902  char ch = CTX(buffer)[CTX(buffer_len) - 1];
1903  if (ch != '\n' && !IS_WHITESPACE(ch)) {
1904  break;
1905  }
1906  (CTX(buffer_len))--;
1907  }
1908 }
1909 
1911  if (!bind) {
1912  return;
1913  }
1914  bind->get_size = rz_cons_get_size;
1915  bind->get_cursor = rz_cons_get_cursor;
1916  bind->cb_printf = rz_cons_printf;
1917  bind->cb_flush = rz_cons_flush;
1918  bind->cb_grep = rz_cons_grep;
1919  bind->is_breaked = rz_cons_is_breaked;
1920 }
1921 
1922 RZ_API const char *rz_cons_get_rune(const ut8 ch) {
1923  switch (ch) {
1924  case RUNECODE_LINE_HORIZ: return RUNE_LINE_HORIZ;
1925  case RUNECODE_LINE_VERT: return RUNE_LINE_VERT;
1926  case RUNECODE_LINE_CROSS: return RUNE_LINE_CROSS;
1927  case RUNECODE_CORNER_TL: return RUNE_CORNER_TL;
1928  case RUNECODE_CORNER_TR: return RUNE_CORNER_TR;
1929  case RUNECODE_CORNER_BR: return RUNE_CORNER_BR;
1930  case RUNECODE_CORNER_BL: return RUNE_CORNER_BL;
1935  }
1936  return NULL;
1937 }
1938 
1940  free(I.break_word);
1941  if (s) {
1942  I.break_word = strdup(s);
1943  I.break_word_len = strlen(s);
1944  } else {
1945  I.break_word = NULL;
1946  I.break_word_len = 0;
1947  }
1948 }
1949 
1950 /* Prints a coloured help message.
1951  * help should be an array of the following form:
1952  * {"command", "args", "description",
1953  * "command2", "args2", "description"}; */
1954 RZ_API void rz_cons_cmd_help(const char *help[], bool use_color) {
1955  RzCons *cons = rz_cons_singleton();
1956  const char *pal_args_color = use_color ? cons->context->pal.args : "",
1957  *pal_help_color = use_color ? cons->context->pal.help : "",
1958  *pal_input_color = use_color ? cons->context->pal.input : "",
1959  *pal_reset = use_color ? cons->context->pal.reset : "";
1960  int i, max_length = 0;
1961  const char *usage_str = "Usage:";
1962 
1963  for (i = 0; help[i]; i += 3) {
1964  int len0 = strlen(help[i]);
1965  int len1 = strlen(help[i + 1]);
1966  if (i) {
1967  max_length = RZ_MAX(max_length, len0 + len1);
1968  }
1969  }
1970 
1971  for (i = 0; help[i]; i += 3) {
1972  if (!strncmp(help[i], usage_str, strlen(usage_str))) {
1973  // Lines matching Usage: should always be the first in inline doc
1974  rz_cons_printf("%s%s %s %s%s\n", pal_args_color,
1975  help[i], help[i + 1], help[i + 2], pal_reset);
1976  continue;
1977  }
1978  if (!help[i + 1][0] && !help[i + 2][0]) {
1979  // no need to indent the sections lines
1980  rz_cons_printf("%s%s%s\n", pal_help_color, help[i], pal_reset);
1981  } else {
1982  // these are the normal lines
1983  int str_length = strlen(help[i]) + strlen(help[i + 1]);
1984  int padding = (str_length < max_length) ? (max_length - str_length) : 0;
1985  rz_cons_printf("| %s%s%s%s%*s %s%s%s\n",
1986  pal_input_color, help[i], pal_args_color, help[i + 1],
1987  padding, "", pal_help_color, help[i + 2], pal_reset);
1988  }
1989  }
1990 }
1991 
1993  if (I.vtmode != RZ_VIRT_TERM_MODE_DISABLE) {
1994  rz_xwrite(1, "\x1b"
1995  "c\x1b[3J",
1996  6);
1997  }
1998 }
1999 
2006 RZ_API void rz_cons_set_flush(bool flush) {
2007  CTX(noflush) = !flush;
2008 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define W(x, y, z)
#define H(x)
static SblHeader sb
Definition: bin_mbn.c:26
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
static RzBinSourceLineInfo * lines(RzBinFile *bf)
Definition: bin_symbols.c:427
const lzma_allocator const uint8_t * in
Definition: block.h:527
static RzBuffer * new_buffer(RzBufferType type, void *user)
Definition: buf.c:244
struct buffer buffer
static RzNumCalcValue term(RzNum *, RzNumCalc *, int)
Definition: calc.c:189
RZ_API void rz_cons_break_clear(void)
Definition: cons.c:304
RZ_API int rz_cons_get_buffer_len(void)
Definition: cons.c:832
static bool lastMatters(void)
Definition: cons.c:935
static void cons_context_init(RzConsContext *context, RZ_NULLABLE RzConsContext *parent)
Definition: cons.c:111
RZ_API void rz_cons_set_utf8(bool b)
Definition: cons.c:1658
RZ_API void rz_cons_zero(void)
Definition: cons.c:1749
RZ_API void rz_cons_filter(void)
Definition: cons.c:836
RZ_API bool rz_cons_default_context_is_interactive(void)
Definition: cons.c:369
static RzConsContext rz_cons_context_default
Definition: cons.c:20
RZ_API void rz_cons_memset(char ch, int len)
Definition: cons.c:1253
static void __cons_write_ll(const char *buf, int len)
Definition: cons.c:150
RZ_API void rz_cons_last(void)
Definition: cons.c:927
RZ_API void rz_cons_clear00(void)
Definition: cons.c:778
RZ_API void rz_cons_break_timeout(int timeout)
Definition: cons.c:421
RZ_API bool rz_cons_set_cup(bool enable)
Definition: cons.c:1672
RZ_API void rz_cons_breakword(RZ_NULLABLE const char *s)
Definition: cons.c:1939
RZ_API void rz_cons_set_raw(bool is_raw)
Definition: cons.c:1617
RZ_API bool rz_cons_drop(int n)
Definition: cons.c:1891
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API RZ_OWN char * rz_cons_get_buffer_dup(void)
Return a newly allocated buffer containing what's currently in RzCons buffer.
Definition: cons.c:827
RZ_API void rz_cons_context_free(RzConsContext *context)
Definition: cons.c:897
RZ_API int rz_cons_memcat(const char *str, int len)
Definition: cons.c:1224
RZ_API const char * rz_cons_get_rune(const ut8 ch)
Definition: cons.c:1922
static void break_stack_free(void *ptr)
Definition: cons.c:47
RZ_API void rz_cons_set_last_interactive(void)
Definition: cons.c:1729
static RzCons rz_cons_instance
Definition: cons.c:21
#define CTX(x)
Definition: cons.c:16
static bool lasti
Definition: cons.c:1722
#define I
Definition: cons.c:22
static void __break_signal(int sig)
Definition: cons.c:146
static void cons_grep_reset(RzConsGrep *grep)
Definition: cons.c:796
RZ_API RzConsContext * rz_cons_context_new(RZ_NULLABLE RzConsContext *parent)
Definition: cons.c:888
static void cons_stack_load(RzConsStack *data, bool free_current)
Definition: cons.c:94
RZ_API void rz_cons_enable_highlight(const bool enable)
Definition: cons.c:496
RZ_API void rz_cons_visual_write(char *buffer)
Definition: cons.c:1097
RZ_API void rz_cons_set_title(const char *str)
Definition: cons.c:1733
RZ_API void rz_cons_context_reset(void)
Definition: cons.c:909
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API void rz_cons_column(int c)
Definition: cons.c:1707
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
RZ_API char * rz_cons_lastline_utf8_ansi_len(int *len)
Definition: cons.c:1831
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API void rz_cons_context_break(RzConsContext *context)
Definition: cons.c:917
RZ_API void rz_cons_strcat(const char *str)
Definition: cons.c:1263
RZ_API void rz_cons_newline(void)
Definition: cons.c:1274
RZ_API void rz_cons_highlight(const char *word)
Definition: cons.c:1756
static bool palloc(int moar)
Definition: cons.c:685
RZ_API void * rz_cons_sleep_begin(void)
Definition: cons.c:443
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API char * rz_cons_lastline(int *len)
Definition: cons.c:1813
RZ_API void rz_cons_strcat_justify(const char *str, int j, char c)
Definition: cons.c:238
RZ_API void rz_cons_bind(RzConsBind *bind)
Definition: cons.c:1910
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API void rz_cons_set_interactive(bool x)
Definition: cons.c:1724
RZ_API RzCons * rz_cons_new(void)
Definition: cons.c:589
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_reset_colors(void)
Definition: cons.c:783
RZ_API void rz_cons_echo(const char *msg)
Definition: cons.c:939
RZ_API void rz_cons_chop(void)
Definition: cons.c:1900
RZ_API void rz_cons_color(int fg, int r, int g, int b)
Definition: cons.c:217
RZ_API const char * rz_cons_get_buffer(void)
Return the current RzCons buffer.
Definition: cons.c:819
RZ_API void rz_cons_printf_list(const char *format, va_list ap)
Definition: cons.c:1170
RZ_API void rz_cons_invert(int set, int color)
Definition: cons.c:1662
static void ctx_rowcol_calc_reset(void)
Definition: cons.c:41
RZ_API void rz_cons_clear_buffer(void)
Definition: cons.c:1992
RZ_API int rz_cons_get_cur_line(void)
Definition: cons.c:387
RZ_API bool rz_cons_is_interactive(void)
Definition: cons.c:365
RZ_API void rz_cons_context_break_pop(RzConsContext *context, bool sig)
Definition: cons.c:335
static void cons_stack_free(void *ptr)
Definition: cons.c:52
RZ_API void rz_cons_cmd_help(const char *help[], bool use_color)
Definition: cons.c:1954
RZ_API bool rz_cons_isatty(void)
Definition: cons.c:1341
RZ_API int rz_cons_get_cursor(RZ_NONNULL int *rows)
Calculates the aproximated x,y coordinates of the cursor before flushing.
Definition: cons.c:1298
RZ_API void rz_cons_visual_flush(void)
Definition: cons.c:1067
RZ_API void rz_cons_strcat_at(const char *_str, int x, char y, int w, int h)
Definition: cons.c:260
RZ_API bool rz_cons_get_click(int *x, int *y)
Definition: cons.c:484
RZ_API void rz_cons_goto_origin_reset(void)
Definition: cons.c:732
RZ_API char * rz_cons_swap_ground(const char *col)
Definition: cons.c:1871
RZ_API void rz_cons_show_cursor(int cursor)
Definition: cons.c:1581
RZ_API void rz_cons_set_click(int x, int y)
Definition: cons.c:477
#define MOAR
Definition: cons.c:684
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API RzColor rz_cons_color_random(ut8 alpha)
Definition: cons.c:183
static void __cons_write(const char *obuf, int olen)
Definition: cons.c:169
RZ_API int rz_cons_eof(void)
Definition: cons.c:720
RZ_API void rz_cons_fill_line(void)
Definition: cons.c:737
RZ_API void rz_cons_break_end(void)
Definition: cons.c:427
RZ_API void rz_cons_context_load(RzConsContext *context)
Definition: cons.c:905
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
RZ_API void rz_cons_context_break_push(RzConsContext *context, RzConsBreak cb, void *user, bool sig)
Definition: cons.c:308
RZ_API void rz_cons_set_flush(bool flush)
Set whether RzCons should flush content to screen or not.
Definition: cons.c:2006
static RzConsStack * cons_stack_dump(bool recreate)
Definition: cons.c:63
RZ_API void rz_cons_sleep_end(void *user)
Definition: cons.c:450
static int real_strlen(const char *ptr, int len)
Definition: cons.c:1087
RZ_API void rz_cons_gotoxy(int x, int y)
Definition: cons.c:724
void resizeWin(void)
Definition: cons.c:471
RZ_API void rz_cons_clear(void)
Definition: cons.c:787
RZ_API int rz_cons_get_column(void)
Definition: cons.c:1214
RZ_API bool rz_cons_context_is_main(void)
Definition: cons.c:913
RZ_API void rz_cons_reset(void)
Definition: cons.c:804
RZ_API RzCons * rz_cons_free(void)
Definition: cons.c:658
static void cons_context_deinit(RzConsContext *context)
Definition: cons.c:138
RZ_LIB_VERSION(rz_cons)
RZ_API void rz_cons_pop(void)
Definition: cons.c:876
RZ_API void rz_cons_push(void)
Definition: cons.c:860
#define RZ_API
#define INT_MAX
Definition: cp-demangle.c:131
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
#define w
Definition: crypto_rc6.c:13
static static fork write
Definition: sflib.h:33
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename ioctl
Definition: sflib.h:62
const char * k
Definition: dsignal.c:11
struct @667 g
#define minor(dev)
Definition: fsmagic.c:57
#define major(dev)
Definition: fsmagic.c:56
RZ_API void rz_cons_grep(const char *grep)
Definition: grep.c:874
RZ_API void rz_cons_grepbuf(void)
Definition: grep.c:463
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API char * rz_cons_html_filter(const char *ptr, int *newlen)
Definition: html.c:34
volatile sig_atomic_t sigwinchFlag
RZ_API int rz_cons_readchar_timeout(ut32 usec)
Definition: input.c:560
RZ_API bool rz_cons_yesno(int def, const char *fmt,...)
Definition: input.c:666
RZ_API int rz_cons_readchar(void)
Definition: input.c:619
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
vsnprintf
Definition: kernel.h:366
RZ_API int rz_cons_less_str(const char *str, const char *exitkeys)
Definition: less.c:10
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static int save
Definition: main.c:14
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
RZ_API RzLine * rz_line_new(void)
Definition: line.c:19
RZ_API void rz_line_free(void)
Definition: line.c:41
static stat
Definition: sflib.h:131
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
#define TRUE
Definition: mybfd.h:103
#define FALSE
Definition: mybfd.h:102
string FILE
Definition: benchmark.py:21
def release
Definition: conf.py:76
line
Definition: setup.py:34
RZ_API void rz_cons_pal_free(RzConsContext *ctx)
Definition: pal.c:247
RZ_API void rz_cons_pal_init(RzConsContext *ctx)
Definition: pal.c:154
RzColor rcolor
Definition: pal.c:97
RZ_API void rz_cons_pal_copy(RzConsContext *dst, RzConsContext *src)
Definition: pal.c:258
RZ_API void rz_print_set_is_interrupted_cb(RzPrintIsInterruptedCallback cb)
Definition: print.c:52
RZ_API void rz_cons_rgb_init(void)
Definition: rgb.c:106
RZ_API char * rz_cons_rgb_str_off(char *outstr, size_t sz, ut64 off)
Definition: rgb.c:209
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RzVirtTermMode
Definition: rz_cons.h:448
@ RZ_VIRT_TERM_MODE_COMPLETE
All the sequences goes through VT (Windows Terminal, mintty, all OSs)
Definition: rz_cons.h:451
@ RZ_VIRT_TERM_MODE_OUTPUT_ONLY
Windows only: Use console c api for input, but output on VT (Windows >= 10)
Definition: rz_cons.h:450
@ RZ_VIRT_TERM_MODE_DISABLE
Windows only: Use console c api for everything (Windows <= 8)
Definition: rz_cons.h:449
#define RZ_CONS_CLEAR_LINE
Definition: rz_cons.h:593
#define RZ_CONS_CLEAR_SCREEN
Definition: rz_cons.h:594
#define RZ_CONS_CURSOR_SAVE
Definition: rz_cons.h:597
#define Color_RESET
Definition: rz_cons.h:617
#define RzColor_WHITE
Definition: rz_cons.h:706
#define RUNECODE_LINE_HORIZ
Definition: rz_cons.h:374
#define Color_RESET_BG
Definition: rz_cons.h:619
#define RZ_CONS_CMD_DEPTH
Definition: rz_cons.h:55
#define RUNE_LINE_CROSS
Definition: rz_cons.h:402
@ COLOR_MODE_16
Definition: rz_cons.h:443
@ COLOR_MODE_DISABLED
Definition: rz_cons.h:442
#define RUNECODE_CURVE_CORNER_TL
Definition: rz_cons.h:378
void(* RzConsEvent)(void *)
Definition: rz_cons.h:346
#define CONS_MAX_USER
Definition: rz_cons.h:41
#define RUNE_CURVE_CORNER_TL
Definition: rz_cons.h:413
#define RUNECODE_CORNER_BL
Definition: rz_cons.h:371
#define RUNE_LINE_HORIZ
Definition: rz_cons.h:403
#define RzColor_YELLOW
Definition: rz_cons.h:712
#define RUNE_CORNER_TR
Definition: rz_cons.h:408
#define RzColor_RED
Definition: rz_cons.h:704
#define RUNECODE_CORNER_BR
Definition: rz_cons.h:370
#define RzColor_GREEN
Definition: rz_cons.h:708
#define RUNECODE_LINE_VERT
Definition: rz_cons.h:368
#define RUNE_CORNER_BL
Definition: rz_cons.h:406
#define RUNECODE_LINE_CROSS
Definition: rz_cons.h:369
#define RUNECODE_CURVE_CORNER_BR
Definition: rz_cons.h:380
struct rcolor_t RzColor
#define RUNE_CORNER_TL
Definition: rz_cons.h:407
#define RUNECODE_CURVE_CORNER_BL
Definition: rz_cons.h:381
#define Color_RESET_ALL
Definition: rz_cons.h:620
#define RzColor_MAGENTA
Definition: rz_cons.h:710
#define RZ_CONS_CURSOR_RESTORE
Definition: rz_cons.h:598
#define RUNE_CORNER_BR
Definition: rz_cons.h:405
#define RZ_CONS_GET_CURSOR_POSITION
Definition: rz_cons.h:599
#define RzColor_GRAY
Definition: rz_cons.h:735
#define RUNECODE_CURVE_CORNER_TR
Definition: rz_cons.h:379
#define RUNECODE_CORNER_TL
Definition: rz_cons.h:375
#define RUNE_CURVE_CORNER_BR
Definition: rz_cons.h:415
@ RZ_CONS_ATTR_BOLD
Definition: rz_cons.h:171
#define RzColor_CYAN
Definition: rz_cons.h:714
#define RUNE_CURVE_CORNER_BL
Definition: rz_cons.h:416
#define RZ_CONS_CLEAR_FROM_CURSOR_TO_END
Definition: rz_cons.h:595
#define RUNE_LINE_VERT
Definition: rz_cons.h:401
#define RzColor_BLUE
Definition: rz_cons.h:716
#define RUNECODE_CORNER_TR
Definition: rz_cons.h:376
#define RUNE_CURVE_CORNER_TR
Definition: rz_cons.h:414
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
RZ_API const ut8 * rz_mem_mem(const ut8 *haystack, int hlen, const ut8 *needle, int nlen)
Definition: mem.c:246
RZ_API char * rz_num_units(char *buf, size_t len, ut64 number)
Definition: unum.c:108
RZ_API int rz_num_rand(int max)
Definition: unum.c:47
RZ_API bool rz_stack_is_empty(RzStack *s)
Definition: stack.c:68
RZ_API RzStack * rz_stack_newf(ut32 n, RzStackFree f)
Definition: stack.c:21
RZ_API void * rz_stack_pop(RzStack *s)
Definition: stack.c:59
RZ_API bool rz_stack_push(RzStack *s, void *el)
Definition: stack.c:42
RZ_API void rz_stack_free(RzStack *s)
Definition: stack.c:29
RZ_API int rz_str_char_count(const char *string, char ch)
Definition: str.c:611
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API size_t rz_str_ansi_len(const char *str)
Definition: str.c:1945
RZ_API int rz_str_ansi_filter(char *str, char **out, int **cposs, int len)
Definition: str.c:2124
RZ_API const char * rz_str_ansi_chrn(const char *str, size_t n)
Definition: str.c:2098
RZ_API size_t rz_str_len_utf8(const char *s)
Definition: str.c:2709
RZ_API char * rz_str_ansi_crop(const char *str, unsigned int x, unsigned int y, unsigned int x2, unsigned int y2)
Definition: str.c:2174
RZ_API char * rz_str_replace_thunked(char *str, char *clean, int *thunk, int clen, const char *key, const char *val, int g)
Definition: str.c:1233
#define IS_WHITESPACE(x)
Definition: rz_str_util.h:13
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
#define rz_sys_xsystem(cmd)
Definition: rz_sys.h:83
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
RZ_API void rz_sys_info_free(RSysInfo *si)
Definition: sys.c:1251
RZ_API int rz_sys_usleep(int usecs)
Sleep for usecs microseconds.
Definition: sys.c:317
RZ_API RSysInfo * rz_sys_info(void)
Definition: sys.c:1175
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
Definition: sys.c:178
RZ_API int rz_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr)
Definition: sys.c:590
RZ_API ut64 rz_time_now_mono(void)
Returns the current time in microseconds, using the monotonic clock.
Definition: time.c:102
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define rz_xwrite(fd, buf, count)
Definition: rz_types.h:642
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_DIM(x, y, z)
#define RZ_MIN(x, y)
#define RZ_MAX(x, y)
#define isdigit(c)
Definition: safe-ctype.h:131
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static bind
Definition: sfsocketcall.h:114
static int
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define CS8
Definition: sftypes.h:942
#define TIOCGWINSZ
Definition: sftypes.h:721
#define BRKINT
Definition: sftypes.h:871
#define ISIG
Definition: sftypes.h:970
#define VMIN
Definition: sftypes.h:857
#define ICANON
Definition: sftypes.h:971
#define PARMRK
Definition: sftypes.h:873
#define IXON
Definition: sftypes.h:880
#define O_RDONLY
Definition: sftypes.h:486
#define TCSANOW
Definition: sftypes.h:998
#define ECHO
Definition: sftypes.h:973
#define IGNCR
Definition: sftypes.h:877
#define IEXTEN
Definition: sftypes.h:984
#define PARENB
Definition: sftypes.h:945
#define INLCR
Definition: sftypes.h:876
#define CSIZE
Definition: sftypes.h:938
#define ECHONL
Definition: sftypes.h:976
#define ICRNL
Definition: sftypes.h:878
#define ISTRIP
Definition: sftypes.h:875
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
#define h(i)
Definition: sha256.c:48
bool breaked
Definition: cons.c:34
RzConsEvent event_interrupt
Definition: cons.c:35
void * event_interrupt_data
Definition: cons.c:36
int buf_len
Definition: cons.c:27
char * buf
Definition: cons.c:26
bool noflush
Definition: cons.c:30
RzConsGrep * grep
Definition: cons.c:29
int buf_size
Definition: cons.c:28
Definition: buffer.h:15
Definition: inftree9.h:24
zip_uint8_t buffer[BUFSIZE]
ut8 g
Definition: rz_cons.h:183
ut8 b
Definition: rz_cons.h:184
ut8 r
Definition: rz_cons.h:182
ut8 a
Definition: rz_cons.h:181
ut8 attr
Definition: rz_cons.h:180
RzConsPrintablePalette pal
Definition: rz_cons.h:491
bool is_interactive
Definition: rz_cons.h:485
char * str
Definition: rz_cons.h:75
bool sort_invert
Definition: rz_cons.h:87
RzConsContext * context
Definition: rz_cons.h:502
Definition: sftypes.h:80
unsigned short ws_row
Definition: sftypes.h:784
unsigned short ws_col
Definition: sftypes.h:785
int pos
Definition: main.c:11
uv_tty_t tty
Definition: main.c:7
uv_timer_t timeout
Definition: main.c:9
static int color
Definition: visual.c:20
static st64 delta
Definition: vmenus.c:2425
#define SIGWINCH
Definition: win.h:88
#define ENABLE_QUICK_EDIT_MODE
Definition: winapi.h:4629
#define ENABLE_EXTENDED_FLAGS
Definition: winapi.h:4633
static bool breaked
DWORD * HANDLE
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
DWORD
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176
static unsigned char * obuf
Definition: z80asm.c:36
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
diff_output_t output
Definition: zipcmp.c:237
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115