Rework conditional feature usage
Currently, the infrastructure that we have to enable a flexible
compilation environment has a few issues:
- the allocator configuration is performed at run-time, while the log
configuration is performed at compile-time
- for a standard compile (ie, standard userspace, using
autoconf+automake to build), we need a few pre-defined configuration
options.
This change adds a bit of runtime selection to the logging
infrastructure, to match the allocator setup. We also unify the
compile-time defines into config.h, using MCTP_-prefixed macro names,
allowing integration into other build systems.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
diff --git a/Makefile.am b/Makefile.am
index 1f3cd2a..b14f3d2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,11 +1,8 @@
ACLOCAL_AMFLAGS = -I m4
-# standalone compilation uses stdio
-libmctp_la_CPPFLAGS = -DMCTP_LOG_STDERR -DMCTP_FILEIO
-
lib_LTLIBRARIES = libmctp.la
-libmctp_la_SOURCES = core.c alloc.c \
- libmctp.h libmctp-alloc.h
+libmctp_la_SOURCES = core.c alloc.c log.c \
+ libmctp.h libmctp-alloc.h libmctp-log.h
if LIBMCTP_BINDING_serial
libmctp_la_SOURCES += serial.c libmctp-serial.h
diff --git a/Makefile.inc b/Makefile.inc
index fd63032..1ee555d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -1,5 +1,5 @@
LIBMCTP_DIR ?= libmctp/
-LIBMCTP_OBJS = core.o alloc.o
+LIBMCTP_OBJS = core.o alloc.o log.o
LIBMCTP_BINDINGS ?= serial astlpc
LIBMCTP_OBJS += $(LIBMCTP_BINDINGS:%=%.o)
diff --git a/README.md b/README.md
index 80b0150..ab89bbf 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@
The libmctp code is intended to be integrated into other codebases by two
methods:
- 1. as a simple library (`libmctp.a`), which can be compiled separately
+ 1. as a simple library (`libmctp.{a,so}`) which can be compiled separately
and linked into the containing project
2. as a set of sources to be included into the containing project (either
@@ -64,23 +64,16 @@
For the latter, we need to support customisation of the functions that libmctp
uses (for example, POSIX file IO is not available).
-In order to support these, we have a couple of compile-time definitions:
+In order to support these, we have a few compile-time definitions:
- - `MCTP_FILEIO`: define if POSIX file io is available, allowing the
+ - `MCTP_HAVE_FILEIO`: define if POSIX file io is available, allowing the
serial hardware binding to access char devices for IO.
- - `MCTP_LOG_`: allows selection of a logging backend. Currently available
- are:
+ - `MCTP_HAVE_SYSLOG`: allow logging to syslog, through the `vsyslog`
+ call.
- - `MCTP_LOG_STDERR`: use `fprintf(stderr, ...)` for log output
-
- - `MCTP_LOG_SYSLOG`: use `syslog()` for log output
-
- - `MCTP_LOG_CUSTOM`: provide your own macro for logging, of
- the format: ```#define mctp_prlog(level, fmt, ...) (....)```
-
- - `MCTP_NO_DEFAULT_ALLOC`: do not set default allocator functions (malloc,
- free, realloc), and require the use of `mctp_set_alloc_ops`.
+ - `MCTP_DEFAULT_ALLOC`: set default allocator functions (malloc, free,
+ realloc), so that applications do not have to provide their own.
TODO
----
diff --git a/alloc.c b/alloc.c
index db16d84..1e7da5a 100644
--- a/alloc.c
+++ b/alloc.c
@@ -5,12 +5,16 @@
#include "libmctp.h"
#include "libmctp-alloc.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
struct {
void *(*m_alloc)(size_t);
void (*m_free)(void *);
void *(*m_realloc)(void *, size_t);
} alloc_ops = {
-#ifndef MCTP_NO_DEFAULT_ALLOC
+#ifdef MCTP_DEFAULT_ALLOC
malloc,
free,
realloc,
diff --git a/configure.ac b/configure.ac
index 334b0a5..a33d1b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,6 +15,14 @@
# libtool init
LT_INIT
+# Set defaults for standard library compiles. We may want to
+# AC_ARG_WITH these in the future.
+AC_DEFINE([MCTP_HAVE_SYSLOG], [1], [Define to enable syslog])
+AC_DEFINE([MCTP_HAVE_FILEIO], [1], [Define to enable filesystem functions])
+AC_DEFINE([MCTP_DEFAULT_ALLOC], [1],
+ [Define to populate allocation functions to defaults (malloc/free)])
+
+# Enable all bindings. AC_ARG_ENABLE in future.
AM_CONDITIONAL([LIBMCTP_BINDING_serial], [true])
AM_CONDITIONAL([LIBMCTP_BINDING_astlpc], [true])
diff --git a/libmctp-log.h b/libmctp-log.h
index 1024913..001374b 100644
--- a/libmctp-log.h
+++ b/libmctp-log.h
@@ -4,44 +4,18 @@
#define _LIBMCTP_LOG_H
/* libmctp-internal logging */
-#ifndef pr_fmt
-#define pr_fmt
-#endif
-#if defined(MCTP_LOG_STDERR)
+/* these should match the syslog-standard LOG_* definitions, for
+ * easier use with syslog */
+#define MCTP_LOG_ERR 3
+#define MCTP_LOG_WARNING 4
+#define MCTP_LOG_NOTICE 5
+#define MCTP_LOG_INFO 6
+#define MCTP_LOG_DEBUG 7
-#include <stdio.h>
-
-#define MCTP_LOG_ERR 0
-#define MCTP_LOG_WARNING 0
-#define MCTP_LOG_NOTICE 0
-#define MCTP_LOG_INFO 0
-#define MCTP_LOG_DEBUG 0
-
-#define mctp_prlog(x, fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
-
-#elif defined(MCTP_LOG_SYSLOG)
-
-#include <syslog.h>
-
-#define MCTP_LOG_ERR LOG_ERR
-#define MCTP_LOG_WARNING LOG_WARNING
-#define MCTP_LOG_NOTICE LOG_NOTICE
-#define MCTP_LOG_INFO LOG_INFO
-#define MCTP_LOG_DEBUG LOG_DEBUG
-
-#define mctp_prlog(x, fmt, ...) syslog(x, fmt, ##__VA_ARGS__)
-
-#elif defined(MCTP_LOG_CUSTOM)
-
-extern void mctp_prlog(int level, const char *fmt, ...)
+void mctp_prlog(int level, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
-
-#else
-#error No log implementation found
-#endif
-
#define mctp_prerr(fmt, ...) mctp_prlog(MCTP_LOG_ERR, fmt, ##__VA_ARGS__)
#define mctp_prwarn(fmt, ...) mctp_prlog(MCTP_LOG_WARNING, fmt, ##__VA_ARGS__)
#define mctp_prinfo(fmt, ...) mctp_prlog(MCTP_LOG_INFO, fmt, ##__VA_ARGS__)
diff --git a/libmctp.h b/libmctp.h
index 5c0c9f4..e3a125c 100644
--- a/libmctp.h
+++ b/libmctp.h
@@ -7,6 +7,7 @@
extern "C" {
#endif
+#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
@@ -102,6 +103,11 @@
void (*free)(void *),
void *(realloc)(void *, size_t));
+/* environment-specific logging */
+void mctp_set_log_stdio(int level);
+void mctp_set_log_syslog(void);
+void mctp_set_log_custom(void (*fn)(int, const char *, va_list));
+
#ifdef __cplusplus
}
diff --git a/log.c b/log.c
new file mode 100644
index 0000000..12662a3
--- /dev/null
+++ b/log.c
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "libmctp.h"
+#include "libmctp-log.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef MCTP_HAVE_SYSLOG
+#include <syslog.h>
+#endif
+
+enum {
+ MCTP_LOG_NONE,
+ MCTP_LOG_STDIO,
+ MCTP_LOG_SYSLOG,
+ MCTP_LOG_CUSTOM,
+} log_type = MCTP_LOG_NONE;
+
+static int log_stdio_level;
+static void (*log_custom_fn)(int, const char *, va_list);
+
+void mctp_prlog(int level, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ switch (log_type) {
+ case MCTP_LOG_NONE:
+ break;
+ case MCTP_LOG_STDIO:
+ if (level <= log_stdio_level) {
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ }
+ break;
+ case MCTP_LOG_SYSLOG:
+#ifdef MCTP_HAVE_SYSLOG
+ vsyslog(level, fmt, ap);
+#endif
+ break;
+ case MCTP_LOG_CUSTOM:
+ log_custom_fn(level, fmt, ap);
+ break;
+ }
+
+ va_end(ap);
+}
+
+void mctp_set_log_stdio(int level)
+{
+ log_type = MCTP_LOG_STDIO;
+ log_stdio_level = level;
+}
+
+void mctp_set_log_syslog(void)
+{
+ log_type = MCTP_LOG_SYSLOG;
+}
+
+void mctp_set_log_custom(void (*fn)(int, const char *, va_list))
+{
+ log_type = MCTP_LOG_CUSTOM;
+ log_custom_fn = fn;
+}
diff --git a/serial.c b/serial.c
index 22c1b4b..8c5303b 100644
--- a/serial.c
+++ b/serial.c
@@ -6,7 +6,11 @@
#include <string.h>
#include <unistd.h>
-#ifdef MCTP_FILEIO
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef MCTP_HAVE_FILEIO
#include <fcntl.h>
#endif
@@ -243,7 +247,7 @@
mctp_rx_consume_one(serial, *(uint8_t *)(buf + i));
}
-#ifdef MCTP_FILEIO
+#ifdef MCTP_HAVE_FILEIO
int mctp_serial_read(struct mctp_binding_serial *serial)
{
ssize_t len;