mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 15:41:38 +00:00
Add user * to REvent Hooking and add all_callbacks for R_EVENT_ALL ##core
This commit is contained in:
parent
c1d0e59d4d
commit
98308a2617
@ -26,35 +26,35 @@ R_API void r_anal_unset_limits(RAnal *anal) {
|
||||
}
|
||||
|
||||
static void meta_unset_for(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *s = (RSpaces *)user;
|
||||
RSpaces *s = (RSpaces *)ev->user;
|
||||
RAnal *anal = container_of (s, RAnal, meta_spaces);
|
||||
RSpaceEvent *se = (RSpaceEvent *)data;
|
||||
r_meta_space_unset_for (anal, se->data.unset.space);
|
||||
}
|
||||
|
||||
static void meta_count_for(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *s = (RSpaces *)user;
|
||||
RSpaces *s = (RSpaces *)ev->user;
|
||||
RAnal *anal = container_of (s, RAnal, meta_spaces);
|
||||
RSpaceEvent *se = (RSpaceEvent *)data;
|
||||
se->res = r_meta_space_count_for (anal, se->data.count.space);
|
||||
}
|
||||
|
||||
static void zign_unset_for(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *s = (RSpaces *)user;
|
||||
RSpaces *s = (RSpaces *)ev->user;
|
||||
RAnal *anal = container_of (s, RAnal, zign_spaces);
|
||||
RSpaceEvent *se = (RSpaceEvent *)data;
|
||||
r_sign_space_unset_for (anal, se->data.unset.space);
|
||||
}
|
||||
|
||||
static void zign_count_for(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *s = (RSpaces *)user;
|
||||
RSpaces *s = (RSpaces *)ev->user;
|
||||
RAnal *anal = container_of (s, RAnal, zign_spaces);
|
||||
RSpaceEvent *se = (RSpaceEvent *)data;
|
||||
se->res = r_sign_space_count_for (anal, se->data.count.space);
|
||||
}
|
||||
|
||||
static void zign_rename_for(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *s = (RSpaces *)user;
|
||||
RSpaces *s = (RSpaces *)ev->user;
|
||||
RAnal *anal = container_of (s, RAnal, zign_spaces);
|
||||
RSpaceEvent *se = (RSpaceEvent *)data;
|
||||
r_sign_space_rename_for (anal, se->data.rename.space,
|
||||
@ -167,13 +167,13 @@ R_API RAnal *r_anal_new() {
|
||||
anal->opt.depth = 32;
|
||||
anal->opt.noncode = false; // do not analyze data by default
|
||||
r_spaces_init (&anal->meta_spaces, "CS");
|
||||
r_event_hook (anal->meta_spaces.event, R_SPACE_EVENT_UNSET, meta_unset_for);
|
||||
r_event_hook (anal->meta_spaces.event, R_SPACE_EVENT_COUNT, meta_count_for);
|
||||
r_event_hook (anal->meta_spaces.event, R_SPACE_EVENT_UNSET, meta_unset_for, NULL);
|
||||
r_event_hook (anal->meta_spaces.event, R_SPACE_EVENT_COUNT, meta_count_for, NULL);
|
||||
|
||||
r_spaces_init (&anal->zign_spaces, "zs");
|
||||
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_UNSET, zign_unset_for);
|
||||
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_COUNT, zign_count_for);
|
||||
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_RENAME, zign_rename_for);
|
||||
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_UNSET, zign_unset_for, NULL);
|
||||
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_COUNT, zign_count_for, NULL);
|
||||
r_event_hook (anal->zign_spaces.event, R_SPACE_EVENT_RENAME, zign_rename_for, NULL);
|
||||
anal->sdb_fcns = sdb_ns (anal->sdb, "fcns", 1);
|
||||
anal->sdb_meta = sdb_ns (anal->sdb, "meta", 1);
|
||||
anal->sdb_hints = sdb_ns (anal->sdb, "hints", 1);
|
||||
|
@ -2296,7 +2296,7 @@ R_API bool r_core_init(RCore *core) {
|
||||
}
|
||||
r_core_setenv (core);
|
||||
core->ev = r_event_new (core);
|
||||
r_event_hook (core->ev, R_EVENT_ALL, cb_event_handler);
|
||||
r_event_hook (core->ev, R_EVENT_ALL, cb_event_handler, NULL);
|
||||
core->lock = r_th_lock_new (true);
|
||||
core->max_cmd_depth = R_CORE_CMD_DEPTH + 1;
|
||||
core->cmd_depth = core->max_cmd_depth;
|
||||
|
@ -202,14 +202,14 @@ static bool unset_flags_space(RFlagItem *fi, void *user) {
|
||||
}
|
||||
|
||||
static void count_flags_in_space(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *sp = (RSpaces *)user;
|
||||
RSpaces *sp = (RSpaces *)ev->user;
|
||||
RFlag *f = container_of (sp, RFlag, spaces);
|
||||
RSpaceEvent *spe = (RSpaceEvent *)data;
|
||||
r_flag_foreach_space (f, spe->data.count.space, count_flags, &spe->res);
|
||||
}
|
||||
|
||||
static void unset_flagspace(REvent *ev, int type, void *user, void *data) {
|
||||
RSpaces *sp = (RSpaces *)user;
|
||||
RSpaces *sp = (RSpaces *)ev->user;
|
||||
RFlag *f = container_of (sp, RFlag, spaces);
|
||||
const RSpaceEvent *spe = (const RSpaceEvent *)data;
|
||||
r_flag_foreach_space (f, spe->data.unset.space, unset_flags_space, NULL);
|
||||
@ -217,8 +217,8 @@ static void unset_flagspace(REvent *ev, int type, void *user, void *data) {
|
||||
|
||||
static void new_spaces(RFlag *f) {
|
||||
r_spaces_init (&f->spaces, "fs");
|
||||
r_event_hook (f->spaces.event, R_SPACE_EVENT_COUNT, count_flags_in_space);
|
||||
r_event_hook (f->spaces.event, R_SPACE_EVENT_UNSET, unset_flagspace);
|
||||
r_event_hook (f->spaces.event, R_SPACE_EVENT_COUNT, count_flags_in_space, NULL);
|
||||
r_event_hook (f->spaces.event, R_SPACE_EVENT_UNSET, unset_flagspace, NULL);
|
||||
}
|
||||
|
||||
R_API RFlag *r_flag_new() {
|
||||
|
@ -8,13 +8,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sdb/ht_up.h>
|
||||
#include <r_vector.h>
|
||||
|
||||
typedef struct r_event_t {
|
||||
void *user;
|
||||
bool incall;
|
||||
HtUP *callbacks;
|
||||
RVector *all_callbacks;
|
||||
int next_handle;
|
||||
} REvent;
|
||||
|
||||
typedef struct r_event_callback_handle_t {
|
||||
int handle;
|
||||
int type;
|
||||
} REventCallbackHandle;
|
||||
|
||||
typedef void (*REventCallback)(REvent *ev, int type, void *user, void *data);
|
||||
|
||||
typedef enum {
|
||||
R_EVENT_ALL = 0,
|
||||
R_EVENT_META_SET,
|
||||
@ -29,12 +39,11 @@ typedef struct r_event_meta_t {
|
||||
const char *string;
|
||||
} REventMeta;
|
||||
|
||||
typedef void (*REventCallback)(REvent *ev, int type, void *user, void *data);
|
||||
|
||||
R_API REvent *r_event_new(void *user);
|
||||
R_API void r_event_free(REvent *ev);
|
||||
R_API void r_event_hook(REvent *ev, int type, REventCallback cb);
|
||||
R_API void r_event_unhook(REvent *ev, int type, REventCallback cb);
|
||||
R_API REventCallbackHandle r_event_hook(REvent *ev, int type, REventCallback cb, void *user);
|
||||
R_API void r_event_unhook(REvent *ev, REventCallbackHandle handle);
|
||||
R_API void r_event_send(REvent *ev, int type, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -125,6 +125,10 @@ R_API void *r_vector_shrink(RVector *vec);
|
||||
if ((vec) && (vec)->a) \
|
||||
for (it = (void *)(vec)->a; (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); it = (void *)((char *)it + (vec)->elem_size))
|
||||
|
||||
#define r_vector_enumerate(vec, it, i) \
|
||||
if ((vec) && (vec)->a) \
|
||||
for (it = (void *)(vec)->a, i = 0; i < (vec)->len; it = (void *)((char *)it + (vec)->elem_size), i++)
|
||||
|
||||
|
||||
// RPVector
|
||||
|
||||
|
@ -3,81 +3,129 @@
|
||||
#include <r_util.h>
|
||||
#include <r_vector.h>
|
||||
|
||||
typedef struct r_event_callback_hook_t {
|
||||
REventCallback cb;
|
||||
void *user;
|
||||
int handle;
|
||||
} REventCallbackHook;
|
||||
|
||||
static RVector *new_cbhook_vector(void) {
|
||||
return r_vector_new (sizeof (REventCallbackHook), NULL, NULL);
|
||||
}
|
||||
|
||||
static void ht_callback_free(HtUPKv *kv) {
|
||||
r_vector_free ((RVector *)kv->value);
|
||||
}
|
||||
|
||||
R_API REvent *r_event_new(void *user) {
|
||||
REvent *ev = R_NEW0 (REvent);
|
||||
if (!ev) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ev->callbacks = ht_up_new0 ();
|
||||
|
||||
// skip R_EVENT_ALL and R_EVENT_MAX, so that they don't have a mapping
|
||||
// and if used in hook/unhook/send APIs will raise a warning
|
||||
ut64 i;
|
||||
for (i = 1; i < R_EVENT_MAX; ++i) {
|
||||
ht_up_insert (ev->callbacks, (ut64)i, r_pvector_new (NULL));
|
||||
}
|
||||
ev->user = user;
|
||||
ev->next_handle = 0;
|
||||
ev->callbacks = ht_up_new (NULL, ht_callback_free, NULL);
|
||||
if (!ev->callbacks) {
|
||||
goto err;
|
||||
}
|
||||
ev->all_callbacks = new_cbhook_vector ();
|
||||
if (!ev->all_callbacks) {
|
||||
goto err;
|
||||
}
|
||||
return ev;
|
||||
err:
|
||||
r_event_free (ev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API void r_event_free(REvent *ev) {
|
||||
if (!ev) {
|
||||
return;
|
||||
}
|
||||
ut64 i;
|
||||
for (i = 1; i < R_EVENT_MAX; ++i) {
|
||||
RVector *entry = ht_up_find (ev->callbacks, i, NULL);
|
||||
r_vector_free (entry);
|
||||
}
|
||||
ht_up_free (ev->callbacks);
|
||||
r_vector_free (ev->all_callbacks);
|
||||
free (ev);
|
||||
}
|
||||
|
||||
static bool add_hook(void *cb, const ut64 k, const void *v) {
|
||||
RPVector *cbs = (RPVector *)v;
|
||||
r_return_val_if_fail (cbs, false);
|
||||
r_pvector_push (cbs, cb);
|
||||
return true;
|
||||
}
|
||||
|
||||
R_API void r_event_hook(REvent *ev, int type, REventCallback cb) {
|
||||
r_return_if_fail (ev);
|
||||
if (type == R_EVENT_ALL) {
|
||||
ht_up_foreach (ev->callbacks, add_hook, cb);
|
||||
} else {
|
||||
RPVector *cbs = ht_up_find (ev->callbacks, type, NULL);
|
||||
add_hook (cb, 0, cbs);
|
||||
static RVector *get_cbs(REvent *ev, int type) {
|
||||
RVector *cbs = ht_up_find (ev->callbacks, (ut64)type, NULL);
|
||||
if (!cbs) {
|
||||
cbs = new_cbhook_vector ();
|
||||
if (cbs) {
|
||||
ht_up_insert (ev->callbacks, (ut64)type, cbs);
|
||||
}
|
||||
}
|
||||
return cbs;
|
||||
}
|
||||
|
||||
static bool del_hook(void *cb, const ut64 k, const void *v) {
|
||||
RPVector *cbs = (RPVector *)v;
|
||||
R_API REventCallbackHandle r_event_hook(REvent *ev, int type, REventCallback cb, void *user) {
|
||||
REventCallbackHandle handle = { 0 };
|
||||
REventCallbackHook hook;
|
||||
|
||||
r_return_val_if_fail (ev, handle);
|
||||
hook.cb = cb;
|
||||
hook.user = user;
|
||||
hook.handle = ev->next_handle++;
|
||||
if (type == R_EVENT_ALL) {
|
||||
r_vector_push (ev->all_callbacks, &hook);
|
||||
} else {
|
||||
RVector *cbs = get_cbs (ev, type);
|
||||
if (!cbs) {
|
||||
return handle;
|
||||
}
|
||||
r_vector_push (cbs, &hook);
|
||||
}
|
||||
handle.handle = hook.handle;
|
||||
handle.type = type;
|
||||
return handle;
|
||||
}
|
||||
|
||||
static bool del_hook(void *user, const ut64 k, const void *v) {
|
||||
int handle = *(int *)user;
|
||||
RVector *cbs = (RVector *)v;
|
||||
REventCallbackHook *hook;
|
||||
size_t i;
|
||||
r_return_val_if_fail (cbs, false);
|
||||
r_pvector_remove_data (cbs, cb);
|
||||
r_vector_enumerate (cbs, hook, i) {
|
||||
if (hook->handle == handle) {
|
||||
r_vector_remove_at (cbs, i, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
R_API void r_event_unhook(REvent *ev, int type, REventCallback cb) {
|
||||
R_API void r_event_unhook(REvent *ev, REventCallbackHandle handle) {
|
||||
r_return_if_fail (ev);
|
||||
if (type == R_EVENT_ALL) {
|
||||
ht_up_foreach (ev->callbacks, del_hook, cb);
|
||||
if (handle.type == R_EVENT_ALL) {
|
||||
// try to delete it both from each list of callbacks and from
|
||||
// the "all_callbacks" vector
|
||||
ht_up_foreach (ev->callbacks, del_hook, &handle.handle);
|
||||
del_hook (&handle.handle, 0, ev->all_callbacks);
|
||||
} else {
|
||||
RPVector *cbs = ht_up_find (ev->callbacks, type, NULL);
|
||||
del_hook (cb, 0, cbs);
|
||||
RVector *cbs = ht_up_find (ev->callbacks, (ut64)handle.type, NULL);
|
||||
r_return_if_fail (cbs);
|
||||
del_hook (&handle.handle, 0, cbs);
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_event_send(REvent *ev, int type, void *data) {
|
||||
REventCallbackHook *hook;
|
||||
r_return_if_fail (ev && !ev->incall);
|
||||
|
||||
void **it;
|
||||
RPVector *cbs = ht_up_find (ev->callbacks, type, NULL);
|
||||
// send to both the per-type callbacks and to the all_callbacks
|
||||
ev->incall = true;
|
||||
r_vector_foreach (ev->all_callbacks, hook) {
|
||||
hook->cb (ev, type, hook->user, data);
|
||||
}
|
||||
ev->incall = false;
|
||||
|
||||
RVector *cbs = ht_up_find (ev->callbacks, (ut64)type, NULL);
|
||||
r_return_if_fail (cbs);
|
||||
ev->incall = true;
|
||||
r_pvector_foreach (cbs, it) {
|
||||
REventCallback cb = *it;
|
||||
cb (ev, type, ev->user, data);
|
||||
r_vector_foreach (cbs, hook) {
|
||||
hook->cb (ev, type, hook->user, data);
|
||||
}
|
||||
ev->incall = false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user