On Fri, Feb 14, 2014 at 10:16:02AM +1000, Peter Hutterer wrote: > The previous log handler wasn't actually hooked up to anything. Add a public > API for the log handler with priority filtering, defaulting to priority > 'error' and stderr as output stream. > > And to keep the diff down and convenience up, provide a few simple wrappers > for logging. The generic is log_msg(), but let's use log_info, log_error, etc. > > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
Looks good to me. Reviewed-by: Jonas Ådahl <jad...@gmail.com> > --- > src/libinput-private.h | 7 ++ > src/libinput-util.c | 20 ------ > src/libinput.c | 62 ++++++++++++++++++ > src/libinput.h | 76 ++++++++++++++++++++++ > src/path.c | 4 +- > test/Makefile.am | 7 +- > test/log.c | 169 > +++++++++++++++++++++++++++++++++++++++++++++++++ > 7 files changed, 322 insertions(+), 23 deletions(-) > create mode 100644 test/log.c > > diff --git a/src/libinput-private.h b/src/libinput-private.h > index 0d7de90..1fff7de 100644 > --- a/src/libinput-private.h > +++ b/src/libinput-private.h > @@ -74,6 +74,13 @@ typedef void (*libinput_source_dispatch_t)(void *data); > > struct libinput_source; > > +#define log_debug(...) log_msg(LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__) > +#define log_info(...) log_msg(LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__) > +#define log_error(...) log_msg(LIBINPUT_LOG_PRIORITY_ERROR, __VA_ARGS__) > + > +void > +log_msg(enum libinput_log_priority priority, const char *format, ...); > + > int > libinput_init(struct libinput *libinput, > const struct libinput_interface *interface, > diff --git a/src/libinput-util.c b/src/libinput-util.c > index a3534e1..eeb9786 100644 > --- a/src/libinput-util.c > +++ b/src/libinput-util.c > @@ -35,26 +35,6 @@ > #include "libinput-util.h" > #include "libinput-private.h" > > -static FILE *g_log_file = NULL; > - > -void > -set_logging_enabled(int enabled) > -{ > - g_log_file = enabled ? stdout : NULL; > -} > - > -void > -log_info(const char *format, ...) > -{ > - va_list ap; > - > - if (g_log_file) { > - va_start(ap, format); > - vfprintf(g_log_file, format, ap); > - va_end(ap); > - } > -} > - > void > list_init(struct list *list) > { > diff --git a/src/libinput.c b/src/libinput.c > index cfce2c5..b4879af 100644 > --- a/src/libinput.c > +++ b/src/libinput.c > @@ -78,6 +78,68 @@ struct libinput_event_touch { > }; > > static void > +libinput_default_log_func(enum libinput_log_priority priority, > + void *data, > + const char *format, va_list args) > +{ > + const char *prefix; > + > + switch(priority) { > + case LIBINPUT_LOG_PRIORITY_DEBUG: prefix = "debug"; break; > + case LIBINPUT_LOG_PRIORITY_INFO: prefix = "info"; break; > + case LIBINPUT_LOG_PRIORITY_ERROR: prefix = "error"; break; > + default: prefix="<invalid priority>"; break; > + } > + > + fprintf(stderr, "libinput %s: ", prefix); > + vfprintf(stderr, format, args); > +} > + > +struct log_data { > + enum libinput_log_priority priority; > + libinput_log_handler handler; > + void *user_data; > +}; > + > +static struct log_data log_data = { > + .priority = LIBINPUT_LOG_PRIORITY_ERROR, > + .handler = libinput_default_log_func, > + .user_data = NULL, > +}; > + > +void > +log_msg(enum libinput_log_priority priority, const char *format, ...) > +{ > + va_list args; > + > + if (log_data.handler && log_data.priority <= priority) { > + va_start(args, format); > + log_data.handler(priority, log_data.user_data, format, args); > + va_end(args); > + } > +} > + > +LIBINPUT_EXPORT void > +libinput_log_set_priority(enum libinput_log_priority priority) > +{ > + log_data.priority = priority; > +} > + > +LIBINPUT_EXPORT enum libinput_log_priority > +libinput_log_get_priority(void) > +{ > + return log_data.priority; > +} > + > +LIBINPUT_EXPORT void > +libinput_log_set_handler(libinput_log_handler log_handler, > + void *user_data) > +{ > + log_data.handler = log_handler; > + log_data.user_data = user_data; > +} > + > +static void > libinput_post_event(struct libinput *libinput, > struct libinput_event *event); > > diff --git a/src/libinput.h b/src/libinput.h > index e87b2b7..6bf538a 100644 > --- a/src/libinput.h > +++ b/src/libinput.h > @@ -42,6 +42,15 @@ > typedef int32_t li_fixed_t; > > /** > + * Log priority for internal logging messages. > + */ > +enum libinput_log_priority { > + LIBINPUT_LOG_PRIORITY_DEBUG = 10, > + LIBINPUT_LOG_PRIORITY_INFO = 20, > + LIBINPUT_LOG_PRIORITY_ERROR = 30, > +}; > + > +/** > * @ingroup device > * > * Capabilities on a device. A device may have one or more capabilities > @@ -875,6 +884,73 @@ void > libinput_destroy(struct libinput *libinput); > > /** > + * @ingroup base > + * > + * Set the global log priority. Messages with priorities equal to or > + * higher than the argument will be printed to the current log handler. > + * > + * The default log priority is LIBINPUT_LOG_PRIORITY_ERROR. > + * > + * @param priority The minimum priority of log messages to print. > + * > + * @see libinput_log_set_handler > + */ > +void > +libinput_log_set_priority(enum libinput_log_priority priority); > + > +/** > + * @ingroup base > + * > + * Get the global log priority. Messages with priorities equal to or > + * higher than the argument will be printed to the current log handler. > + * > + * The default log priority is LIBINPUT_LOG_PRIORITY_ERROR. > + * > + * @return The minimum priority of log messages to print. > + * > + * @see libinput_log_set_handler > + */ > +enum libinput_log_priority > +libinput_log_get_priority(void); > + > +/** > + * @ingroup base > + * > + * Log handler type for custom logging. > + * > + * @param priority The priority of the current message > + * @param user_data Caller-specific data pointer as previously passed into > + * libinput_log_set_handler() > + * @param format Message format in printf-style > + * @param args Message arguments > + * > + * @see libinput_set_log_priority > + * @see libinput_log_set_handler > + */ > +typedef void (*libinput_log_handler)(enum libinput_log_priority priority, > + void *user_data, > + const char *format, va_list args); > + > +/** > + * @ingroup base > + * > + * Set the global log handler. Messages with priorities equal to or higher > + * than the current log priority will be passed to the given > + * log handler. > + * > + * The default log handler prints to stderr. > + * > + * @param log_handler The log handler for library messages. > + * @param user_data Caller-specific data pointer, passed into the log > + * handler. > + * > + * @see libinput_log_set_handler > + */ > +void > +libinput_log_set_handler(libinput_log_handler log_handler, > + void *user_data); > + > +/** > * @defgroup seat Initialization and manipulation of seats > * > * A seat has two identifiers, the physical name and the logical name. The > diff --git a/src/path.c b/src/path.c > index 31a916a..f7b6a61 100644 > --- a/src/path.c > +++ b/src/path.c > @@ -273,7 +273,7 @@ libinput_path_add_device(struct libinput *libinput, > struct libinput_device *device; > > if (libinput->interface_backend != &interface_backend) { > - log_info("Mismatching backends. This is an application bug.\n"); > + log_error("Mismatching backends. This is an application > bug.\n"); > return NULL; > } > > @@ -310,7 +310,7 @@ libinput_path_remove_device(struct libinput_device > *device) > struct path_device *dev; > > if (libinput->interface_backend != &interface_backend) { > - log_info("Mismatching backends. This is an application bug.\n"); > + log_error("Mismatching backends. This is an application > bug.\n"); > return; > } > > diff --git a/test/Makefile.am b/test/Makefile.am > index 59687f6..11df4f8 100644 > --- a/test/Makefile.am > +++ b/test/Makefile.am > @@ -16,7 +16,7 @@ liblitest_la_SOURCES = \ > litest-wacom-touch.c \ > litest.c > > -run_tests = test-udev test-path test-pointer test-touch > +run_tests = test-udev test-path test-pointer test-touch test-log > build_tests = test-build-linker test-build-pedantic-c99 test-build-std-gnuc90 > > noinst_PROGRAMS = $(build_tests) $(run_tests) > @@ -42,6 +42,11 @@ test_touch_CFLAGS = $(AM_CPPFLAGS) > test_touch_LDADD = $(TEST_LIBS) > test_touch_LDFLAGS = -static > > +test_log_SOURCES = log.c > +test_log_CFLAGS = $(AM_CPPFLAGS) > +test_log_LDADD = $(TEST_LIBS) > +test_log_LDFLAGS = -static > + > # build-test only > test_build_pedantic_c99_SOURCES = build-pedantic.c > test_build_pedantic_c99_CFLAGS = $(AM_CPPFLAGS) -std=c99 -pedantic -Werror > diff --git a/test/log.c b/test/log.c > new file mode 100644 > index 0000000..bdd99df > --- /dev/null > +++ b/test/log.c > @@ -0,0 +1,169 @@ > +/* > + * Copyright © 2014 Red Hat, Inc. > + * > + * Permission to use, copy, modify, distribute, and sell this software and > + * its documentation for any purpose is hereby granted without fee, provided > + * that the above copyright notice appear in all copies and that both that > + * copyright notice and this permission notice appear in supporting > + * documentation, and that the name of the copyright holders not be used in > + * advertising or publicity pertaining to distribution of the software > + * without specific, written prior permission. The copyright holders make > + * no representations about the suitability of this software for any > + * purpose. It is provided "as is" without express or implied warranty. > + * > + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS > + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND > + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY > + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER > + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF > + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN > + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <config.h> > + > +#include <check.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <libinput.h> > +#include <libudev.h> > +#include <unistd.h> > + > +#include "litest.h" > + > +static int log_handler_called; > +static void *log_handler_userdata; > + > +static int open_restricted(const char *path, int flags, void *data) > +{ > + int fd; > + fd = open(path, flags); > + return fd < 0 ? -errno : fd; > +} > +static void close_restricted(int fd, void *data) > +{ > + close(fd); > +} > + > +const struct libinput_interface simple_interface = { > + .open_restricted = open_restricted, > + .close_restricted = close_restricted, > +}; > + > +static void > +simple_log_handler(enum libinput_log_priority priority, > + void *userdata, > + const char *format, > + va_list args) > +{ > + log_handler_called++; > + ck_assert(userdata == log_handler_userdata); > + ck_assert(format != NULL); > +} > + > +START_TEST(log_default_priority) > +{ > + enum libinput_log_priority pri; > + > + pri = libinput_log_get_priority(); > + > + ck_assert_int_eq(pri, LIBINPUT_LOG_PRIORITY_ERROR); > +} > +END_TEST > + > +START_TEST(log_handler_invoked) > +{ > + struct libinput *li; > + > + libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); > + libinput_log_set_handler(simple_log_handler, NULL); > + log_handler_userdata = NULL; > + > + li = libinput_path_create_context(&simple_interface, NULL); > + libinput_path_add_device(li, "/tmp"); > + > + ck_assert_int_gt(log_handler_called, 0); > + log_handler_called = 0; > +} > +END_TEST > + > +START_TEST(log_userdata_NULL) > +{ > + struct libinput *li; > + > + libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); > + libinput_log_set_handler(simple_log_handler, NULL); > + log_handler_userdata = NULL; > + > + li = libinput_path_create_context(&simple_interface, NULL); > + libinput_path_add_device(li, "/tmp"); > + > + ck_assert_int_gt(log_handler_called, 0); > + log_handler_called = 0; > +} > +END_TEST > + > +START_TEST(log_userdata) > +{ > + struct libinput *li; > + > + libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); > + libinput_log_set_handler(simple_log_handler, &li); > + log_handler_userdata = &li; > + > + li = libinput_path_create_context(&simple_interface, NULL); > + libinput_path_add_device(li, "/tmp"); > + > + ck_assert_int_gt(log_handler_called, 0); > + log_handler_called = 0; > +} > +END_TEST > + > +START_TEST(log_handler_NULL) > +{ > + struct libinput *li; > + > + libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); > + libinput_log_set_handler(NULL, NULL); > + log_handler_userdata = NULL; > + > + li = libinput_path_create_context(&simple_interface, NULL); > + libinput_path_add_device(li, "/tmp"); > + > + ck_assert_int_eq(log_handler_called, 0); > + log_handler_called = 0; > + libinput_log_set_handler(simple_log_handler, NULL); > +} > +END_TEST > + > +START_TEST(log_priority) > +{ > + struct libinput *li; > + > + libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_ERROR); > + libinput_log_set_handler(simple_log_handler, NULL); > + log_handler_userdata = NULL; > + > + li = libinput_path_create_context(&simple_interface, NULL); > + libinput_path_add_device(li, "/tmp"); > + > + ck_assert_int_eq(log_handler_called, 0); > + > + libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_INFO); > + libinput_path_add_device(li, "/tmp"); > + ck_assert_int_gt(log_handler_called, 0); > + > + log_handler_called = 0; > +} > +END_TEST > + > +int main (int argc, char **argv) { > + litest_add_no_device("log:defaults", log_default_priority); > + litest_add_no_device("log:logging", log_handler_invoked); > + litest_add_no_device("log:logging", log_handler_NULL); > + litest_add_no_device("log:logging", log_userdata); > + litest_add_no_device("log:logging", log_userdata_NULL); > + litest_add_no_device("log:logging", log_priority); > + > + return litest_run(argc, argv); > +} > -- > 1.8.4.2 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel