Rizin
unix-like reverse engineering framework and cli tools
hud.c File Reference
#include <rz_cons.h>
#include <ctype.h>

Go to the source code of this file.

Macros

#define I(x)   rz_cons_singleton()->x
 
#define HUD_CACHE   0
 

Functions

RZ_API char * rz_cons_hud_file (const char *f)
 
RZ_API char * rz_cons_hud_string (const char *s)
 
static bool __matchString (char *entry, char *filter, char *mask, const int mask_size)
 
static RzListhud_filter (RzList *list, char *user_input, int top_entry_n, int *current_entry_n, char **selected_entry)
 
static void mht_free_kv (HtPPKv *kv)
 
RZ_API char * rz_cons_hud (RzList *list, const char *prompt)
 
RZ_API char * rz_cons_hud_path (const char *path, int dir)
 
RZ_API void rz_cons_message (RZ_NONNULL const char *msg)
 

Macro Definition Documentation

◆ HUD_CACHE

#define HUD_CACHE   0

Definition at line 201 of file hud.c.

◆ I

#define I (   x)    rz_cons_singleton()->x

Definition at line 7 of file hud.c.

Function Documentation

◆ __matchString()

static bool __matchString ( char *  entry,
char *  filter,
char *  mask,
const int  mask_size 
)
static

Definition at line 64 of file hud.c.

64  {
65  char *p, *current_token = filter;
66  const char *filter_end = filter + strlen(filter);
67  char *ansi_filtered = strdup(entry);
68  int *cps;
69  rz_str_ansi_filter(ansi_filtered, NULL, &cps, -1);
70  entry = ansi_filtered;
71  // first we separate the filter in words (include the terminator char
72  // to avoid special handling of the last token)
73  for (p = filter; p <= filter_end; p++) {
74  if (*p == ' ' || *p == '\0') {
75  const char *next_match, *entry_ptr = entry;
76  char old_char = *p;
77  int token_len;
78 
79  // Ignoring consecutive spaces
80  if (p == current_token) {
81  current_token++;
82  continue;
83  }
84  *p = 0;
85  token_len = strlen(current_token);
86  // look for all matches of the current_token in this entry
87  while ((next_match = rz_str_casestr(entry_ptr, current_token))) {
88  int real_pos, filtered_pos = next_match - entry;
89  int end_pos = cps[filtered_pos + token_len];
90  for (real_pos = cps[filtered_pos];
91  real_pos < end_pos && real_pos < mask_size;
92  real_pos = cps[++filtered_pos]) {
93  mask[real_pos] = 'x';
94  }
95  entry_ptr += token_len;
96  }
97  *p = old_char;
98  if (entry_ptr == entry) {
99  // the word is not present in the target
100  free(cps);
101  free(ansi_filtered);
102  return false;
103  }
104  current_token = p + 1;
105  }
106  }
107  free(cps);
108  free(ansi_filtered);
109  return true;
110 }
#define mask()
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * p
Definition: libc.cpp:67
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")
static bool filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian)
Definition: filter.c:185
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_casestr(const char *a, const char *b)
Definition: str.c:2757
Definition: zipcmp.c:77

References filter(), free(), mask, NULL, p, rz_str_ansi_filter(), rz_str_casestr(), and strdup().

Referenced by hud_filter().

◆ hud_filter()

static RzList* hud_filter ( RzList list,
char *  user_input,
int  top_entry_n,
int current_entry_n,
char **  selected_entry 
)
static

Definition at line 112 of file hud.c.

