]> git.alsa-project.org Git - alsa-lib.git/commitdiff
redesign the message log functions
authorJaroslav Kysela <perex@perex.cz>
Thu, 6 Nov 2025 13:29:54 +0000 (14:29 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 7 Nov 2025 17:09:26 +0000 (18:09 +0100)
Add priority level and interface classifiers. Define macros
for all priority level types to keep the callers more readable.
Ensure the compatibility with previous logging mechanism.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/error.h
include/local.h
src/Versions.in.in
src/conf.c
src/control/namehint.c
src/error.c

index 13f59d551a2a56d7fadac9e3214596baae97c095..8b9b85913a7d8759695640fb8fa639bb4fe73885 100644 (file)
@@ -49,42 +49,103 @@ extern "C" {
 
 const char *snd_strerror(int errnum);
 
+#define SND_LOG_ERROR          1       /**< error priority level */
+#define SND_LOG_WARN           2       /**< warning priority level */
+#define SND_LOG_INFO           3       /**< info priority level */
+#define SND_LOG_DEBUG          4       /**< debug priority level */
+#define SND_LOG_TRACE          5       /**< trace priority level */
+
+#define SND_ILOG_CORE           1      /**< core library code */
+#define SND_ILOG_CONFIG                2       /**< configuration parsing and operations */
+#define SND_ILOG_CONTROL       3       /**< control API */
+#define SND_ILOG_HWDEP         4       /**< hwdep API */
+#define SND_ILOG_TIMER         5       /**< timer API */
+#define SND_ILOG_RAWMIDI       6       /**< RawMidi API */
+#define SND_ILOG_PCM           7       /**< PCM API */
+#define SND_ILOG_MIXER         8       /**< mixer API */
+#define SND_ILOG_SEQUENCER     9       /**< sequencer API */
+#define SND_ILOG_UCM           10      /**< UCM API */
+#define SND_ILOG_TOPOLOGY      11      /**< topology API */
+#define SND_ILOG_ASERVER       12      /**< aserver */
+
+/**
+ * \brief Log handler callback.
+ * \param prio Priority (SND_LOG_* defines).
+ * \param interface Interface (SND_ILOG_* defines).
+ * \param file Source file name.
+ * \param line Line number.
+ * \param function Function name.
+ * \param errcode Value of \c errno, or 0 if not relevant.
+ * \param fmt \c printf(3) format.
+ * \param ... \c printf(3) arguments.
+ *
+ * A function of this type is called by the ALSA library when an error occurs.
+ * This function usually shows the message on the screen, and/or logs it.
+ */
+typedef void (*snd_lib_log_handler_t)(int prio, int interface, const char *file, int line, const char *function, int errcode, const char *fmt, va_list arg);
+extern snd_lib_log_handler_t snd_lib_vlog;
+void snd_lib_log(int prio, int interface, const char *file, int line, const char *function, int errcode, const char *fmt, ...) /* __attribute__ ((format (printf, 7, 8))) */;
+void snd_lib_check(int interface, const char *file, int line, const char *function, int errcode, const char *fmt, ...);
+snd_lib_log_handler_t snd_lib_log_set_handler(snd_lib_log_handler_t handler);
+snd_lib_log_handler_t snd_lib_log_set_local(snd_lib_log_handler_t handler);
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95)
+#define snd_error(interface, ...) snd_lib_log(SND_LOG_ERROR, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows an error log message. */
+#define snd_errornum(interface, ...) snd_lib_log(SND_LOG_ERROR, SND_ILOG_##interface, __FILE__, __LINE__, __func__, errno, __VA_ARGS__) /**< Shows a system error log message (related to \c errno). */
+#define snd_warn(interface, ...) snd_lib_log(SND_LOG_WARN, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows an error log message. */
+#define snd_info(interface, ...) snd_lib_log(SND_LOG_INFO, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows an informational log message. */
+#define snd_debug(interface, ...) snd_lib_log(SND_LOG_DEBUG, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows an debug log message. */
+#define snd_trace(interface, ...) snd_lib_log(SND_LOG_TRACE, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows an trace log message. */
+#define snd_check(interface, ...) snd_lib_check(SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows an check log message. */
+#define snd_checknum(interface, ...) snd_lib_check(SND_ILOG_##interface, __FILE__, __LINE__, __func__, errno, __VA_ARGS__) /**< Shows an check log message (related to \c errno). */
+#else
+#define snd_error(interface, args...) snd_lib_log(SND_LOG_ERROR, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows an error log message. */
+#define snd_errornum(interface, args...) snd_lib_log(SND_LOG_ERROR, SND_ILOG_##interface, __FILE__, __LINE__, __func__, errno, ##args) /**< Shows a system error log message (related to \c errno). */
+#define snd_warn(interface, args...) snd_lib_log(SND_LOG_WARN, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows an error log message. */
+#define snd_info(interface, args...) snd_lib_log(SND_LOG_INFO, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows an error log message. */
+#define snd_debug(interface, args...) snd_lib_log(SND_LOG_DEBUG, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows an error log message. */
+#define snd_trace(interface, args...) snd_lib_log(SND_LOG_TRACE, SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows an trace log message. */
+#define snd_check(interface, args...) snd_lib_check(SND_ILOG_##interface, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows an check log message. */
+#define snd_check(interface, args...) snd_lib_check(SND_ILOG_##interface, __FILE__, __LINE__, __func__, errno, ##args) /**< Shows an check log message (related to \c errno). */
+#endif
+
 /**
  * \brief Error handler callback.
  * \param file Source file name.
  * \param line Line number.
  * \param function Function name.
- * \param err Value of \c errno, or 0 if not relevant.
+ * \param errcode Value of \c errno, or 0 if not relevant.
  * \param fmt \c printf(3) format.
  * \param ... \c printf(3) arguments.
+ * \deprecated Since 1.2.15
  *
  * A function of this type is called by the ALSA library when an error occurs.
  * This function usually shows the message on the screen, and/or logs it.
  */
-typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int err, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */;
+typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int errcode, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */;
 extern snd_lib_error_handler_t snd_lib_error;
-extern int snd_lib_error_set_handler(snd_lib_error_handler_t handler);
+int snd_lib_error_set_handler(snd_lib_error_handler_t handler);
 
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95)
-#define SNDERR(...) snd_lib_error(__FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows a sound error message. */
-#define SYSERR(...) snd_lib_error(__FILE__, __LINE__, __func__, errno, __VA_ARGS__) /**< Shows a system error message (related to \c errno). */
+#define SNDERR(...) snd_lib_log(SND_LOG_ERROR, 0, __FILE__, __LINE__, __func__, 0, __VA_ARGS__) /**< Shows a sound error message. */
+#define SYSERR(...) snd_lib_log(SND_LOG_ERROR, 0, __FILE__, __LINE__, __func__, errno, __VA_ARGS__) /**< Shows a system error message (related to \c errno). */
 #else
