diff --git a/spa/include/spa/support/log.h b/spa/include/spa/support/log.h index 450ff2624..fba50e75b 100644 --- a/spa/include/spa/support/log.h +++ b/spa/include/spa/support/log.h @@ -84,6 +84,21 @@ struct spa_log_topic { bool has_custom_level; }; +/** + * Enumeration of log topics in a plugin + * + * \since 1.1.0 + */ +struct spa_log_topic_enum { +#define SPA_VERSION_LOG_TOPIC_ENUM 0 + uint32_t version; + /** Array of pointers to log topics */ + struct spa_log_topic * const * const topics; + /** End of topics array */ + struct spa_log_topic * const * const topics_end; +}; + + struct spa_log_methods { #define SPA_VERSION_LOG_METHODS 1 uint32_t version; @@ -185,6 +200,10 @@ struct spa_log_methods { /** * Initializes a \ref spa_log_topic to the correct logging level. * + * \deprecated + * Plugin host should obtain log topics from \ref SPA_LOG_TOPIC_ENUM_NAME + * and update them itself. + * * \since 1 */ void (*topic_init) (void *object, struct spa_log_topic *topic); @@ -282,6 +301,66 @@ static inline bool spa_log_level_topic_enabled(const struct spa_log *log, #endif +/** + * Name of the symbol indicating a \ref spa_log_topic_enum enumerating + * the static log topics in a plugin, + * + * \since 1.1.0 + */ +#define SPA_LOG_TOPIC_ENUM_NAME "spa_log_topic_enum" + +/** + * Define the symbol for \ref SPA_LOG_TOPIC_ENUM_NAME + * + * \since 1.1.0 + */ +#define SPA_LOG_TOPIC_ENUM_DEFINE(s, e) \ + SPA_EXPORT struct spa_log_topic_enum spa_log_topic_enum = (struct spa_log_topic_enum) { \ + .version = SPA_VERSION_LOG_TOPIC_ENUM, \ + .topics = (s), \ + .topics_end = (e), \ + } + +/** + * Magically register a statically defined \ref spa_log_topic into + * the log topic enumeration for a plugin. + * + * \since 1.1.0 + */ +#define SPA_LOG_TOPIC_REGISTER(v) \ + __attribute__((used)) __attribute__((retain)) \ + __attribute__((section("spa_log_topic"))) __attribute__((aligned(__alignof__(struct spa_log_topic *)))) \ + static struct spa_log_topic * const spa_log_topic_export_##v = &v + +/** + * Define and magically register a \ref spa_log_topic + * + * \since 1.1.0 + */ +#define SPA_LOG_TOPIC_DEFINE(var,name) \ + struct spa_log_topic var = SPA_LOG_TOPIC(SPA_VERSION_LOG_TOPIC, name); \ + SPA_LOG_TOPIC_REGISTER(var) + +/** + * Define and magically register a \ref spa_log_topic with static scope + * + * \since 1.1.0 + */ +#define SPA_LOG_TOPIC_DEFINE_STATIC(var,name) \ + static struct spa_log_topic var = SPA_LOG_TOPIC(SPA_VERSION_LOG_TOPIC, name); \ + SPA_LOG_TOPIC_REGISTER(var) + +/** + * Do \ref SPA_LOG_TOPIC_ENUM_DEFINE for the auto-registered + * \ref spa_log_topic in the plugin. + * + * \since 1.1.0 + */ +#define SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED \ + extern struct spa_log_topic * const __start_spa_log_topic[]; \ + extern struct spa_log_topic * const __stop_spa_log_topic[]; \ + SPA_LOG_TOPIC_ENUM_DEFINE(__start_spa_log_topic, __stop_spa_log_topic) + /** \fn spa_log_error */ /** keys can be given when initializing the logger handle */