summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Schink <swo-dev@marcschink.de>2017-03-12 12:28:08 +0100
committerMarc Schink <swo-dev@marcschink.de>2017-03-12 22:55:48 +0100
commitcd137376eb15886c7989d87b0318f86d54f352e2 (patch)
tree397dc5308b014f796548751718464283042a6334
parent061cee89b5a84ec94eb7187aa8473accbb1912fb (diff)
Add option to set log level
-rw-r--r--man/swodec.129
-rw-r--r--src/main.c93
2 files changed, 118 insertions, 4 deletions
diff --git a/man/swodec.1 b/man/swodec.1
index 01ca776..d9e39c4 100644
--- a/man/swodec.1
+++ b/man/swodec.1
@@ -1,4 +1,4 @@
-.TH swodec 1 "Dec 23, 2015"
+.TH swodec 1 "Mar 12, 2017"
.SH NAME
swodec \- decode SWO trace data
@@ -19,6 +19,33 @@ Show a help text and exit.
Show version information and exit.
.TP
+.B \-l, \-\-log\-level
+Set the log level of \fBswodec\fP and \fBlibswo\fP. The following log levels
+are available:
+
+.RS
+.RS
+.TP
+.B none (0)
+No messages
+.TP
+.B error (1)
+Error messages
+.TP
+.B warn (2)
+Warning messages
+.TP
+.B info (3)
+Informational messages
+.TP
+.B debug (4)
+Debug messages
+.RE
+
+The name or its correspoding number can be used to specify a log level.
+.RE
+
+.TP
.BR "\-i, \-\-input\-file " <filename>
Load trace data from a file instead of using standard input.
diff --git a/src/main.c b/src/main.c
index 8479a09..a9bec50 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@
#include <stdint.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <glib.h>
#include <libswo/libswo.h>
@@ -60,6 +61,7 @@ static const char *exception_names[] = {
#define BUFFER_SIZE 1024
static gboolean opt_version;
+static enum libswo_log_level opt_log_level;
static gchar *input_file = NULL;
static uint32_t packet_type_filter;
static uint32_t inst_address_filter;
@@ -233,9 +235,47 @@ static gboolean parse_inst_filter_option(const gchar *option_name,
return TRUE;
}
+static gboolean parse_log_level_option(const gchar *option_name,
+ const gchar *value, gpointer data, GError **error)
+{
+ uint64_t tmp;
+ gchar *endptr;
+
+ (void)option_name;
+ (void)data;
+ (void)error;
+
+ if (!g_ascii_strcasecmp(value, "none")) {
+ opt_log_level = LIBSWO_LOG_LEVEL_NONE;
+ } else if (!g_ascii_strcasecmp(value, "error")) {
+ opt_log_level = LIBSWO_LOG_LEVEL_ERROR;
+ } else if (!g_ascii_strcasecmp(value, "warn")) {
+ opt_log_level = LIBSWO_LOG_LEVEL_WARNING;
+ } else if (!g_ascii_strcasecmp(value, "info")) {
+ opt_log_level = LIBSWO_LOG_LEVEL_INFO;
+ } else if (!g_ascii_strcasecmp(value, "debug")) {
+ opt_log_level = LIBSWO_LOG_LEVEL_DEBUG;
+ } else {
+ errno = 0;
+ tmp = g_ascii_strtoull(value, &endptr, 10);
+
+ if (*endptr != '\0' || errno != 0 ||
+ tmp > LIBSWO_LOG_LEVEL_DEBUG) {
+ g_critical("Invalid log level: %s.", value);
+ return FALSE;
+ }
+
+ opt_log_level = tmp;
+ }
+
+ return TRUE;
+}
+
static GOptionEntry entries[] = {
{"version", 'V', 0, G_OPTION_ARG_NONE, &opt_version,
"Show version information", NULL},
+ {"log-level", 'l', 0, G_OPTION_ARG_CALLBACK, &parse_log_level_option,
+ "Log level", NULL},
{"input-file", 'i', 0, G_OPTION_ARG_FILENAME, &input_file,
"Load trace data from file", NULL},
{"filter", 'f', 0, G_OPTION_ARG_CALLBACK, &parse_filter_option,
@@ -515,14 +555,50 @@ static int parse_options(int *argc, char ***argv)
static void log_handler(const gchar *domain, GLogLevelFlags level,
const gchar *message, gpointer user_data)
{
+ enum libswo_log_level tmp;
+
(void)domain;
- (void)level;
(void)user_data;
+ if (level & G_LOG_LEVEL_ERROR)
+ tmp = LIBSWO_LOG_LEVEL_ERROR;
+ else if (level & G_LOG_LEVEL_CRITICAL)
+ tmp = LIBSWO_LOG_LEVEL_ERROR;
+ else if (level & G_LOG_LEVEL_WARNING)
+ tmp = LIBSWO_LOG_LEVEL_WARNING;
+ else if (level & G_LOG_LEVEL_MESSAGE)
+ tmp = LIBSWO_LOG_LEVEL_INFO;
+ else if (level & G_LOG_LEVEL_INFO)
+ tmp = LIBSWO_LOG_LEVEL_INFO;
+ else if (level & G_LOG_LEVEL_DEBUG)
+ tmp = LIBSWO_LOG_LEVEL_DEBUG;
+ else
+ tmp = LIBSWO_LOG_LEVEL_WARNING;
+
+ if (tmp > opt_log_level)
+ return;
+
fprintf(stderr, "%s\n", message);
fflush(stderr);
}
+static int decoder_log_callback(struct libswo_context *ctx,
+ enum libswo_log_level level, const char *format, va_list args,
+ void *user_data)
+{
+ (void)ctx;
+ (void)user_data;
+
+ if (level > opt_log_level)
+ return 0;
+
+ fprintf(stderr, "libswo: ");
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
int ret;
@@ -533,11 +609,12 @@ int main(int argc, char **argv)
GIOStatus iostat;
gsize num;
- g_log_set_default_handler(&log_handler, NULL);
-
opt_version = FALSE;
+ opt_log_level = LIBSWO_LOG_LEVEL_WARNING;
opt_dump_inst = FALSE;
+ g_log_set_default_handler(&log_handler, NULL);
+
/* Disable packet filtering for all packet types by default. */
packet_type_filter = (1 << LIBSWO_PACKET_TYPE_UNKNOWN) | \
(1 << LIBSWO_PACKET_TYPE_SYNC) | \
@@ -617,6 +694,16 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
+ ret = libswo_log_set_callback(ctx, &decoder_log_callback, NULL);
+
+ if (ret != LIBSWO_OK) {
+ g_critical("libswo_log_set_callback() failed: %s.",
+ libswo_strerror_name(ret));
+ g_io_channel_unref(input);
+ libswo_exit(ctx);
+ return EXIT_FAILURE;
+ }
+
while (TRUE) {
iostat = g_io_channel_read_chars(input, (gchar *)buffer,
BUFFER_SIZE, &num, &error);