-#define SNDERR(args...) snd_lib_error(__FILE__, __LINE__, __func__, 0, ##args) /**< Shows a sound error message. */
-#define SYSERR(args...) snd_lib_error(__FILE__, __LINE__, __func__, errno, ##args) /**< Shows a system error message (related to \c errno). */
+#define SNDERR(args...) snd_lib_log(SND_LOG_ERROR, 0, __FILE__, __LINE__, __func__, 0, ##args) /**< Shows a sound error message. */
+#define SYSERR(args...) snd_lib_log(SND_LOG_ERROR, 0, __FILE__, __LINE__, __func__, errno, ##args) /**< Shows a system error message (related to \c errno). */
 #endif
 
+/** Local error handler function type */
+typedef void (*snd_local_error_handler_t)(const char *file, int line,
+                                         const char *func, int errcode,
+                                         const char *fmt, va_list arg);
+snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func);
+
 /** \} */
 
 #ifdef __cplusplus
 }
 #endif
 
-/** Local error handler function type */
-typedef void (*snd_local_error_handler_t)(const char *file, int line,
-                                         const char *func, int err,
-                                         const char *fmt, va_list arg);
 
-snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func);
 
 #endif /* __ALSA_ERROR_H */
-
index fec332e58484fe2d4b4b22a3b285ca2c12ac0b35..da70cf5253dde9498ee373a97c7f194ab68cd6e5 100644 (file)
@@ -274,9 +274,8 @@ size_t snd_strlcat(char *dst, const char *src, size_t size);
  */
 #ifndef NDEBUG
 #define CHECK_SANITY(x) x
