spa: add context to debug functions

Add new spa_debugc_ funnctions that take a context. The user should also
redefine the spa_debugc macro to handle the context.

Use this to let some plugins log the pod and format to the log without
using the global logger.

Also use this to remove our custom pod logger function by reusing the
spa one with a custom context.
This commit is contained in:
Wim Taymans 2023-01-18 13:09:00 +01:00
parent f472fd736d
commit 3c67821c4a
14 changed files with 158 additions and 268 deletions

View file

@ -239,163 +239,14 @@ struct log_ctx {
const char *func;
};
#define _log(_c,fmt,...) pw_log_log(_c->level, _c->file, _c->line, _c->func, \
"%*s" fmt, indent, "", ## __VA_ARGS__)
#undef spa_debugc
#define spa_debugc(_ctx,_fmt,...) \
({ struct log_ctx *_c = _ctx; \
pw_log_log(_c->level, _c->file, _c->line, _c->func, \
_fmt, ## __VA_ARGS__); \
})
static inline int
log_pod_value(struct log_ctx *ctx, int indent, const struct spa_type_info *info,
uint32_t type, void *body, uint32_t size)
{
switch (type) {
case SPA_TYPE_Bool:
_log(ctx, "Bool %s", (*(int32_t *) body) ? "true" : "false");
break;
case SPA_TYPE_Id:
_log(ctx, "Id %-8d (%s)", *(int32_t *) body,
spa_debug_type_find_name(info, *(int32_t *) body));
break;
case SPA_TYPE_Int:
_log(ctx, "Int %d", *(int32_t *) body);
break;
case SPA_TYPE_Long:
_log(ctx, "Long %" PRIi64 "", *(int64_t *) body);
break;
case SPA_TYPE_Float:
_log(ctx, "Float %f", *(float *) body);
break;
case SPA_TYPE_Double:
_log(ctx, "Double %f", *(double *) body);
break;
case SPA_TYPE_String:
_log(ctx, "String \"%s\"", (char *) body);
break;
case SPA_TYPE_Fd:
_log(ctx, "Fd %d", *(int *) body);
break;
case SPA_TYPE_Pointer:
{
struct spa_pod_pointer_body *b = (struct spa_pod_pointer_body *)body;
_log(ctx, "Pointer %s %p",
spa_debug_type_find_name(SPA_TYPE_ROOT, b->type), b->value);
break;
}
case SPA_TYPE_Rectangle:
{
struct spa_rectangle *r = (struct spa_rectangle *)body;
_log(ctx, "Rectangle %dx%d", r->width, r->height);
break;
}
case SPA_TYPE_Fraction:
{
struct spa_fraction *f = (struct spa_fraction *)body;
_log(ctx, "Fraction %d/%d", f->num, f->denom);
break;
}
case SPA_TYPE_Bitmap:
_log(ctx, "Bitmap");
break;
case SPA_TYPE_Array:
{
struct spa_pod_array_body *b = (struct spa_pod_array_body *)body;
void *p;
const struct spa_type_info *ti = spa_debug_type_find(SPA_TYPE_ROOT, b->child.type);
_log(ctx, "Array: child.size %d, child.type %s", b->child.size,
ti ? ti->name : "unknown");
SPA_POD_ARRAY_BODY_FOREACH(b, size, p)
log_pod_value(ctx, indent + 2, info, b->child.type, p, b->child.size);
break;
}
case SPA_TYPE_Choice:
{
struct spa_pod_choice_body *b = (struct spa_pod_choice_body *)body;
void *p;
const struct spa_type_info *ti = spa_debug_type_find(spa_type_choice, b->type);
_log(ctx, "Choice: type %s, flags %08x %d %d",
ti ? ti->name : "unknown", b->flags, size, b->child.size);
SPA_POD_CHOICE_BODY_FOREACH(b, size, p)
log_pod_value(ctx, indent + 2, info, b->child.type, p, b->child.size);
break;
}
case SPA_TYPE_Struct:
{
struct spa_pod *b = (struct spa_pod *)body, *p;
_log(ctx, "Struct: size %d", size);
SPA_POD_FOREACH(b, size, p)
log_pod_value(ctx, indent + 2, info, p->type, SPA_POD_BODY(p), p->size);
break;
}
case SPA_TYPE_Object:
{
struct spa_pod_object_body *b = (struct spa_pod_object_body *)body;
struct spa_pod_prop *p;
const struct spa_type_info *ti, *ii;
ti = spa_debug_type_find(info, b->type);
ii = ti ? spa_debug_type_find(ti->values, 0) : NULL;
ii = ii ? spa_debug_type_find(ii->values, b->id) : NULL;
_log(ctx, "Object: size %d, type %s (%d), id %s (%d)", size,
ti ? ti->name : "unknown", b->type, ii ? ii->name : "unknown", b->id);
info = ti ? ti->values : info;
indent += 2;
SPA_POD_OBJECT_BODY_FOREACH(b, size, p) {
ii = spa_debug_type_find(info, p->key);
_log(ctx, "Prop: key %s (%d), flags %08x",
ii ? ii->name : "unknown", p->key, p->flags);
log_pod_value(ctx, indent + 2, ii ? ii->values : NULL,
p->value.type,
SPA_POD_CONTENTS(struct spa_pod_prop, p),
p->value.size);
}
indent -= 2;
break;
}
case SPA_TYPE_Sequence:
{
struct spa_pod_sequence_body *b = (struct spa_pod_sequence_body *)body;
const struct spa_type_info *ti, *ii;
struct spa_pod_control *c;
ti = spa_debug_type_find(info, b->unit);
_log(ctx, "%*s" "Sequence: size %d, unit %s", indent, "", size,
ti ? ti->name : "unknown");
indent +=2;
SPA_POD_SEQUENCE_BODY_FOREACH(b, size, c) {
ii = spa_debug_type_find(spa_type_control, c->type);
_log(ctx, "Control: offset %d, type %s",
c->offset, ii ? ii->name : "unknown");
log_pod_value(ctx, indent + 2, ii ? ii->values : NULL,
c->value.type,
SPA_POD_CONTENTS(struct spa_pod_control, c),
c->value.size);
}
indent -=2;
break;
}
case SPA_TYPE_Bytes:
_log(ctx, "Bytes");
break;
case SPA_TYPE_None:
_log(ctx, "None");
break;
default:
_log(ctx, "unhandled POD type %d", type);
break;
}
return 0;
}
#include <spa/debug/pod.h>
void pw_log_log_object(enum spa_log_level level,
const char *file,
@ -403,16 +254,13 @@ void pw_log_log_object(enum spa_log_level level,
const char *func,
uint32_t flags, const void *object)
{
struct log_ctx ctx = { level, file, 0, func, };
struct log_ctx ctx = { level, file, line, func, };
if (flags & PW_LOG_OBJECT_POD) {
const struct spa_pod *pod = object;
if (pod == NULL) {
pw_log_log(level, file, line, func, "NULL");
} else {
log_pod_value(&ctx, 0, SPA_TYPE_ROOT,
SPA_POD_TYPE(pod),
SPA_POD_BODY(pod),
SPA_POD_BODY_SIZE(pod));
spa_debugc_pod(&ctx, 0, SPA_TYPE_ROOT, pod);
}
}
}