[PATCH libevdev 5/9] Drop per-device logging function, use per-library one instead

Peter Hutterer peter.hutterer at who-t.net
Tue Sep 3 00:07:43 PDT 2013


There's no need to have separate logging function for each device created.
More likely, libevdev will be hooked up once into the logging system and
expected to deal with it.

Plus, this allows us to log from the uinput code where we don't
have the context anyway.

Requires a rename to libevdev_set_log_function to avoid ABI breaks, and
while we're breaking the ABI make the logging function more sophisticated
to log line, number, etc.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 libevdev/libevdev-int.h   | 27 +++++++++++++++++++++--
 libevdev/libevdev.c       | 56 +++++++++++++++++++++++++++++++++++++----------
 libevdev/libevdev.h       | 40 +++++++++++++++++++++++++++++----
 test/test-libevdev-init.c | 15 ++++++++-----
 4 files changed, 115 insertions(+), 23 deletions(-)

diff --git a/libevdev/libevdev-int.h b/libevdev/libevdev-int.h
index dd38cc8..e77db32 100644
--- a/libevdev/libevdev-int.h
+++ b/libevdev/libevdev-int.h
@@ -38,6 +38,7 @@
 #define ABS_MT_MAX ABS_MT_TOOL_Y
 #define ABS_MT_CNT (ABS_MT_MAX - ABS_MT_MIN + 1)
 #define LIBEVDEV_EXPORT __attribute__((visibility("default")))
+#define LIBEVDEV_PRINTF(_format, _args) __attribute__ ((format (printf, _format, _args)))
 
 #undef min
 #undef max