-extern snd_lib_error_handler_t _snd_err_msg;
-#define SNDMSG(args...) _snd_err_msg(__FILE__, __LINE__, __func__, 0, ##args)
-#define SYSMSG(args...) _snd_err_msg(__FILE__, __LINE__, __func__, errno, ##args)
+#define SNDMSG(args...) snd_lib_check(0, __FILE__, __LINE__, __func__, 0, ##args)
+#define SYSMSG(args...) snd_lib_check(0, __FILE__, __LINE__, __func__, errno, ##args)
 #else
 #define CHECK_SANITY(x) 0 /* not evaluated */
 #define SNDMSG(args...) /* nop */
index 4aa2e13b74c85df1e193d3ccb9ca5c7574c1511d..36b6ab5d7b320e2e2ba563bc7262609cfe0a1bb0 100644 (file)
@@ -214,3 +214,16 @@ ALSA_1.2.13 {
     @SYMBOL_PREFIX@snd_ump_packet_length;
 #endif
 } ALSA_1.2.10;
+
+
+ALSA_1.2.15 {
+  global:
+
+    @SYMBOL_PREFIX@snd_lib_vlog;
+    @SYMBOL_PREFIX@snd_lib_log;
+    @SYMBOL_PREFIX@snd_lib_log_set_handler;
+    @SYMBOL_PREFIX@snd_lib_log_set_local;
+    @SYMBOL_PREFIX@snd_lib_log_priority;
+    @SYMBOL_PREFIX@snd_lib_log_interface;
+    @SYMBOL_PREFIX@snd_lib_check;
+} ALSA_1.2.13;
index 91aa628b8ac1bebd98faaa4303c608a9cc6e09c9..92446e619f50663560ae185271752aea89fc9f7c 100644 (file)
@@ -811,7 +811,7 @@ static int get_char_skip_comments(input_t *input)
 
                                dirp = opendir(str);
                                if (!dirp) {
-                                       SNDERR("Invalid search dir %s", str);
+                                       snd_error(CONFIG, "Invalid search dir %s", str);
                                        free(str);
                                        return -EINVAL;
                                }
index 11783c0c44653637e69958ad8b55271f14822a5c..8d6c64d5a375295cdb738d59db0aaac9d6db7f59 100644 (file)
@@ -104,7 +104,9 @@ static int hint_list_add_custom(struct hint_list *list,
        return err;
 }
 
