From 44d9048169dc57c52c01185ca2ab01ea4c0990b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Felipe=20Melchor?= Date: Tue, 18 Oct 2016 23:15:51 +0200 Subject: [PATCH] Fix #5986 - use RStack in r_cons_push/pop clean up cons and stack code extend RStack to have free function use RStack in r_cons_push/pop --- libr/cons/cons.c | 179 ++++++++++++++++++++-------------- libr/include/r_cons.h | 1 + libr/include/r_util/r_stack.h | 6 +- libr/util/stack.c | 32 ++++-- 4 files changed, 139 insertions(+), 79 deletions(-) diff --git a/libr/cons/cons.c b/libr/cons/cons.c index 92a8e69a04..d36b06e38f 100644 --- a/libr/cons/cons.c +++ b/libr/cons/cons.c @@ -18,6 +18,20 @@ R_LIB_VERSION (r_cons); static RCons r_cons_instance; #define I r_cons_instance +//this structure goes into cons_stack when r_cons_push/pop +typedef struct { + char *buf; + int buf_len; + int buf_size; +} RConsStack; + + +static void cons_stack_free(void *ptr) { + RConsStack *s = (RConsStack *)ptr; + free (s->buf); + free (s); +} + static void break_signal(int sig) { I.breaked = true; r_print_set_interrupted (I.breaked); @@ -26,7 +40,7 @@ static void break_signal(int sig) { } } -static inline void r_cons_write (const char *buf, int len) { +static inline void r_cons_write(const char *buf, int len) { #if __WINDOWS__ && !__CYGWIN__ if (I.ansicon) { (void) write (I.fdout, buf, len); @@ -210,7 +224,7 @@ static void r_cons_pal_null() { } } -R_API RCons *r_cons_new () { +R_API RCons *r_cons_new() { I.refcnt++; if (I.refcnt != 1) { return &I; @@ -267,6 +281,7 @@ R_API RCons *r_cons_new () { I.pager = NULL; /* no pager by default */ I.truecolor = 0; I.mouse = 0; + I.cons_stack = r_stack_newf (6, cons_stack_free); r_cons_pal_null (); r_cons_pal_init (NULL); r_cons_rgb_init (); @@ -274,7 +289,7 @@ R_API RCons *r_cons_new () { return &I; } -R_API RCons *r_cons_free () { +R_API RCons *r_cons_free() { I.refcnt--; if (I.refcnt != 0) { return NULL; @@ -288,6 +303,7 @@ R_API RCons *r_cons_free () { free (I.buffer); I.buffer = NULL; } + r_stack_free (I.cons_stack); return NULL; } @@ -330,19 +346,6 @@ R_API int r_cons_eof() { } R_API void r_cons_gotoxy(int x, int y) { -#if 0 -#if __WINDOWS__ - static HANDLE hStdout = NULL; - COORD coord; - coord.X = x; - coord.Y = y; - if (!hStdout) - hStdout = GetStdHandle (STD_OUTPUT_HANDLE); - SetConsoleCursorPosition (hStdout, coord); -#else - r_cons_printf ("\x1b[%d;%dH", y, x); -#endif -#endif r_cons_printf ("\x1b[%d;%dH", y, x); } @@ -375,9 +378,11 @@ R_API void r_cons_clear_line(int std_err) { } else { char white[1024]; memset (&white, ' ', sizeof (white)); - if (I.columnsbuf = malloc (I.buffer_len); + if (!data->buf) { + free (data); return; } - memcpy (I.buffer, backup, I.buffer_len); + memcpy (data->buf, I.buffer, I.buffer_len); + data->buf_len = I.buffer_len; + data->buf_size = I.buffer_sz; + r_stack_push (I.cons_stack, data); I.buffer_len = 0; } } R_API void r_cons_pop() { - if (backup) { - free (I.buffer); - I.buffer = backup; - I.buffer_len = backup_len; - I.buffer_sz = backup_size; - backup = NULL; + if (I.cons_stack) { + RConsStack *data = (RConsStack *)r_stack_pop (I.cons_stack); + if (!data) { + return; + } + if (!data->buf) { + free (data); + return; + } + memcpy (I.buffer, data->buf, data->buf_len); + I.buffer_len = data->buf_len; + I.buffer_sz = data->buf_size; + cons_stack_free ((void *)data); } } @@ -482,11 +490,12 @@ R_API void r_cons_flush() { } else if (I.buffer_len > CONS_MAX_USER) { #if COUNT_LINES int i, lines = 0; - for (i=0; I.buffer[i]; i++) { - if (I.buffer[i]=='\n') + for (i = 0; I.buffer[i]; i++) { + if (I.buffer[i]=='\n') { lines ++; + } } - if (lines>0 && !r_cons_yesno ('n',"Do you want to print %d lines? (y/N)", lines)) { + if (lines > 0 && !r_cons_yesno ('n',"Do you want to print %d lines? (y/N)", lines)) { r_cons_reset (); return; } @@ -504,16 +513,21 @@ R_API void r_cons_flush() { } if (tee && *tee) { FILE *d = r_sandbox_fopen (tee, "a+"); - if (d != NULL) { + if (d) { if (I.buffer_len != fwrite (I.buffer, 1, I.buffer_len, d)) eprintf ("r_cons_flush: fwrite: error (%s)\n", tee); fclose (d); - } else eprintf ("Cannot write on '%s'\n", tee); + } else { + eprintf ("Cannot write on '%s'\n", tee); + } } r_cons_highlight (I.highlight); // is_html must be a filter, not a write endpoint - if (I.is_html) r_cons_html_print (I.buffer); - else r_cons_write (I.buffer, I.buffer_len); + if (I.is_html) { + r_cons_html_print (I.buffer); + } else { + r_cons_write (I.buffer, I.buffer_len); + } r_cons_reset (); if (I.newline) { @@ -549,7 +563,9 @@ R_API void r_cons_visual_flush() { ut64 diff = now-prev; fps = (diff<1000000)? (1000000/diff): 0; prev = now; - } else prev = r_sys_now (); + } else { + prev = r_sys_now (); + } eprintf ("\x1b[0;%dH[%d FPS] \n", w-10, fps); } } @@ -571,7 +587,9 @@ R_API void r_cons_visual_write (char *buffer) { const char *endptr; char *nl, *ptr = buffer, *pptr; - if (I.null) return; + if (I.null) { + return; + } memset (&white, ' ', sizeof (white)); while ((nl = strchr (ptr, '\n'))) { int len = ((int)(size_t)(nl-ptr))+1; @@ -598,9 +616,10 @@ R_API void r_cons_visual_write (char *buffer) { if (lines > 0) { int w = cols - alen; r_cons_write (pptr, plen); - if (I.blankline && w>0) { - if (w > sizeof (white) - 1) + if (I.blankline && w > 0) { + if (w > sizeof (white) - 1) { w = sizeof (white) - 1; + } r_cons_write (white, w); } } @@ -628,7 +647,9 @@ R_API void r_cons_printf(const char *format, ...) { size_t size, written; va_list ap; - if (I.null || !format) return; + if (I.null || !format) { + return; + } if (strchr (format, '%')) { palloc (MOAR + strlen (format) * 20); size = I.buffer_sz - I.buffer_len - 1; /* remaining space in I.buffer */ @@ -649,7 +670,9 @@ R_API void r_cons_printf(const char *format, ...) { R_API int r_cons_get_column() { char *line = strrchr (I.buffer, '\n'); - if (!line) line = I.buffer; + if (!line) { + line = I.buffer; + } I.buffer[I.buffer_len] = 0; return r_str_ansi_len (line); } @@ -712,10 +735,10 @@ R_API int r_cons_get_cursor(int *rows) { if (ch2 == '\\') { i++; } else if (ch2 == ']') { - if (!strncmp (str+2+5, "rgb:", 4)) + if (!strncmp (str + 2 + 5, "rgb:", 4)) i += 18; } else if (ch2 == '[') { - for (++i; str[i]&&str[i]!='J'&& str[i]!='m'&&str[i]!='H';i++); + for (++i; str[i] && str[i] != 'J' && str[i] != 'm' && str[i] != 'H'; i++); } } else if (I.buffer[i] == '\n') { row++; @@ -742,7 +765,7 @@ R_API bool r_cons_isatty() { if (ioctl (1, TIOCGWINSZ, &win)) { return false; } - if ((win.ws_col == 0) || (win.ws_row == 0)) { + if (!win.ws_col || !win.ws_row) { return false; } tty = ttyname (1); @@ -771,13 +794,13 @@ R_API int r_cons_get_size(int *rows) { I.rows = 23; #elif __UNIX__ || __CYGWIN__ struct winsize win = { 0 }; - if (isatty (0) && ioctl (0, TIOCGWINSZ, &win) == 0) { - if ((win.ws_col == 0) || (win.ws_row == 0)) { + if (isatty (0) && !ioctl (0, TIOCGWINSZ, &win)) { + if ((!win.ws_col) || (!win.ws_row)) { const char *tty = ttyname (1); int fd = open (tty? tty: "/dev/tty", O_RDONLY); if (fd != -1) { int ret = ioctl (fd, TIOCGWINSZ, &win); - if ((ret != 0) || (win.ws_col == 0) || (win.ws_row == 0)) { + if (ret || !win.ws_col || !win.ws_row) { win.ws_col = 80; win.ws_row = 23; } @@ -816,12 +839,21 @@ R_API int r_cons_get_size(int *rows) { if (I.columns < 0) { I.columns = 0; } - if (I.force_columns) I.columns = I.force_columns; - if (I.force_rows) I.rows = I.force_rows; - if (I.fix_columns) I.columns += I.fix_columns; - if (I.fix_rows) I.rows += I.fix_rows; - if (rows) + if (I.force_columns) { + I.columns = I.force_columns; + } + if (I.force_rows) { + I.rows = I.force_rows; + } + if (I.fix_columns) { + I.columns += I.fix_columns; + } + if (I.fix_rows) { + I.rows += I.fix_rows; + } + if (rows) { *rows = I.rows; + } I.rows = R_MAX (0, I.rows); return R_MAX (0, I.columns); } @@ -925,7 +957,9 @@ R_API void r_cons_set_cup(int enable) { R_API void r_cons_column(int c) { char *b = malloc (I.buffer_len+1); - if (!b) return; + if (!b) { + return; + } memcpy (b, I.buffer, I.buffer_len); b[I.buffer_len] = 0; r_cons_reset (); @@ -1011,7 +1045,7 @@ R_API void r_cons_highlight (const char *word) { R_API char *r_cons_lastline () { char *b = I.buffer+I.buffer_len; while (b >I.buffer) { - if (*b=='\n') { + if (*b == '\n') { b++; break; } @@ -1048,16 +1082,19 @@ R_API bool r_cons_drop (int n) { } R_API void r_cons_chop () { - while (I.buffer_len>0) { + while (I.buffer_len > 0) { char ch = I.buffer[I.buffer_len-1]; - if (ch != '\n' && !IS_WHITESPACE (ch)) + if (ch != '\n' && !IS_WHITESPACE (ch)) { break; + } I.buffer_len--; } } R_API void r_cons_bind(RConsBind *bind) { - if (!bind) return; + if (!bind) { + return; + } bind->get_size = r_cons_get_size; bind->get_cursor = r_cons_get_cursor; } diff --git a/libr/include/r_cons.h b/libr/include/r_cons.h index dc7f33ab7e..a518b1a96d 100644 --- a/libr/include/r_cons.h +++ b/libr/include/r_cons.h @@ -165,6 +165,7 @@ r_cons_click_clear(); typedef struct r_cons_t { RConsGrep grep; + RStack *cons_stack; char *buffer; //int line; int buffer_len; diff --git a/libr/include/r_util/r_stack.h b/libr/include/r_util/r_stack.h index d1fc240719..c41a0d726a 100644 --- a/libr/include/r_util/r_stack.h +++ b/libr/include/r_util/r_stack.h @@ -1,14 +1,18 @@ #ifndef R_STACK_H #define R_STACK_H +typedef void (*RStackFree)(void *ptr); + typedef struct r_stack_t { void **elems; unsigned int n_elems; int top; + RStackFree free; } RStack; -R_API RStack *r_stack_new(unsigned int n); +R_API RStack *r_stack_new(ut32 n); R_API void r_stack_free(RStack *s); +R_API RStack *r_stack_newf(ut32 n, RStackFree f); R_API int r_stack_push(RStack *s, void *el); R_API void *r_stack_pop(RStack *s); R_API int r_stack_is_empty(RStack *s); diff --git a/libr/util/stack.c b/libr/util/stack.c index 627f48e168..35e6763921 100644 --- a/libr/util/stack.c +++ b/libr/util/stack.c @@ -2,23 +2,40 @@ #include -R_API RStack *r_stack_new(unsigned int n) { +R_API RStack *r_stack_new(ut32 n) { RStack *s = R_NEW0 (RStack); - if (!s) return NULL; + if (!s) { + return NULL; + } s->elems = R_NEWS0 (void *, n); if (!s->elems) { free (s); return NULL; } - s->n_elems = n; s->top = -1; return s; } +R_API RStack *r_stack_newf(ut32 n, RStackFree f) { + RStack *s = r_stack_new (n); + if (s) { + s->free = f; + } + return s; +} + R_API void r_stack_free(RStack *s) { - free (s->elems); - free (s); + if (s) { + if (s->free && s->top > 0) { + int i = 0; + for (i = 0; i < s->top; i++) { + s->free (s->elems[i]); + } + } + free (s->elems); + free (s); + } } R_API int r_stack_push(RStack *s, void *el) { @@ -35,11 +52,12 @@ R_API int r_stack_push(RStack *s, void *el) { return true; } +//the caller should be take care of the object returned R_API void *r_stack_pop(RStack *s) { void *res; - if (s->top == -1) + if (s->top == -1) { return NULL; - + } res = s->elems[s->top]; s->top--; return res;