summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wimaxll.h15
-rw-r--r--include/wimaxll/log.h61
-rw-r--r--lib/log.c253
-rw-r--r--lib/wimax.c62
4 files changed, 274 insertions, 117 deletions
diff --git a/include/wimaxll.h b/include/wimaxll.h
index ad2941e..5396c16 100644
--- a/include/wimaxll.h
+++ b/include/wimaxll.h
@@ -176,7 +176,7 @@
* @subsection diagnostics Controlling the ouput of diagnostics
*
* \e libwimaxll will output messages by default to \a stderr. See
- * \ref diagnostics_group for changing the default destination.
+ * \ref helper_log for changing the default destination.
*
* @subsection bytesex Endianess conversion
*
@@ -341,13 +341,20 @@ ssize_t wimaxll_wait_for_state_change(struct wimaxll_handle *wmx,
enum wimax_st *old_state,
enum wimax_st *new_state);
+/*
+ * Basic diagnostics
+ *
+ * Deprecated, see wimaxll/log.h
+ */
+extern void (*wimaxll_vmsg)(const char *, va_list)
+ __attribute__((deprecated));
+void wimaxll_vmsg_stderr(const char *, va_list)
+ __attribute__((deprecated));
+
/**
* \defgroup miscellaneous_group Miscellaneous utilities
*/
-extern void (*wimaxll_vmsg)(const char *, va_list);
-void wimaxll_vmsg_stderr(const char *, va_list);
-
enum wimax_st wimaxll_state_by_name(const char *);
size_t wimaxll_states_snprintf(char *, size_t);
const char * wimaxll_state_to_name(enum wimax_st);
diff --git a/include/wimaxll/log.h b/include/wimaxll/log.h
index bb955b3..fac0afa 100644
--- a/include/wimaxll/log.h
+++ b/include/wimaxll/log.h
@@ -62,6 +62,19 @@
* }
*
* @endcode
+ *
+ * To control where the log/progress messages go and how they are
+ * formatted, the client can set a couple of function pointers
+ * wimaxll_msg_hdr_cb() (which controls how a header/prefix for the
+ * message is created) and wimaxll_vlmsg_cb(), which takes the message
+ * and delivers it to whichever destination.
+ *
+ * The default implementations are wimaxll_msg_hdr_default() and
+ * wimaxll_vlmsg_default(), which add a
+ * "libwimall[DEVICENAME]:" header (with an optional "(@
+ * FUNCTION:LINE)") and deliver the message to \e stdout if it is a
+ * normal message (\e W_PRINT) or else if it is an error, warning,
+ * info or debug message, it is sent to \e stderr.
*/
#ifndef __wimaxll__log_h__
@@ -90,27 +103,39 @@ enum w_levels {
W_D7,
};
-void __w_vmsg(unsigned level, unsigned current_level,
- const char *tag, unsigned line,
- const char *fmt, va_list vargs);
+struct wimaxll_handle;
+
+void wimaxll_msg(struct wimaxll_handle *, const char *fmt, ...)
+ __attribute__ ((format(printf, 2, 3)));
+
+void wimaxll_lmsg(unsigned level, unsigned current_level,
+ const char *origin_str, unsigned origin_line,
+ struct wimaxll_handle *wmx, const char *fmt, ...)
+ __attribute__ ((format(printf, 6, 7)));
+
+extern void (*wimaxll_vlmsg_cb)(struct wimaxll_handle *, unsigned,
+ const char *, const char *, va_list);
+void wimaxll_vlmsg_stderr(struct wimaxll_handle *, unsigned,
+ const char *, const char *, va_list);
-void __w_msg(unsigned level, unsigned current_level,
- const char *tag, unsigned line,
- const char *fmt, ...);
+extern void (*wimaxll_msg_hdr_cb)(char *, size_t, struct wimaxll_handle *,
+ enum w_levels, const char *, unsigned);
+void wimaxll_msg_hdr_default(char *, size_t, struct wimaxll_handle *,
+ enum w_levels, const char *, unsigned);
void w_abort(int result, const char *fmt, ...);
-#define w_error(fmt...) __w_msg(W_ERROR, W_VERBOSITY, __func__, __LINE__, "E: " fmt)
-#define w_warn(fmt...) __w_msg(W_WARN, W_VERBOSITY, __func__, __LINE__, "W: " fmt)
-#define w_info(fmt...) __w_msg(W_INFO, W_VERBOSITY, __func__, __LINE__, "I: " fmt)
-#define w_print(fmt...) __w_msg(W_PRINT, W_VERBOSITY, __func__, __LINE__, fmt)
-#define w_d0(fmt...) __w_msg(W_D0, W_VERBOSITY, __func__, __LINE__, "D0: " fmt)
-#define w_d1(fmt...) __w_msg(W_D1, W_VERBOSITY, __func__, __LINE__, "D1: " fmt)
-#define w_d2(fmt...) __w_msg(W_D2, W_VERBOSITY, __func__, __LINE__, "D2: " fmt)
-#define w_d3(fmt...) __w_msg(W_D3, W_VERBOSITY, __func__, __LINE__, "D3: " fmt)
-#define w_d4(fmt...) __w_msg(W_D4, W_VERBOSITY, __func__, __LINE__, "D4: " fmt)
-#define w_d5(fmt...) __w_msg(W_D5, W_VERBOSITY, __func__, __LINE__, "D5: " fmt)
-#define w_d6(fmt...) __w_msg(W_D6, W_VERBOSITY, __func__, __LINE__, "D6: " fmt)
-#define w_d7(fmt...) __w_msg(W_D7, W_VERBOSITY, __func__, __LINE__, "D7: " fmt)
+#define w_error(fmt...) wimaxll_lmsg(W_ERROR, W_VERBOSITY, __func__, __LINE__, NULL, "E: " fmt)
+#define w_warn(fmt...) wimaxll_lmsg(W_WARN, W_VERBOSITY, __func__, __LINE__, NULL, "W: " fmt)
+#define w_info(fmt...) wimaxll_lmsg(W_INFO, W_VERBOSITY, __func__, __LINE__, NULL, "I: " fmt)
+#define w_print(fmt...) wimaxll_lmsg(W_PRINT, W_VERBOSITY, __func__, __LINE__, NULL, fmt)
+#define w_d0(fmt...) wimaxll_lmsg(W_D0, W_VERBOSITY, __func__, __LINE__, NULL, "D0: " fmt)
+#define w_d1(fmt...) wimaxll_lmsg(W_D1, W_VERBOSITY, __func__, __LINE__, NULL, "D1: " fmt)
+#define w_d2(fmt...) wimaxll_lmsg(W_D2, W_VERBOSITY, __func__, __LINE__, NULL, "D2: " fmt)
+#define w_d3(fmt...) wimaxll_lmsg(W_D3, W_VERBOSITY, __func__, __LINE__, NULL, "D3: " fmt)
+#define w_d4(fmt...) wimaxll_lmsg(W_D4, W_VERBOSITY, __func__, __LINE__, NULL, "D4: " fmt)
+#define w_d5(fmt...) wimaxll_lmsg(W_D5, W_VERBOSITY, __func__, __LINE__, NULL, "D5: " fmt)
+#define w_d6(fmt...) wimaxll_lmsg(W_D6, W_VERBOSITY, __func__, __LINE__, NULL, "D6: " fmt)
+#define w_d7(fmt...) wimaxll_lmsg(W_D7, W_VERBOSITY, __func__, __LINE__, NULL, "D7: " fmt)
#endif /* #define __wimaxll__log_h__ */
diff --git a/lib/log.c b/lib/log.c
index 29463c8..9d85988 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -35,64 +35,241 @@
#include <stdlib.h>
#define W_VERBOSITY W_ERROR
#include <wimaxll/log.h>
+#include "internal.h"
/**
- * Log a message to (varargs version) if log level allows it
+ * Deliver \e libwimaxll diagnostics messages to \e stderr or \e stdout.
*
- * \param level level of the messagve
- * \param current_level current logging level
- * \param tag a str to print along with \e line (if not NULL, its
- * not printed).
- * \param line an integer to print along with \e tag (if \e tag is not
- * NULL)
- * \param fmt printf-like format string
- * \param vargs arguments to \e fmt
+ * \param wmx WiMAX handle this message is related to
+ * \param level Message level
+ * \param header Header for the message; the implementation must
+ * decide if it has to be printed or not.
+ * \param fmt printf-like format
+ * \param vargs variable-argument list as created by
+ * stdargs.h:va_list() that will be formatted according to \e
+ * fmt.
*
- * \internal
+ * Default diagnostics printing function. If the log level is
+ * "W_PRINT", we put it on stdout without a header, otherwise in
+ * stderr with header.
*
- * Use w_*() functions only
- *
- * @ingroup: helper_log
+ * \ingroup helper_log
*/
-void __w_vmsg(unsigned level, unsigned current_level,
- const char *tag, unsigned line,
- const char *fmt, va_list vargs)
+void wimaxll_vlmsg_default(struct wimaxll_handle *wmx, unsigned level,
+ const char *header,
+ const char *fmt, va_list vargs)
{
- FILE *f;
- f = level != W_PRINT? stderr : stdout;
- if (level <= current_level || level == W_PRINT) {
- if (tag)
- fprintf(f, "%s:%u: ", tag, line);
- vfprintf(f, fmt, vargs);
+ FILE *f = level != W_PRINT? stderr : stdout;
+
+ /* Backwards compat */
+ if (wimaxll_vmsg) {
+ if (header)
+ wimaxll_vmsg(header, NULL);
+ wimaxll_vmsg(fmt, vargs);
+ return;
+ }
+ if (level == W_PRINT)
+ f = stdout;
+ else {
+ f = stderr;
+ fprintf(f, header);
}
+ vfprintf(f, fmt, vargs);
}
/**
- * Log a message to if log level allows it
+ * Print library diagnostics messages [backend]
*
- * \param level level of the messagve
- * \param current_level current logging level
- * \param tag a str to print along with \e line (if not NULL, its
- * not printed).
- * \param line an integer to print along with \e tag (if \e tag is not
- * NULL)
- * \param fmt printf-like format string, plus their arguments
+ * @param wmx WiMAX handle this message is related to
+ * @param level Message level
+ * @param header Header to print for the message (the implementation
+ * must decide if to print it or not).
+ * @param fmt printf-like format
+ * @param vargs variable-argument list as created by
+ * stdargs.h:va_list() that will be formatted according to \e
+ * fmt.
*
- * \internal
+ * Prints/writes the \e libwimaxll's diagnostics messages to a
+ * destination as selected by the user of the library.
*
- * Use w_*() functions only
+ * \note This function pointer must be set \b before calling any other
+ * \e libwimaxll function.
*
- * @ingroup: helper_log
+ * By default, diagnostics are printed with wimaxll_vlmsg_default() to
+ * \a stderr or stdout based on the level.
+ *
+ * For example, to deliver diagnostics to syslog:
+ *
+ * @code
+ * #include <syslog.h>
+ * ...
+ * static
+ * void wimaxll_vlmsg_syslog(....const char *fmt, va_list vargs)
+ * {
+ * syslog(LOG_MAKEPRI(LOG_USER, LOG_INFO), header);
+ * vsyslog(LOG_MAKEPRI(LOG_USER, LOG_INFO), fmt, vargs);
+ * }
+ * ...
+ * wimaxll_vlmsg = wimaxll_vlmsg_syslog();
+ * ...
+ * wimaxll_open(BLAH);
+ * @endcode
+ *
+ * The internal function wimaxll_msg() and wimaxll_lmsg() are used as
+ * as a frontend to this function.
+ *
+ * \ingroup helper_log
+ */
+void (*wimaxll_vlmsg_cb)(struct wimaxll_handle *wmx, unsigned level,
+ const char *header,
+ const char *fmt, va_list vargs) =
+ wimaxll_vlmsg_default;
+
+
+/**
+ * Default header for diagnostic messages
+ *
+ * If there is no handle, prints just "libwimaxll", otherwise
+ * "libwimaxll[device]"; if the message is debug, also adds a
+ * "(@ FUNCTION:LINE)" origin tag.
+ *
+ * \ingroup helper_log
+ */
+void wimaxll_msg_hdr_default(char *buf, size_t buf_len,
+ struct wimaxll_handle *wmx, enum w_levels level,
+ const char *origin_str, unsigned origin_line)
+{
+ size_t bytes;
+ if (wmx == NULL)
+ bytes = snprintf(buf, buf_len, "libwimaxll: ");
+ else if ((unsigned long) wmx < 4096)
+ bytes = snprintf(buf, buf_len, "libwimaxll[bad handle %p]: ",
+ wmx);
+ else
+ bytes = snprintf(buf, buf_len, "libwimaxll[%s]: ", wmx->name);
+ if (level >= W_D0 && origin_str != NULL)
+ snprintf(buf + bytes, buf_len - bytes,
+ "(@ %s:%u) ", origin_str, origin_line);
+}
+
+
+/**
+ * Create a header for library diagnostic messages [backend]
+ *
+ * @param buf Buffer where to place the header
+ * @param buf_len Size of the buffer
+ * @param wmx WiMAX handle the message is being generated for (can be
+ * NULL or invalid).
+ * @param level Level of the log message this header is being
+ * generated for.
+ * @param origin_str Origin of the message (used for a source file
+ * name or function name). If %NULL, the origin information should
+ * not be considered.
+ * @param origin_line Origin of the message (used for a line in a
+ * source file or function).
+ *
+ * Creates a header to prefix to ever message printed with
+ * wimaxll_msg().
+ *
+ * By default, diagnostics are printed with wimaxll_msg_hdr_default()
+ * is used, which creates a "libwimaxll[DEVICENAME]" prefix.
+ *
+ * To change it:
+ *
+ * @code
+ * ...
+ * static
+ * void my_wimaxll_msg_hdr(char *buf, size_t len, struct
+ * wimaxll_handle *wmx)
+ * {
+ * snprintf(buf, len, "my prefix: ");
+ * }
+ * ...
+ * wimaxll_msg_hdr = my_wimaxll_msg_hdr;
+ * ...
+ * wimaxll_open(BLAH);
+ * @endcode
+ *
+ * \ingroup helper_log
+ */
+void (*wimaxll_msg_hdr_cb)(char *buf, size_t buf_len,
+ struct wimaxll_handle *wmx, enum w_levels level,
+ const char *origin_str, unsigned origin_line) =
+ wimaxll_msg_hdr_default;
+
+
+static
+void wimaxll_vlmsg(unsigned level, unsigned current_level,
+ const char *origin_str, unsigned origin_int,
+ struct wimaxll_handle *wmx, const char *fmt, va_list vargs)
+{
+ char header[64] = "";
+ if (level > current_level && level != W_PRINT)
+ return;
+ if (wimaxll_msg_hdr_cb)
+ wimaxll_msg_hdr_cb(header, sizeof(header), wmx,
+ level, origin_str, origin_int);
+ wimaxll_vlmsg_cb(wmx, level, header, fmt, vargs);
+}
+
+
+/**
+ * Prints library diagnostic messages with a predefined format [frontend]
+ *
+ * @param wmx WiMAX handle; if NULL, no device header will be presented.
+ * @param fmt printf-like format followed by any arguments
+ *
+ * Called by the library functions to print status/error messages. By
+ * default these are sent over to stderr.
+ *
+ * However, library users can change this default behaviour by setting
+ * wimaxll_vmsg() as documented in that function pointer's
+ * documentation.
+ *
+ * \ingroup helper_log
+ */
+void wimaxll_msg(struct wimaxll_handle *wmx, const char *fmt, ...)
+{
+ va_list vargs;
+ va_start(vargs, fmt);
+ wimaxll_vlmsg(W_PRINT, W_PRINT, NULL, 0, wmx, fmt, vargs);
+ va_end(vargs);
+}
+
+
+/**
+ * Prints library diagnostic messages with a predefined format
+ * [frontend] and log level control
+ *
+ * @param level level of the messagve
+ * @param current_level current logging level
+ * @param origin_str Origin of the message (used for a source file
+ * name or function name).
+ * @param origin_line Origin of the message (used for a line in a
+ * source file or function).
+ * @param wmx WiMAX handle; if NULL, no device header will be presented.
+ * @param fmt printf-like format followed by any arguments
+ *
+ * Called by the library functions to print status/error messages if
+ * the current log level allows it. By default these are sent over to
+ * stderr.
+ *
+ * However, library users can change this default behaviour by setting
+ * wimaxll_vmsg() as documented in that function pointer's
+ * documentation.
+ *
+ * \ingroup helper_log
*/
-void __w_msg(unsigned level, unsigned current_level,
- const char *tag, unsigned line,
- const char *fmt, ...)
+void wimaxll_lmsg(unsigned level, unsigned current_level,
+ const char *origin_str, unsigned origin_line,
+ struct wimaxll_handle *wmx, const char *fmt, ...)
{
va_list vargs;
va_start(vargs, fmt);
- __w_vmsg(level, current_level, tag, line, fmt, vargs);
+ wimaxll_vlmsg(level, current_level, origin_str, origin_line,
+ wmx, fmt, vargs);
va_end(vargs);
}
@@ -109,7 +286,7 @@ void w_abort(int result, const char *fmt, ...)
{
va_list vargs;
va_start(vargs, fmt);
- __w_vmsg(W_ERROR, W_ERROR, __FILE__, __LINE__, fmt, vargs);
+ wimaxll_vlmsg(W_ERROR, W_ERROR, __FILE__, __LINE__, NULL, fmt, vargs);
va_end(vargs);
exit(result);
}
diff --git a/lib/wimax.c b/lib/wimax.c
index c0a52e4..d579d8c 100644
--- a/lib/wimax.c
+++ b/lib/wimax.c
@@ -192,21 +192,10 @@ int wimaxll_wait_for_ack(struct wimaxll_handle *wmx)
/**
- * \defgroup diagnostics_group Output of diagnostics messages
- *
- * The \e libwimaxll library prints diagnostics by default to \a
- * stderr. Said destination can be changed by the user by setting the
- * wimaxll_vmsg() function pointer before calling any other \a
- * libwimaxll function.
- *
- * To restore the default diagnostics destination, set wimaxll_vmsg()
- * back to wimaxll_vmsg_stderr().
- */
-
-
-/**
* Deliver \e libwimaxll diagnostics messages to \e stderr
*
+ * \deprecated { use wimaxll_vlmsg_cb }
+ *
* \param fmt printf-like format
* \param vargs variable-argument list as created by
* stdargs.h:va_list() that will be formatted according to \e
@@ -226,6 +215,8 @@ void wimaxll_vmsg_stderr(const char *fmt, va_list vargs)
/**
* Print library diagnostics messages [backend]
*
+ * \deprecated { use wimaxll_vlmsg_cb }
+ *
* @param fmt printf-like format
* @param vargs variable-argument list as created by
* stdargs.h:va_list() that will be formatted according to \e
@@ -262,50 +253,7 @@ void wimaxll_vmsg_stderr(const char *fmt, va_list vargs)
* The internal function wimaxll_msg() is used as as a frontend to
* this function.
*/
-void (*wimaxll_vmsg)(const char *fmt, va_list vargs) = wimaxll_vmsg_stderr;
-
-
-static
-void __wimaxll_msg(const char *fmt, ...)
-{
- va_list vargs;
- va_start(vargs, fmt);
- wimaxll_vmsg(fmt, vargs);
- va_end(vargs);
-}
-
-
-/**
- * \internal
- *
- * Prints library diagnostic messages with a predefined format [frontend]
- *
- * @param wmx WiMAX handle; if NULL, no device header will be presented.
- * @param fmt printf-like format followed by any arguments
- *
- * Called by the library functions to print status/error messages. By
- * default these are sent over to stderr.
- *
- * However, library users can change this default behaviour by setting
- * wimaxll_vmsg() as documented in that function pointer's
- * documentation.
- *
- * \ingroup diagnostics_group
- */
-void wimaxll_msg(struct wimaxll_handle *wmx, const char *fmt, ...)
-{
- va_list vargs;
- if (wmx == NULL)
- __wimaxll_msg("libwimax: ");
- else if ((unsigned long) wmx < 4096) {
- __wimaxll_msg("libwimax: E: Corrupt device handle %p\n", wmx);
- __wimaxll_msg("libwimax[n/a]: ");
- } else
- __wimaxll_msg("libwimax[%s]: ", wmx->name);
- va_start(vargs, fmt);
- wimaxll_vmsg(fmt, vargs);
- va_end(vargs);
-}
+void (*wimaxll_vmsg)(const char *fmt, va_list vargs) = NULL;
/**