-static void zero_handler(const char *file ATTRIBUTE_UNUSED,
+static void zero_handler(int prio ATTRIBUTE_UNUSED,
+                        int interface ATTRIBUTE_UNUSED,
+                        const char *file ATTRIBUTE_UNUSED,
                         int line ATTRIBUTE_UNUSED,
                         const char *function ATTRIBUTE_UNUSED,
                         int err ATTRIBUTE_UNUSED,
@@ -239,7 +241,7 @@ static int try_config(snd_config_t *config,
                      const char *base,
                      const char *name)
 {
-       snd_local_error_handler_t eh;
+       snd_lib_log_handler_t eh;
        snd_config_t *res = NULL, *cfg, *cfg1, *n;
        snd_config_iterator_t i, next;
        char *buf, *buf1 = NULL, *buf2;
@@ -266,9 +268,9 @@ static int try_config(snd_config_t *config,
                sprintf(buf, "%s:CARD=%s", name, snd_ctl_card_info_get_id(list->info));
        else
                strcpy(buf, name);
-       eh = snd_lib_error_set_local(&zero_handler);
+       eh = snd_lib_log_set_local(&zero_handler);
        err = snd_config_search_definition(config, base, buf, &res);
-       snd_lib_error_set_local(eh);
+       snd_lib_log_set_local(eh);
        if (err < 0)
                goto __skip_add;
        cleanup_res = 1;
@@ -369,9 +371,9 @@ static int try_config(snd_config_t *config,
                goto __ok;
        /* find, if all parameters have a default, */
        /* otherwise filter this definition */
-       eh = snd_lib_error_set_local(&zero_handler);
+       eh = snd_lib_log_set_local(&zero_handler);
        err = snd_config_search_alias_hooks(config, base, buf, &res);
-       snd_lib_error_set_local(eh);
+       snd_lib_log_set_local(eh);
        if (err < 0)
                goto __cleanup;
        if (snd_config_search(res, "@args", &cfg) >= 0) {
index 0eefce0eea7cb7b52549d83fcb875a90ad71f3a4..e077cb9503f1cf7eee9b453c543703952b7bf8b8 100644 (file)
@@ -68,12 +68,131 @@ const char *snd_strerror(int errnum)
 #endif
 #endif
 
+static TLS_PFX snd_lib_log_handler_t local_log = NULL;
 static TLS_PFX snd_local_error_handler_t local_error = NULL;
 
+/**
+ * \brief Install local log handler
+ * \param func The local log handler function
+ * \retval Previous local log handler function
+ */
+snd_lib_log_handler_t snd_lib_log_set_local(snd_lib_log_handler_t func)
+{
+       snd_lib_log_handler_t old = local_log;
+       local_log = func;
+       return old;
+}
+
+/**
+ * \brief The default log handler function.
+ * \param prio Priority value (SND_LOG_*).
+ * \param interface Interface (SND_ILOG_*).
+ * \param file The filename where the error was hit.
+ * \param line The line number.
+ * \param function The function name.
+ * \param errcode The error code.
+ * \param fmt The message (including the format characters).
+ * \param ... Optional arguments.
+ *
+ * If a local error function has been installed for the current thread by
+ * \ref snd_lib_log_set_local, it is called. Otherwise, prints the error
+ * message including location to \c stderr.
+ */
+static void snd_lib_vlog_default(int prio, int interface, const char *file, int line, const char *function, int errcode, const char *fmt, va_list arg)
+{
+       if (local_log) {
+               local_log(prio, interface, file, line, function, errcode, fmt, arg);
+               return;
+       }
+       if (local_error && prio == SND_LOG_ERROR) {
+               local_error(file, line, function, errcode, fmt, arg);
+               return;
+       }
+       fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function);
+       vfprintf(stderr, fmt, arg);
+       if (errcode)
+               fprintf(stderr, ": %s", snd_strerror(errcode));
+       putc('\n', stderr);
+}
+
+/**
+ * \brief Root log handler function.
+ * \param prio Priority value (SND_LOG_*).
+ * \param interface Interface (SND_ILOG_*).
+ * \param file The filename where the error was hit.
+ * \param line The line number.
+ * \param function The function name.
+ * \param errcode The error code.
+ * \param fmt The message (including the format characters).
+ * \param ... Optional arguments.
+ */
+void snd_lib_log(int prio, int interface, const char *file, int line, const char *function, int errcode, const char *fmt, ...)
+{
+       va_list arg;
+       va_start(arg, fmt);
+       snd_lib_vlog(prio, interface, file, line, function, errcode, fmt, arg);
+       va_end(arg);
+}
+
+/**
+ * \brief The check point function.
+ * \param interface Interface (SND_ILOG_*).
+ * \param file The filename where the error was hit.
+ * \param line The line number.
+ * \param function The function name.
+ * \param errcode The error code.
+ * \param fmt The message (including the format characters).
+ * \param ... Optional arguments.
+ *
+ * The error message is passed with error priority level to snd_lib_vlog handler.
+ */
+void snd_lib_check(int interface, const char *file, int line, const char *function, int errcode, const char *fmt, ...)
+{
+       const char *verbose;
+
+       va_list arg;
+       va_start(arg, fmt);
+       verbose = getenv("LIBASOUND_DEBUG");
+       if (! verbose || ! *verbose)
+               goto finish;
+       snd_lib_vlog(SND_LOG_ERROR, interface, file, line, function, errcode, fmt, arg);
+#ifdef ALSA_DEBUG_ASSERT
+       verbose = getenv("LIBASOUND_DEBUG_ASSERT");
+       if (verbose && *verbose)
+               assert(0);
+#endif
+finish:
+       va_end(arg);
+}
+
+/**
+ * \ingroup Error
+ * Pointer to the error handler function.
+ * For internal use only.
+ */
+snd_lib_log_handler_t snd_lib_vlog = snd_lib_vlog_default;
+
+/**
+ * \brief Sets the log handler.
+ * \param handler The pointer to the new log handler function.
+ * \retval Previous log handler function
+ *
+ * This function sets a new log handler, or (if \c handler is \c NULL)
+ * the default one which prints the error messages to \c stderr.
+ */
+snd_lib_log_handler_t snd_lib_log_set_handler(snd_lib_log_handler_t handler)
+{
+       snd_lib_log_handler_t old = snd_lib_vlog;
+       snd_lib_vlog = handler == NULL ? snd_lib_vlog_default : handler;
+       return old;
+}
+
+
 /**
  * \brief Install local error handler
  * \param func The local error handler function
  * \retval Previous local error handler function
+ * \deprecated Since 1.2.15
  */
 snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func)
 {
@@ -81,47 +200,41 @@ snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func
        local_error = func;
        return old;
 }
+link_warning(snd_lib_error_set_local, "Warning: snd_lib_error_set_local is deprecated, use snd_lib_log_set_local");
 
 /**
  * \brief The default error handler function.
  * \param file The filename where the error was hit.
  * \param line The line number.
  * \param function The function name.
- * \param err The error code.
+ * \param errcode The error code.
  * \param fmt The message (including the format characters).
  * \param ... Optional arguments.
+ * \deprecated Since 1.2.15
  *
- * If a local error function has been installed for the current thread by
- * \ref snd_lib_error_set_local, it is called. Otherwise, prints the error
- * message including location to \c stderr.
+ * Use snd_lib_vlog handler to print error message for anonymous interface.
  */
-static void snd_lib_error_default(const char *file, int line, const char *function, int err, const char *fmt, ...)
+static void snd_lib_error_default(const char *file, int line, const char *function, int errcode, const char *fmt, ...)
 {
        va_list arg;
        va_start(arg, fmt);
-       if (local_error) {
-               local_error(file, line, function, err, fmt, arg);
-               va_end(arg);
-               return;
-       }
-       fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function);
-       vfprintf(stderr, fmt, arg);
-       if (err)
-               fprintf(stderr, ": %s", snd_strerror(err));
-       putc('\n', stderr);
+       snd_lib_vlog(SND_LOG_ERROR, 0, file, line, function, errcode, fmt, arg);
        va_end(arg);
 }
 
 /**
  * \ingroup Error
+ * \deprecated Since 1.2.15
  * Pointer to the error handler function.
  * For internal use only.
  */
 snd_lib_error_handler_t snd_lib_error = snd_lib_error_default;
+link_warning(snd_lib_error, "Warning: snd_lib_error is deprecated, use snd_log interface");
 
 /**
  * \brief Sets the error handler.
  * \param handler The pointer to the new error handler function.
+ * \deprecated Since 1.2.15
  *
  * This function sets a new error handler, or (if \c handler is \c NULL)
  * the default one which prints the error messages to \c stderr.
@@ -129,10 +242,6 @@ snd_lib_error_handler_t snd_lib_error = snd_lib_error_default;
 int snd_lib_error_set_handler(snd_lib_error_handler_t handler)
 {
        snd_lib_error = handler == NULL ? snd_lib_error_default : handler;
-#ifndef NDEBUG
-       if (snd_lib_error != snd_lib_error_default)
-               _snd_err_msg = snd_lib_error;
-#endif
        return 0;
 }
 
@@ -145,39 +254,6 @@ const char *snd_asoundlib_version(void)
        return SND_LIB_VERSION_STR;
 }
 
-#ifndef NDEBUG
-/*
- * internal error handling
- */
-static void snd_err_msg_default(const char *file, int line, const char *function, int err, const char *fmt, ...)
-{
-       va_list arg;
-       const char *verbose;
-       
-       verbose = getenv("LIBASOUND_DEBUG");
-       if (! verbose || ! *verbose)
-               return;
-       va_start(arg, fmt);
-       fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function);
-       vfprintf(stderr, fmt, arg);
-       if (err)
-               fprintf(stderr, ": %s", snd_strerror(err));
-       putc('\n', stderr);
-       va_end(arg);
-#ifdef ALSA_DEBUG_ASSERT
-       verbose = getenv("LIBASOUND_DEBUG_ASSERT");
-       if (verbose && *verbose)
-               assert(0);
-#endif
-}
-
-/**
- * The ALSA error message handler
- */
-snd_lib_error_handler_t _snd_err_msg = snd_err_msg_default;
-
-#endif
-
 /**
  * \brief Copy a C-string into a sized buffer
  * \param dst Where to copy the string to