Rizin
unix-like reverse engineering framework and cli tools
spaces.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2019 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2019 ret2libc <sirmy15@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include "rz_util/rz_spaces.h"
6 
9  if (!sp || !rz_spaces_init(sp, name)) {
10  free(sp);
11  return NULL;
12  }
13  return sp;
14 }
15 
16 RZ_API bool rz_spaces_init(RzSpaces *sp, const char *name) {
17  rz_return_val_if_fail(sp && name, false);
18  sp->name = strdup(name);
19  if (!sp->name) {
20  goto fail;
21  }
22 
23  sp->spaces = NULL;
24  sp->current = NULL;
25  sp->spacestack = rz_list_new();
26  if (!sp->spacestack) {
27  goto fail;
28  }
29 
30  sp->event = rz_event_new(sp);
31  if (!sp->event) {
32  goto fail;
33  }
34 
35  return true;
36 
37 fail:
39  return false;
40 }
41 
44  free(sp);
45 }
46 
47 static inline void space_free(RzSpace *s) {
48  if (s) {
49  free(s->name);
50  free(s);
51  }
52 }
53 
54 static void space_node_free(RBNode *n, void *user) {
55  RzSpace *s = container_of(n, RzSpace, rb);
56  space_free(s);
57 }
58 
60  rz_list_free(sp->spacestack);
61  sp->spacestack = NULL;
63  sp->spaces = NULL;
64  rz_event_free(sp->event);
65  sp->event = NULL;
66  sp->current = NULL;
67  RZ_FREE(sp->name);
68 }
69 
71  sp->current = NULL;
72  rz_list_purge(sp->spacestack);
74  sp->spaces = NULL;
75 }
76 
77 static int name_space_cmp(const void *incoming, const RBNode *rb, void *user) {
78  const RzSpace *s = container_of(rb, const RzSpace, rb);
79  return strcmp(incoming, s->name);
80 }
81 
83  if (!name) {
84  return NULL;
85  }
86  RBNode *n = rz_rbtree_find(sp->spaces, (void *)name, name_space_cmp, NULL);
87  return n ? container_of(n, RzSpace, rb) : NULL;
88 }
89 
90 static int space_cmp(const void *incoming, const RBNode *rb, void *user) {
91  const RzSpace *a = (const RzSpace *)incoming;
92  const RzSpace *b = container_of(rb, const RzSpace, rb);
93  return strcmp(a->name, b->name);
94 }
95 
98  if (!name || !*name || *name == '*') {
99  return NULL;
100  }
101 
103  if (s) {
104  return s;
105  }
106 
107  s = RZ_NEW0(RzSpace);
108  if (!s) {
109  return NULL;
110  }
111 
112  s->name = strdup(name);
113  if (!s->name) {
114  free(s);
115  return NULL;
116  }
117 
118  rz_rbtree_insert(&sp->spaces, s, &s->rb, space_cmp, NULL);
119  return s;
120 }
121 
123  sp->current = rz_spaces_add(sp, name);
124  return sp->current;
125 }
126 
127 static inline bool spaces_unset_single(RzSpaces *sp, const char *name) {
128  RzSpace *space = rz_spaces_get(sp, name);
129  if (!space) {
130  return false;
131  }
132 
133  RzSpaceEvent ev = { .data.unset.space = space };
134  rz_event_send(sp->event, RZ_SPACE_EVENT_UNSET, &ev);
135  if (sp->current == space) {
136  sp->current = NULL;
137  }
138  return rz_rbtree_delete(&sp->spaces, (void *)name, name_space_cmp, NULL, space_node_free, NULL);
139 }
140 
141 RZ_API bool rz_spaces_unset(RzSpaces *sp, const char *name) {
142  if (name) {
143  return spaces_unset_single(sp, name);
144  }
145 
147  if (!names) {
148  return false;
149  }
150 
151  RBIter it;
152  RzSpace *s;
153  rz_spaces_foreach(sp, it, s) {
154  rz_list_append(names, strdup(s->name));
155  }
156 
157  RzListIter *lit;
158  const char *n;
159  bool res = false;
160  rz_list_foreach (names, lit, n) {
161  res |= spaces_unset_single(sp, n);
162  }
164  return res;
165 }
166 
167 RZ_API int rz_spaces_count(RzSpaces *sp, const char *name) {
169  if (!s) {
170  return 0;
171  }
172  RzSpaceEvent ev = { .data.count.space = s, .res = 0 };
173  rz_event_send(sp->event, RZ_SPACE_EVENT_COUNT, &ev);
174  return ev.res;
175 }
176 
177 RZ_API bool rz_spaces_push(RzSpaces *sp, const char *name) {
178  rz_return_val_if_fail(sp, false);
179 
180  rz_list_push(sp->spacestack, sp->current ? sp->current->name : "*");
182  return true;
183 }
184 
186  char *name = rz_list_pop(sp->spacestack);
187  if (!name) {
188  return false;
189  }
190 
192  rz_spaces_set(sp, s ? s->name : NULL);
193  return true;
194 }
195 
196 RZ_API bool rz_spaces_rename(RzSpaces *sp, const char *oname, const char *nname) {
197  if (!oname && !sp->current) {
198  return false;
199  }
200 
201  RzSpace *s;
202  if (oname) {
203  s = rz_spaces_get(sp, oname);
204  if (!s) {
205  return false;
206  }
207  } else {
208  s = sp->current;
209  }
210 
211  RzSpace *sn = rz_spaces_get(sp, nname);
212  if (sn) {
213  return false;
214  }
215 
216  RzSpaceEvent ev = {
217  .data.rename.oldname = s->name,
218  .data.rename.newname = nname,
219  .data.rename.space = s
220  };
221  rz_event_send(sp->event, RZ_SPACE_EVENT_RENAME, &ev);
222 
223  rz_rbtree_delete(&sp->spaces, (void *)s->name, name_space_cmp, NULL, NULL, NULL);
224  free(s->name);
225  s->name = strdup(nname);
226  rz_rbtree_insert(&sp->spaces, s, &s->rb, space_cmp, NULL);
227 
228  return true;
229 }
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
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_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
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 RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
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
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
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 n
Definition: mipsasm.c:19
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_event_send(RzEvent *ev, int type, void *data)
Definition: event.c:115
RZ_API void rz_event_free(RzEvent *ev)
Definition: event.c:37
RZ_API RzEvent * rz_event_new(void *user)
Definition: event.c:17
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API RBNode * rz_rbtree_find(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:267
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *root, RBNodeFree freefn, void *user)
Definition: rbtree.c:281
RZ_API bool rz_rbtree_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *user)
Returns true if the node was inserted successfully.
Definition: rbtree.c:291
RZ_API bool rz_rbtree_delete(RBNode **root, void *data, RBComparator cmp, void *cmp_user, RBNodeFree freefn, void *free_user)
Returns true if a node with an equal key is deleted.
Definition: rbtree.c:263
#define rz_spaces_foreach(sp, it, s)
Definition: rz_spaces.h:105
@ RZ_SPACE_EVENT_COUNT
Definition: rz_spaces.h:34
@ RZ_SPACE_EVENT_RENAME
Definition: rz_spaces.h:35
@ RZ_SPACE_EVENT_UNSET
Definition: rz_spaces.h:36
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
#define container_of(ptr, type, member)
Definition: rz_types.h:650
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
RZ_API RzSpace * rz_spaces_get(RzSpaces *sp, const char *name)
Definition: spaces.c:82
RZ_API void rz_spaces_free(RzSpaces *sp)
Definition: spaces.c:42
RZ_API bool rz_spaces_push(RzSpaces *sp, const char *name)
Definition: spaces.c:177
RZ_API void rz_spaces_fini(RzSpaces *sp)
Definition: spaces.c:59
RZ_API RzSpaces * rz_spaces_new(const char *name)
Definition: spaces.c:7
RZ_API RzSpace * rz_spaces_set(RzSpaces *sp, const char *name)
Definition: spaces.c:122
static void space_free(RzSpace *s)
Definition: spaces.c:47
RZ_API RzSpace * rz_spaces_add(RzSpaces *sp, const char *name)
Definition: spaces.c:96
RZ_API int rz_spaces_count(RzSpaces *sp, const char *name)
Definition: spaces.c:167
static int name_space_cmp(const void *incoming, const RBNode *rb, void *user)
Definition: spaces.c:77
RZ_API bool rz_spaces_pop(RzSpaces *sp)
Definition: spaces.c:185
RZ_API void rz_spaces_purge(RzSpaces *sp)
Definition: spaces.c:70
static bool spaces_unset_single(RzSpaces *sp, const char *name)
Definition: spaces.c:127
static void space_node_free(RBNode *n, void *user)
Definition: spaces.c:54
static int space_cmp(const void *incoming, const RBNode *rb, void *user)
Definition: spaces.c:90
RZ_API bool rz_spaces_init(RzSpaces *sp, const char *name)
Definition: spaces.c:16
RZ_API bool rz_spaces_rename(RzSpaces *sp, const char *oname, const char *nname)
Definition: spaces.c:196
RZ_API bool rz_spaces_unset(RzSpaces *sp, const char *name)
Definition: spaces.c:141
Definition: z80asm.h:102
Definition: names.h:123
struct rz_space_event_t::@311::@314 rename
struct rz_space_event_t::@311::@313 unset
struct rz_space_event_t::@311::@312 count
union rz_space_event_t::@311 data
#define fail(test)
Definition: tests.h:29
static int sp
Definition: z80asm.c:91