Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions libr/include/r_util/r_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#define R_LOG_H

#include <r_userconf.h>
#include <r_list.h>
#include <r_types.h>
#include <stdarg.h>
// NOTE: avoid including <r_vec.h> here because it includes r_assert.h, which
// includes this header, causing a circular dependency.

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -39,6 +42,8 @@ typedef enum r_log_level {

typedef bool (*RLogCallback)(void *user, int type, const char *origin, const char *msg);

typedef struct r_vec_RVecRLogCallbackUser_t RVecRLogCallbackUser;

typedef struct r_log_t {
int level; // skip messages lower than this level
int traplevel; // skip messages lower than this level
Expand All @@ -50,7 +55,7 @@ typedef struct r_log_t {
bool show_origin;
bool show_source;
bool show_ts;
RList *cbs;
RVecRLogCallbackUser *cbs;
PrintfCallback cb_printf;
} RLog;

Expand Down
39 changes: 20 additions & 19 deletions libr/util/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ typedef struct r_log_cbuser_t {
RLogCallback cb;
} RLogCallbackUser;

R_VEC_TYPE (RVecRLogCallbackUser, RLogCallbackUser);

static const char *level_tags[] = { // Log level to tag string lookup array
[R_LOG_LEVEL_FATAL] = "FATAL",
[R_LOG_LEVEL_ERROR] = "ERROR",
Expand Down Expand Up @@ -78,7 +80,7 @@ R_API void r_log_fini(void) {
if (rlog) {
RLog *log = rlog;
rlog = NULL;
r_list_free (log->cbs);
RVecRLogCallbackUser_free (log->cbs);
free (log->file);
free (log->filter);
free (log);
Expand Down Expand Up @@ -161,10 +163,9 @@ R_API bool r_log_match(int level, const char *origin) {
}
}
if (rlog->cbs) {
RListIter *iter;
RLogCallbackUser *cbu;
r_list_foreach (rlog->cbs, iter, cbu) {
if (cbu->cb (cbu->user, level, origin, NULL)) {
RLogCallbackUser *iter;
R_VEC_FOREACH (rlog->cbs, iter) {
if (iter->cb (iter->user, level, origin, NULL)) {
return true;
}
}
Expand All @@ -179,10 +180,9 @@ R_API void r_log_vmessage(RLogLevel level, const char *origin, const char *func,
}
vsnprintf (out, sizeof (out), fmt, ap);
if (rlog->cbs) {
RListIter *iter;
RLogCallbackUser *cbu;
r_list_foreach (rlog->cbs, iter, cbu) {
if (cbu->cb (cbu->user, level, origin, out)) {
RLogCallbackUser *iter;
R_VEC_FOREACH (rlog->cbs, iter) {
if (iter->cb (iter->user, level, origin, out)) {
return;
}
}
Expand Down Expand Up @@ -251,21 +251,22 @@ R_API void r_log_add_callback(RLogCallback cb, void *user) {
return;
}
if (!rlog->cbs) {
rlog->cbs = r_list_newf (free);
rlog->cbs = RVecRLogCallbackUser_new ();
}
RLogCallbackUser *cbu = R_NEW (RLogCallbackUser);
cbu->cb = cb;
cbu->user = user;
r_list_append (rlog->cbs, cbu);
RLogCallbackUser cbu = {
.cb = cb,
.user = user,
};
RVecRLogCallbackUser_push_back (rlog->cbs, &cbu);
}

R_API void r_log_del_callback(RLogCallback cb) {
if (r_log_init ()) {
RLogCallbackUser *p;
RListIter *iter;
r_list_foreach (rlog->cbs, iter, p) {
if (cb == p->cb) {
r_list_delete (rlog->cbs, iter);
size_t i;
for (i = 0; rlog->cbs && i < RVecRLogCallbackUser_length (rlog->cbs); i++) {
RLogCallbackUser *p = RVecRLogCallbackUser_at (rlog->cbs, i);
if (p && cb == p->cb) {
RVecRLogCallbackUser_remove (rlog->cbs, i);
return;
}
}
Expand Down
21 changes: 21 additions & 0 deletions test/unit/test_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ static Sdb *setup_sdb(void) {
return res;
}

typedef struct {
int calls;
} LogCbCtx;

static bool log_cb_counter(void *user, int type, const char *origin, const char *msg) {
(void)type;
(void)origin;
if (msg) {
LogCbCtx *ctx = (LogCbCtx *)user;
ctx->calls++;
}
return false;
}

bool test_dll_names(void) {
Sdb *TDB = setup_sdb ();
char *s;
Expand Down Expand Up @@ -237,6 +251,13 @@ bool test_log(void) {
// https://github.com/radareorg/radare2/issues/22468
R_LOG_INFO ("%s", "");

LogCbCtx ctx = { 0 };
r_log_add_callback (log_cb_counter, &ctx);
R_LOG_INFO ("hi");
r_log_del_callback (log_cb_counter);
R_LOG_INFO ("bye");
mu_assert_eq (ctx.calls, 1, "r_log_del_callback should unregister callback");

r_core_free (core);
mu_end;
}
Expand Down
Loading