@@ -71,8 +72,6 @@ enum SyncState {
 
 struct libevdev {
 	int fd;
-	libevdev_log_func_t log;
-
 	char *name;
 	char *phys;
 	char *uniq;
@@ -109,6 +108,30 @@ struct libevdev {
 	struct timeval last_event_time;
 };
 
+struct logdata {
+	enum libevdev_log_priority priority;	/** minimum logging priority */
+	libevdev_log_func_t handler;		/** handler function */
+	void *userdata;				/** user-defined data pointer */
+};
+extern struct logdata log_data;
+
+#define log_msg_cond(priority, ...) \
+	do { \
+		if (libevdev_get_log_priority() >= priority) \
+			log_msg(priority, log_data.userdata, __FILE__, __LINE__, __func__, __VA_ARGS__); \
+	} while(0)
+
+#define log_error(...) log_msg_cond(LIBEVDEV_LOG_ERROR, __VA_ARGS__)
+#define log_info(...) log_msg_cond(LIBEVDEV_LOG_INFO, __VA_ARGS__)
+#define log_dbg(...) log_msg_cond(LIBEVDEV_LOG_DEBUG, __VA_ARGS__)
+#define log_bug(...) log_msg_cond(LIBEVDEV_LOG_ERROR, "BUG: "__VA_ARGS__)
+
+extern void
+log_msg(enum libevdev_log_priority priority,
+	void *data,
+	const char *file, int line, const char *func,
+	const char *format, ...) LIBEVDEV_PRINTF(6, 7);
+
 /**
  * @return a pointer to the next element in the queue, or NULL if the queue
  * is full.
diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
index 867e008..ff1fd07 100644
--- a/libevdev/libevdev.c
+++ b/libevdev/libevdev.c
@@ -49,20 +49,35 @@ init_event_queue(struct libevdev *dev)
 }
 
 static void
-_libevdev_log(struct libevdev *dev, const char *format, ...)
+libevdev_noop_log_func(enum libevdev_log_priority priority,
+		       void *data,
+		       const char *file, int line, const char *func,
+		       const char *format, va_list args)
+{
+}
+
+/*
+ * Global logging settings.
+ */
+struct logdata log_data = {
+	LIBEVDEV_LOG_INFO,
+	libevdev_noop_log_func,
+	NULL,
+};
+
+void
+log_msg(enum libevdev_log_priority priority,
+	void *data,
+	const char *file, int line, const char *func,
+	const char *format, ...)
 {
 	va_list args;
 
 	va_start(args, format);
-	dev->log(format, args);
+	log_data.handler(priority, data, file, line, func, format, args);
 	va_end(args);
 }
 
-static void
-libevdev_noop_log_func(const char *format, va_list args)
-{
-}
-
 LIBEVDEV_EXPORT struct libevdev*
 libevdev_new(void)
 {
@@ -74,7 +89,6 @@ libevdev_new(void)
 	dev->fd = -1;
 	dev->num_slots = -1;
 	dev->current_slot = -1;
-	dev->log = libevdev_noop_log_func;
 	dev->grabbed = LIBEVDEV_UNGRAB;
 	dev->sync_state = SYNC_NONE;
 
@@ -112,13 +126,33 @@ libevdev_free(struct libevdev *dev)
 	free(dev);
 }
 
+/* DEPRECATED */
 LIBEVDEV_EXPORT void
 libevdev_set_log_handler(struct libevdev *dev, libevdev_log_func_t logfunc)
 {
-	if (dev == NULL)
-		return;
+	/* Can't be backwards compatible to this yet, so don't even try */
+	fprintf(stderr, "libevdev: ABI change. Log function will not be honored.\n");
+}
 
-	dev->log = logfunc ? logfunc : libevdev_noop_log_func;
+LIBEVDEV_EXPORT void
+libevdev_set_log_function(libevdev_log_func_t logfunc, void *data)
+{
+	log_data.handler = logfunc ? logfunc : libevdev_noop_log_func;
+	log_data.userdata = data;
+}
+
+LIBEVDEV_EXPORT void
+libevdev_set_log_priority(enum libevdev_log_priority priority)
+{
+	if (priority > LIBEVDEV_LOG_DEBUG)
+		priority = LIBEVDEV_LOG_DEBUG;
+	log_data.priority = priority;
+}
+
+LIBEVDEV_EXPORT enum libevdev_log_priority
+libevdev_get_log_priority(void)
+{
+	return log_data.priority;
 }
 
 LIBEVDEV_EXPORT int
diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
index 43b768d..36ecdd1 100644
--- a/libevdev/libevdev.h
+++ b/libevdev/libevdev.h
@@ -349,28 +349,58 @@ int libevdev_new_from_fd(int fd, struct libevdev **dev);
  */
 void libevdev_free(struct libevdev *dev);
 
+enum libevdev_log_priority {
+	LIBEVDEV_LOG_ERROR = 10,	/** cricitical errors and application bugs */
+	LIBEVDEV_LOG_INFO  = 20,	/** informational messages */
+	LIBEVDEV_LOG_DEBUG = 30,	/** debug information */
+};
+
 /**
  * Logging function called by library-internal logging.
  * This function is expected to treat it's input like printf would.
  *
+ * @param priority Log priority of this message
+ * @param data User-supplied data pointer (see libevdev_set_log_function())
+ * @param file libevdev source code file generating this message
+ * @param line libevdev source code line generating this message
+ * @param func libevdev source code function generating this message
  * @param format printf-style format string
  * @param args List of arguments
  *
- * @see libevdev_set_log_handler
+ * @see libevdev_set_log_function
  */
-typedef void (*libevdev_log_func_t)(const char *format, va_list args);
+typedef void (*libevdev_log_func_t)(enum libevdev_log_priority priority,
+				    void *data,
+				    const char *file, int line,
+				    const char *func,
+				    const char *format, va_list args);
 
 /**
  * Set a printf-style logging handler for library-internal logging. The default
  * logging function is a noop.
  *
- * @param dev The evdev device
  * @param logfunc The logging function for this device. If NULL, the current
  * logging function is unset.
+ * @param data User-specific data passed to the log handler.
  *
  * @note This function may be called before libevdev_set_fd().
  */
-void libevdev_set_log_handler(struct libevdev *dev, libevdev_log_func_t logfunc);
+void libevdev_set_log_function(libevdev_log_func_t logfunc, void *data);
+
+/**
+ * Define the minimum level to be printed to the log handler.
+ * Messages higher than this level are printed, others are discarded. This
+ * is a global setting and applies to any future logging messages.
+ *
+ * @param priority Minimum priority to be printed to the log.
+ *
+ */
+void libevdev_set_log_priority(enum libevdev_log_priority priority);
+
+/**
+ * @return the current log level
+ */
+enum libevdev_log_priority libevdev_get_log_priority(void);
 
 
 enum libevdev_grab_mode {
@@ -1333,6 +1363,8 @@ int libevdev_get_repeat(struct libevdev *dev, int *delay, int *period);
 /* replacement: libevdev_kernel_set_abs_info */
 int libevdev_kernel_set_abs_value(struct libevdev *dev, unsigned int code, const struct input_absinfo *abs) LIBEVDEV_DEPRECATED;
 
+/* replacement: libevdev_set_log_function */
+void libevdev_set_log_handler(struct libevdev *dev, libevdev_log_func_t logfunc) LIBEVDEV_DEPRECATED;
 /**************************************/
 
 #ifdef __cplusplus
diff --git a/test/test-libevdev-init.c b/test/test-libevdev-init.c
index 344bbac..8f1d0d1 100644
--- a/test/test-libevdev-init.c
+++ b/test/test-libevdev-init.c
@@ -93,24 +93,27 @@ START_TEST(test_init_and_change_fd)
 }
 END_TEST
 
-static void logfunc(const char *f, va_list args) {}
+static void logfunc(enum libevdev_log_priority priority,
+		    void *data,
+		    const char *file, int line, const char *func,
+		    const char *f, va_list args) {}
 
 START_TEST(test_log_init)
 {
 	struct libevdev *dev = NULL;
 
-	libevdev_set_log_handler(NULL, logfunc);
-	libevdev_set_log_handler(NULL, NULL);
+	libevdev_set_log_function(logfunc, NULL);
+	libevdev_set_log_function(NULL, NULL);
 
 	dev = libevdev_new();
 	ck_assert(dev != NULL);
-	libevdev_set_log_handler(dev, logfunc);
+	libevdev_set_log_function(logfunc, NULL);
 	libevdev_free(dev);
 
 	dev = libevdev_new();
 	ck_assert(dev != NULL);
-	libevdev_set_log_handler(dev, NULL);
-	libevdev_set_log_handler(dev, logfunc);
+	libevdev_set_log_function(NULL, NULL);
+	libevdev_set_log_function(logfunc, NULL);
 	libevdev_free(dev);
 	/* well, we didn't crash. can't test this otherwise */
 
-- 
1.8.2.1



More information about the Input-tools mailing list