112  {
113  RzListIter *iter;
114  char *current_entry;
115  char mask[HUD_BUF_SIZE];
116  char *p, *x;
117  int j, rows;
118  (void)rz_cons_get_size(&rows);
119  int counter = 0;
120  bool first_line = true;
121  RzList *res = rz_list_newf(free);
122  rz_list_foreach (list, iter, current_entry) {
123  memset(mask, 0, HUD_BUF_SIZE);
124  if (*user_input && !__matchString(current_entry, user_input, mask, HUD_BUF_SIZE)) {
125  continue;
126  }
127  if (++counter == rows + top_entry_n) {
128  break;
129  }
130  // if the user scrolled down the list, do not print the first entries
131  if (!top_entry_n || *current_entry_n >= top_entry_n) {
132  // remove everything after a tab (in ??, it contains the commands)
133  x = strchr(current_entry, '\t');
134  if (x) {
135  *x = 0;
136  }
137  p = strdup(current_entry);
138  // if the filter is empty, print the entry and move on
139  if (!user_input[0]) {
140  rz_list_append(res, rz_str_newf(" %c %s", first_line ? '-' : ' ', p));
141  } else {
142  // otherwise we need to emphasize the matching part
143  if (I(context->color_mode)) {
144  int last_color_change = 0;
145  int last_mask = 0;
146  char *str = rz_str_newf(" %c ", first_line ? '-' : ' ');
147  // Instead of printing one char at the time
148  // (which would be slow), we group substrings of the same color
149  for (j = 0; p[j] && j < HUD_BUF_SIZE; j++) {
150  if (mask[j] != last_mask) {
151  char tmp = p[j];
152  p[j] = 0;
153  if (mask[j]) {
154  str = rz_str_appendf(str, Color_RESET "%s", p + last_color_change);
155  } else {
156  str = rz_str_appendf(str, Color_GREEN "%s", p + last_color_change);
157  }
158  p[j] = tmp;
159  last_color_change = j;
160  last_mask = mask[j];
161  }
162  }
163  if (last_mask) {
164  str = rz_str_appendf(str, Color_GREEN "%s" Color_RESET, p + last_color_change);
165  } else {
166  str = rz_str_appendf(str, Color_RESET "%s", p + last_color_change);
167  }
168  rz_list_append(res, str);
169  } else {
170  // Otherwise we print the matching characters uppercase
171  for (j = 0; p[j]; j++) {
172  if (mask[j]) {
173  p[j] = toupper((unsigned char)p[j]);
174  }
175  }
176  rz_list_append(res, rz_str_newf(" %c %s", first_line ? '-' : ' ', p));
177  }
178  }
179  // Clean up and restore the tab character (if any)
180  free(p);
181  if (x) {
182  *x = '\t';
183  }
184  if (first_line) {
185  *selected_entry = current_entry;
186  }
187  first_line = false;
188  }
189  (*current_entry_n)++;
190  }
191  return res;
192 }
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
static bool __matchString(char *entry, char *filter, char *mask, const int mask_size)
Definition: hud.c:64
#define I(x)
Definition: hud.c:7
return memset(p, 0, total)
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
int x
Definition: mipsasm.c:20
#define Color_RESET
Definition: rz_cons.h:617
#define Color_GREEN
Definition: rz_cons.h:627
#define HUD_BUF_SIZE
Definition: rz_cons.h:499
RZ_API char * rz_str_appendf(char *ptr, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define toupper(c)
Definition: safe-ctype.h:147
int64_t counter
Definition: main.c:4

References __matchString(), Color_GREEN, Color_RESET, counter, free(), HUD_BUF_SIZE, I, list(), mask, memset(), p, rz_cons_get_size(), rz_list_append(), rz_list_newf(), rz_str_appendf(), rz_str_newf(), cmd_descs_generate::str, strdup(), autogen_x86imm::tmp, toupper, and x.

Referenced by rz_cons_hud().

◆ mht_free_kv()

static void mht_free_kv ( HtPPKv *  kv)
static

Definition at line 194 of file hud.c.

194  {
195  free(kv->key);
196  rz_list_free(kv->value);
197 }
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137

References free(), and rz_list_free().

Referenced by rz_cons_hud().

◆ rz_cons_hud()

RZ_API char* rz_cons_hud ( RzList list,
const char *  prompt 
)

Definition at line 202 of file hud.c.

202  {
203  char user_input[HUD_BUF_SIZE + 1];
204  char *selected_entry = NULL;
205  RzListIter *iter;
206 
207  HtPP *ht = ht_pp_new(NULL, (HtPPKvFreeFunc)mht_free_kv, (HtPPCalcSizeV)strlen);
208  RzLineHud *hud = (RzLineHud *)RZ_NEW(RzLineHud);
209  hud->activate = 0;
210  hud->vi = 0;
211  I(line)->echo = false;
212  I(line)->hud = hud;
213  user_input[0] = 0;
214  user_input[HUD_BUF_SIZE] = 0;
215  hud->top_entry_n = 0;
216  rz_cons_show_cursor(false);
217  rz_cons_enable_mouse(false);
218  rz_cons_clear();
219 
220  // Repeat until the user exits the hud
221  for (;;) {
222  rz_cons_gotoxy(0, 0);
223  hud->current_entry_n = 0;
224 
225  if (hud->top_entry_n < 0) {
226  hud->top_entry_n = 0;
227  }
228  selected_entry = NULL;
229  if (prompt && *prompt) {
230  rz_cons_printf(">> %s\n", prompt);
231  }
232  rz_cons_printf("%d> %s|\n", hud->top_entry_n, user_input);
233  char *row;
234  RzList *filtered_list = NULL;
235 
236  bool found = false;
237  filtered_list = ht_pp_find(ht, user_input, &found);
238  if (!found) {
239  filtered_list = hud_filter(list, user_input,
240  hud->top_entry_n, &(hud->current_entry_n), &selected_entry);
241 #if HUD_CACHE
242  ht_pp_insert(ht, user_input, filtered_list);
243 #endif
244  }
245  rz_list_foreach (filtered_list, iter, row) {
246  rz_cons_printf("%s\n", row);
247  }
248  if (!filtered_list->length) { // hack to remove garbage value when list is empty
249  printf("%s", RZ_CONS_CLEAR_LINE);
250  }
251 #if !HUD_CACHE
252  rz_list_free(filtered_list);
253 #endif
255  (void)rz_line_readline();
256  rz_str_ncpy(user_input, I(line)->buffer.data, HUD_BUF_SIZE); // to search
257 
258  if (!hud->activate) {
259  hud->top_entry_n = 0;
260  if (hud->current_entry_n >= 1) {
261  if (selected_entry) {
262  RZ_FREE(I(line)->hud);
263  I(line)->echo = true;
264  rz_cons_enable_mouse(false);
265  rz_cons_show_cursor(true);
266  rz_cons_set_raw(false);
267  return strdup(selected_entry);
268  }
269  } else {
270  goto _beach;
271  }
272  }
273  }
274 _beach:
275  RZ_FREE(I(line)->hud);
276  I(line)->echo = true;
277  rz_cons_show_cursor(true);
278  rz_cons_enable_mouse(false);
279  rz_cons_set_raw(false);
280  ht_pp_free(ht);
281  return NULL;
282 }
RZ_API void rz_cons_set_raw(bool is_raw)
Definition: cons.c:1617
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_visual_flush(void)
Definition: cons.c:1067
RZ_API void rz_cons_show_cursor(int cursor)
Definition: cons.c:1581
RZ_API void rz_cons_gotoxy(int x, int y)
Definition: cons.c:724
RZ_API void rz_cons_clear(void)
Definition: cons.c:787
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
RZ_API const char * rz_line_readline(void)
Definition: dietline.c:913
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
static void mht_free_kv(HtPPKv *kv)
Definition: hud.c:194
static RzList * hud_filter(RzList *list, char *user_input, int top_entry_n, int *current_entry_n, char **selected_entry)
Definition: hud.c:112
line
Definition: setup.py:34
#define RZ_CONS_CLEAR_LINE
Definition: rz_cons.h:593
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
Definition: str.c:923
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_FREE(x)
Definition: rz_types.h:369
Definition: buffer.h:15
int current_entry_n
Definition: rz_cons.h:1028
int vi
Definition: rz_cons.h:1031
int top_entry_n
Definition: rz_cons.h:1029
char activate
Definition: rz_cons.h:1030
ut32 length
Definition: rz_list.h:22
static char * prompt(const char *str, const char *txt)
Definition: vmenus.c:30

References rz_hud_t::activate, rz_hud_t::current_entry_n, found, HUD_BUF_SIZE, hud_filter(), I, rz_list_t::length, setup::line, list(), mht_free_kv(), NULL, printf(), prompt(), rz_cons_clear(), RZ_CONS_CLEAR_LINE, rz_cons_enable_mouse(), rz_cons_gotoxy(), rz_cons_printf(), rz_cons_set_raw(), rz_cons_show_cursor(), rz_cons_visual_flush(), RZ_FREE, rz_line_readline(), rz_list_free(), RZ_NEW, rz_str_ncpy(), strdup(), rz_hud_t::top_entry_n, and rz_hud_t::vi.

Referenced by rz_cons_hud_path(), rz_cons_hud_string(), rz_core_visual_config_hud(), rz_core_visual_hudclasses(), and rz_core_visual_hudstuff().

◆ rz_cons_hud_file()

RZ_API char* rz_cons_hud_file ( const char *  f)

Definition at line 10 of file hud.c.

10  {
11  char *s = rz_file_slurp(f, NULL);
12  if (s) {
13  char *ret = rz_cons_hud_string(s);
14  free(s);
15  return ret;
16  }
17  return NULL;
18 }
RZ_API char * rz_cons_hud_string(const char *s)
Definition: hud.c:22
static RzSocket * s
Definition: rtr.c:28
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
#define f(i)
Definition: sha256.c:46

References f, free(), NULL, rz_cons_hud_string(), rz_file_slurp(), and s.

Referenced by rz_core_visual_hud(), and rz_core_yank_hud_file().

◆ rz_cons_hud_path()

RZ_API char* rz_cons_hud_path ( const char *  path,
int  dir 
)

Definition at line 285 of file hud.c.

285  {
286  char *tmp, *ret = NULL;
287  RzList *files;
288  if (path) {
290  tmp = strdup(*path ? path : "./");
291  } else {
292  tmp = strdup("./");
293  }
294  files = rz_sys_dir(tmp);
295  if (files) {
296  ret = rz_cons_hud(files, tmp);
297  if (ret) {
298  tmp = rz_str_append(tmp, "/");
299  tmp = rz_str_append(tmp, ret);
300  free(ret);
301  ret = rz_file_abspath(tmp);
302  free(tmp);
303  tmp = ret;
304  if (rz_file_is_directory(tmp)) {
305  ret = rz_cons_hud_path(tmp, dir);
306  free(tmp);
307  tmp = ret;
308  }
309  }
311  } else {
312  eprintf("No files found\n");
313  }
314  if (!ret) {
315  free(tmp);
316  return NULL;
317  }
318  return tmp;
319 }
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type special files
Definition: file_opts.h:46
RZ_API char * rz_cons_hud_path(const char *path, int dir)
Definition: hud.c:285
RZ_API char * rz_cons_hud(RzList *list, const char *prompt)
Definition: hud.c:202
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API bool rz_file_is_directory(const char *str)
Definition: file.c:167
RZ_API char * rz_file_abspath(const char *file)
Definition: file.c:267
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API RzList * rz_sys_dir(const char *path)
Definition: sys.c:216

References eprintf, files, free(), NULL, path, rz_cons_hud(), rz_file_abspath(), rz_file_is_directory(), rz_list_free(), rz_str_append(), rz_str_trim_head_ro(), rz_sys_dir(), strdup(), and autogen_x86imm::tmp.

Referenced by rz_core_yank_hud_path().

◆ rz_cons_hud_string()

RZ_API char* rz_cons_hud_string ( const char *  s)

Definition at line 22 of file hud.c.

22  {
23  if (!rz_cons_is_interactive()) {
24  eprintf("Hud mode requires scr.interactive=true.\n");
25  return NULL;
26  }
27  char *os, *track, *ret, *o = strdup(s);
28  if (!o) {
29  return NULL;
30  }
31  rz_str_replace_ch(o, '\r', 0, true);
32  rz_str_replace_ch(o, '\t', 0, true);
33  RzList *fl = rz_list_new();
34  int i;
35  if (!fl) {
36  free(o);
37  return NULL;
38  }
39  fl->free = free;
40  for (os = o, i = 0; o[i]; i++) {
41  if (o[i] == '\n') {
42  o[i] = 0;
43  if (*os && *os != '#') {
44  track = strdup(os);
45  if (!rz_list_append(fl, track)) {
46  free(track);
47  break;
48  }
49  }
50  os = o + i + 1;
51  }
52  }
53  ret = rz_cons_hud(fl, NULL);
54  free(o);
55  rz_list_free(fl);
56  return ret;
57 }
lzma_index ** i
Definition: index.h:629
RZ_API bool rz_cons_is_interactive(void)
Definition: cons.c:365
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API int rz_str_replace_ch(char *s, char a, char b, bool g)
Definition: str.c:139
RzListFree free
Definition: rz_list.h:21

References eprintf, rz_list_t::free, free(), i, NULL, rz_cons_hud(), rz_cons_is_interactive(), rz_list_append(), rz_list_free(), rz_list_new(), rz_str_replace_ch(), s, and strdup().

Referenced by rz_cons_grepbuf(), rz_cons_hud_file(), and rz_cons_less_str().

◆ rz_cons_message()

RZ_API void rz_cons_message ( RZ_NONNULL const char *  msg)

Definition at line 321 of file hud.c.

321  {
323  int len = strlen(msg);
324  int rows, cols = rz_cons_get_size(&rows);
325  rz_cons_clear();
326  rz_cons_gotoxy((cols - len) / 2, rows / 2);
328  rz_cons_flush();
329  rz_cons_gotoxy(0, rows - 2);
331 }
size_t len
Definition: 6502dis.c:15
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
RZ_API int rz_cons_any_key(const char *msg)
Definition: input.c:393
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119

References len, msg, NULL, rz_cons_any_key(), rz_cons_clear(), rz_cons_flush(), rz_cons_get_size(), rz_cons_gotoxy(), rz_cons_println(), and rz_return_if_fail.

Referenced by __check_func(), __fortune_cb(), __license_cb(), __version_cb(), agraph_refresh(), rz_cmd_help(), rz_core_visual_analysis_classes(), rz_core_visual_classes(), rz_core_visual_cmd(), and rz_core_visual_hud().