summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--COPYING19
-rw-r--r--Makefile55
-rw-r--r--README40
-rw-r--r--include/nslog/nslog.h108
-rw-r--r--libnslog.pc.in10
-rw-r--r--src/Makefile3
-rw-r--r--src/core.c150
-rw-r--r--test/Makefile3
-rw-r--r--test/basic.c33
-rwxr-xr-xtest/runtest.sh12
11 files changed, 435 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8039af5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*~
+build-*
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..0bedd97
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,19 @@
+Copyright 2014 Vincent Sanders <vince@netsurf-browser.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..184f9d4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,55 @@
+#!/bin/make
+#
+# Makefile for libnslog
+#
+# Copyright 2014-1015 Vincent Sanders <vince@netsurf-browser.org>
+# Copyright 2017 Daniel Silverstone <dsilvers@netsurf-browser.org>
+
+# Component settings
+COMPONENT := nslog
+COMPONENT_VERSION := 0.0.0
+# Default to a static library
+COMPONENT_TYPE ?= lib-static
+
+# Setup the tooling
+PREFIX ?= /opt/netsurf
+NSSHARED ?= $(PREFIX)/share/netsurf-buildsystem
+include $(NSSHARED)/makefiles/Makefile.tools
+
+# Reevaluate when used, as BUILDDIR won't be defined yet
+TESTRUNNER = test/runtest.sh $(BUILDDIR) $(EXEEXT)
+
+# Toolchain flags
+WARNFLAGS := -Wall -W -Wundef -Wpointer-arith -Wcast-align \
+ -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \
+ -Wmissing-declarations -Wnested-externs
+
+CFLAGS := -D_GNU_SOURCE -D_DEFAULT_SOURCE \
+ -I$(CURDIR)/include/ -I$(CURDIR)/src $(WARNFLAGS) $(CFLAGS)
+ifneq ($(GCCVER),2)
+ CFLAGS := $(CFLAGS) -std=c99
+else
+ # __inline__ is a GCCism
+ CFLAGS := $(CFLAGS) -Dinline="__inline__"
+endif
+CFLAGS := $(CFLAGS) -D_POSIX_C_SOURCE=200809L
+
+REQUIRED_LIBS := nslog
+
+# Strictly the requirement for rt is dependant on both the clib and if
+# the build is using rt features like clock_gettime() but this check
+# will suffice
+ifeq ($(HOST),x86_64-linux-gnu)
+ REQUIRED_LIBS := $(REQUIRED_LIBS) rt
+endif
+
+TESTCFLAGS := -g -O2
+TESTLDFLAGS := -lm -l$(COMPONENT) $(TESTLDFLAGS)
+
+include $(NSBUILD)/Makefile.top
+
+# Extra installation rules
+I := /$(INCLUDEDIR)/nslog
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/nslog/nslog.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR)/pkgconfig:lib$(COMPONENT).pc.in
+INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR):$(OUTPUT)
diff --git a/README b/README
new file mode 100644
index 0000000..45e0a12
--- /dev/null
+++ b/README
@@ -0,0 +1,40 @@
+Libnsutils - NetSurf utility functions
+======================================
+
+Overview
+--------
+
+ Libnsutils provides a small number of useful utility routines which
+ require platform-specific implementations.
+
+Requirements
+------------
+
+ Libnsutils requires the following tools:
+
+ + A C99 capable C compiler
+ + GNU make or compatible
+ + Pkg-config
+
+Compilation
+-----------
+
+ If necessary, modify the toolchain settings in the Makefile.
+ Invoke make:
+ $ make
+
+Verification
+------------
+
+ To verify that the library is working, it is necessary to specify a
+ different makefile target than that used for normal compilation, thus:
+
+ $ make test
+
+API documentation
+-----------------
+
+ Currently, there is none. However, the code is well commented and the
+ public API may be found in the "include" directory. The testcase sources
+ may also be of use in working out how to use it.
+
diff --git a/include/nslog/nslog.h b/include/nslog/nslog.h
new file mode 100644
index 0000000..fff31a7
--- /dev/null
+++ b/include/nslog/nslog.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017 Daniel Silverstone <dsilvers@netsurf-browser.org>
+ *
+ * This file is part of libnslog.
+ *
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * NetSurf Logging
+ */
+
+#ifndef NSLOG_NSLOG_H_
+#define NSLOG_NSLOG_H_
+
+typedef enum {
+ NSLOG_LEVEL_DEEPDEBUG = 0,
+ NSLOG_LEVEL_DEBUG = 1,
+ NSLOG_LEVEL_VERBOSE = 2,
+ NSLOG_LEVEL_INFO = 3,
+ NSLOG_LEVEL_WARNING = 4,
+ NSLOG_LEVEL_ERROR = 5,
+ NSLOG_LEVEL_CRITICAL = 6,
+} nslog_level;
+
+const char *nslog_level_name(nslog_level level);
+
+#define NSLOG_LEVEL_DD NSLOG_LEVEL_DEEPDEBUG
+#define NSLOG_LEVEL_CHAT NSLOG_LEVEL_VERBOSE
+#define NSLOG_LEVEL_WARN NSLOG_LEVEL_WARNING
+#define NSLOG_LEVEL_ERR NSLOG_LEVEL_ERROR
+#define NSLOG_LEVEL_CRIT NSLOG_LEVEL_CRITICAL
+
+#ifndef NSLOG_COMPILED_MIN_LEVEL
+#define NSLOG_COMPILED_MIN_LEVEL NSLOG_LEVEL_DEBUG
+#endif
+
+typedef struct nslog_category_s {
+ const char *cat_name;
+ const char *description;
+ struct nslog_category_s *parent;
+ char *name;
+ struct nslog_category_s *next;
+} nslog_category_t;
+
+typedef struct nslog_entry_s {
+ nslog_category_t *category;
+ nslog_level level;
+ const char *filename;
+ const char *funcname;
+ int lineno;
+ char message[0]; /* NUL terminated */
+} nslog_entry_t;
+
+#define NSLOG_DECLARE_CATEGORY(catname) \
+ extern nslog_category_t __nslog_category_##catname
+
+#define NSLOG_DEFINE_CATEGORY(catname, description) \
+ nslog_category_t __nslog_category_##catname = { \
+ #catname, \
+ description, \
+ NULL, \
+ NULL, \
+ NULL, \
+ }
+
+#define NSLOG_DEFINE_SUBCATEGORY(parentcatname, catname, description) \
+ nslog_category_t __nslog_category_##catname = { \
+ #catname, \
+ description, \
+ &__nslog_category_##parentcatname, \
+ NULL, \
+ NULL, \
+ }
+
+#define NSLOG(catname, level, logmsg, args...) \
+ if (NSLOG_LEVEL_##level >= NSLOG_COMPILED_MIN_LEVEL) { \
+ nslog__log(&__nslog_category_##catname, \
+ NSLOG_LEVEL_##level, \
+ __FILE__, \
+ __LINE__, \
+ __PRETTY_FUNCTION__, \
+ logmsg, \
+ ##args); \
+ }
+
+void nslog__log(nslog_category_t *category,
+ nslog_level level,
+ const char *filename,
+ int lineno,
+ const char *funcname,
+ const char *pattern,
+ ...) __attribute__ ((format (printf, 6, 7)));
+
+typedef enum {
+ NSLOG_NO_ERROR = 0,
+ NSLOG_NO_MEMORY = 1,
+} nslog_error;
+
+typedef void (*nslog_callback)(void *context, nslog_entry_t *msg);
+
+nslog_error nslog_set_render_callback(nslog_callback cb, void *context);
+
+nslog_error nslog_uncork(void);
+
+#endif /* NSLOG_NSLOG_H_ */
diff --git a/libnslog.pc.in b/libnslog.pc.in
new file mode 100644
index 0000000..d382216
--- /dev/null
+++ b/libnslog.pc.in
@@ -0,0 +1,10 @@
+prefix=PREFIX
+exec_prefix=${prefix}
+libdir=${exec_prefix}/LIBDIR
+includedir=${prefix}/INCLUDEDIR
+
+Name: libnslog
+Description: NetSurf Logging sublayer
+Version: VERSION
+Libs: -L${libdir} LIBRARIES
+Cflags: -I${includedir}
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..45ecb90
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,3 @@
+DIR_SOURCES := core.c
+
+include $(NSBUILD)/Makefile.subdir
diff --git a/src/core.c b/src/core.c
new file mode 100644
index 0000000..0665195
--- /dev/null
+++ b/src/core.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2017 Daniel Silverstone <dsilvers@netsurf-browser.org>
+ *
+ * This file is part of libnslog.
+ *
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * NetSurf Logging Core
+ */
+
+#include "nslog/nslog.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+static bool nslog__corked = true;
+
+static struct nslog_cork_chain {
+ struct nslog_cork_chain *next;
+ nslog_entry_t *entry;
+} *nslog__cork_chain = NULL;
+
+static nslog_callback nslog__cb = NULL;
+static void *nslog__cb_ctx = NULL;
+
+static nslog_category_t *nslog__all_categories = NULL;
+
+const char *nslog_level_name(nslog_level level)
+{
+ switch (level) {
+ case NSLOG_LEVEL_DEEPDEBUG:
+ return "DEEPDEBUG";
+ case NSLOG_LEVEL_DEBUG:
+ return "DEBUG";
+ case NSLOG_LEVEL_VERBOSE:
+ return "VERBOSE";
+ case NSLOG_LEVEL_INFO:
+ return "INFO";
+ case NSLOG_LEVEL_WARNING:
+ return "WARNING";
+ case NSLOG_LEVEL_ERROR:
+ return "ERROR";
+ case NSLOG_LEVEL_CRITICAL:
+ return "CRITICAL";
+ };
+
+ return "**UNKNOWN**";
+}
+
+
+static void nslog__normalise_category(nslog_category_t *cat)
+{
+ if (cat->parent == NULL) {
+ cat->name = strdup(cat->cat_name);
+ } else {
+ nslog__normalise_category(cat->parent);
+ cat->name = malloc(strlen(cat->parent->name) + strlen(cat->cat_name) + 2);
+ strcpy(cat->name, cat->parent->name);
+ strcat(cat->name, "/");
+ strcat(cat->name, cat->cat_name);
+ cat->next = nslog__all_categories;
+ nslog__all_categories = cat;
+ }
+}
+
+static void nslog__deliver(nslog_entry_t *entry)
+{
+ /* TODO: Add filtering here */
+ if (nslog__cb != NULL) {
+ if (entry->category->name == NULL) {
+ nslog__normalise_category(entry->category);
+ }
+ (*nslog__cb)(nslog__cb_ctx, entry);
+ }
+}
+
+void nslog__log(nslog_category_t *category,
+ nslog_level level,
+ const char *filename,
+ int lineno,
+ const char *funcname,
+ const char *pattern,
+ ...)
+{
+ va_list ap;
+ va_start(ap, pattern);
+ va_list ap2;
+ va_copy(ap2, ap);
+ int slen = vsnprintf(NULL, 0, pattern, ap);
+ va_end(ap);
+ nslog_entry_t *entry = malloc(sizeof(nslog_entry_t) + slen + 1);
+ if (entry == NULL) {
+ /* We're at ENOMEM! log entry is lost */
+ va_end(ap2);
+ return;
+ }
+ entry->category = category;
+ entry->level = level;
+ entry->filename = filename;
+ entry->funcname = funcname;
+ entry->lineno = lineno;
+ vsprintf(entry->message, pattern, ap2);
+ va_end(ap2);
+ if (nslog__corked) {
+ struct nslog_cork_chain *chained = malloc(sizeof(struct nslog_cork_chain));
+ if (chained == NULL) {
+ /* ENOMEM during corked operation! wow */
+ free(entry);
+ return;
+ }
+ chained->next = nslog__cork_chain;
+ chained->entry = entry;
+ nslog__cork_chain = chained;
+ } else {
+ /* Not corked */
+ nslog__deliver(entry);
+ free(entry);
+ }
+}
+
+nslog_error nslog_set_render_callback(nslog_callback cb, void *context)
+{
+ nslog__cb = cb;
+ nslog__cb_ctx = context;
+
+ return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_uncork()
+{
+ if (nslog__corked) {
+ while (nslog__cork_chain != NULL) {
+ struct nslog_cork_chain *ent = nslog__cork_chain;
+ nslog__cork_chain = ent->next;
+ nslog__deliver(ent->entry);
+ free(ent->entry);
+ free(ent);
+ }
+ nslog__corked = false;
+ }
+ return NSLOG_NO_ERROR;
+}
+
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..0cebdaa
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,3 @@
+DIR_TEST_ITEMS := basic:basic.c
+
+include $(NSBUILD)/Makefile.subdir
diff --git a/test/basic.c b/test/basic.c
new file mode 100644
index 0000000..fd40633
--- /dev/null
+++ b/test/basic.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 Daniel Silverstone <dsilvers@netsurf-browser.org>
+ *
+ * This file is part of libnslog.
+ *
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+#include "nslog/nslog.h"
+
+#include <stdio.h>
+
+NSLOG_DEFINE_CATEGORY(test, "Test category");
+
+static void test_render_function(void *ctx, nslog_entry_t *log)
+{
+ (void)ctx;
+ fprintf(stderr, "%s %s:%d [%s] %s() %s\n",
+ nslog_level_name(log->level),
+ log->filename, log->lineno,
+ log->category->name,
+ log->funcname,
+ log->message);
+}
+
+int main(int argc, char **argv)
+{
+ nslog_set_render_callback(test_render_function, NULL);
+ nslog_uncork();
+ NSLOG(test, WARN, "argc=%d", argc);
+ return 0;
+}
diff --git a/test/runtest.sh b/test/runtest.sh
new file mode 100755
index 0000000..1b67a97
--- /dev/null
+++ b/test/runtest.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+TEST_PATH=$1
+TEST_PFX=$4
+
+for TEST in basic; do
+ ${TEST_PATH}/${TEST_PFX}${TEST}
+done
+
+exit 0