Gitweb links:

...log 
http://git.netsurf-browser.org/libnslog.git/shortlog/0d8bf0efca755ba4446a213d500975de65098dd0
...commit 
http://git.netsurf-browser.org/libnslog.git/commit/0d8bf0efca755ba4446a213d500975de65098dd0
...tree 
http://git.netsurf-browser.org/libnslog.git/tree/0d8bf0efca755ba4446a213d500975de65098dd0

The branch, master has been created
        at  0d8bf0efca755ba4446a213d500975de65098dd0 (commit)

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=0d8bf0efca755ba4446a213d500975de65098dd0
commit 0d8bf0efca755ba4446a213d500975de65098dd0
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Remove redundant parse test

diff --git a/test/Makefile b/test/Makefile
index 5ebac01..36d5092 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c parse:parse.c
+DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/test/parse.c b/test/parse.c
deleted file mode 100644
index 9fca97b..0000000
--- a/test/parse.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "nslog/nslog.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-int main(int argc, char **argv)
-{
-       if (argc != 2) {
-               fprintf(stderr, "usage: parse 'filtertext'\n");
-               return 1;
-       }
-       nslog_filter_t *filt;
-       nslog_error err;
-
-       err = nslog_filter_from_text(argv[1], &filt);
-       if (err != NSLOG_NO_ERROR) {
-               fprintf(stderr, "Unable to parse.\n");
-               return 2;
-       }
-       char *ct = nslog_filter_sprintf(filt);
-       filt = nslog_filter_unref(filt);
-       printf("%s\n", ct);
-       free(ct);
-       return 0;
-}


commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=768988d88470ffc1c64c35d6f9d3c37a9a6f75da
commit 768988d88470ffc1c64c35d6f9d3c37a9a6f75da
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Simple parser for filter syntax

diff --git a/include/nslog/nslog.h b/include/nslog/nslog.h
index fc3ead4..10b90a8 100644
--- a/include/nslog/nslog.h
+++ b/include/nslog/nslog.h
@@ -30,6 +30,7 @@ typedef enum {
 const char *nslog_level_name(nslog_level level);
 
 #define NSLOG_LEVEL_DD         NSLOG_LEVEL_DEEPDEBUG
+#define NSLOG_LEVEL_DBG                NSLOG_LEVEL_DEBUG
 #define NSLOG_LEVEL_CHAT       NSLOG_LEVEL_VERBOSE
 #define NSLOG_LEVEL_WARN       NSLOG_LEVEL_WARNING
 #define NSLOG_LEVEL_ERR                NSLOG_LEVEL_ERROR
@@ -105,6 +106,7 @@ typedef enum {
        NSLOG_NO_ERROR = 0,
        NSLOG_NO_MEMORY = 1,
        NSLOG_UNCORKED = 2,
+       NSLOG_PARSE_ERROR = 3,
 } nslog_error;
 
 typedef void (*nslog_callback)(void *context, nslog_entry_context_t *ctx,
@@ -145,4 +147,9 @@ nslog_filter_t *nslog_filter_unref(nslog_filter_t *filter);
 nslog_error nslog_filter_set_active(nslog_filter_t *filter,
                                    nslog_filter_t **prev);
 
+char *nslog_filter_sprintf(nslog_filter_t *filter);
+
+nslog_error nslog_filter_from_text(const char *input,
+                                  nslog_filter_t **output);
+
 #endif /* NSLOG_NSLOG_H_ */
diff --git a/src/Makefile b/src/Makefile
index 7fbad1c..3ca70cd 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,3 +1,37 @@
 DIR_SOURCES := core.c filter.c
 
+CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/
+
+SOURCES := $(SOURCES) $(BUILDDIR)/filter-parser.c $(BUILDDIR)/filter-lexer.c
+
+$(BUILDDIR)/%-lexer.c $(BUILDDIR)/%-lexer.h: src/%-lexer.l
+       $(VQ)$(ECHO) "    FLEX: $<"
+       $(Q)$(FLEX) --outfile=$(BUILDDIR)/$(*F)-lexer.c 
--header-file=$(BUILDDIR)/$(*F)-lexer.h $<
+
+$(BUILDDIR)/%-lexer.c: $(BUILDDIR)/%-parser.h
+
+# Bison 3.0 and later require api.prefix in curly braces
+# Bison 2.6 and later require api.prefix
+# Bison 2.5 and earlier require name-prefix switch
+bisonvsn := $(word 4,$(shell $(BISON) --version))
+bisonmaj := $(word 1,$(subst ., ,$(bisonvsn)))
+bisonmin := $(word 2,$(subst ., ,$(bisonvsn)))
+ifeq ($(bisonmaj),1)
+  BISON_DEFINES = --name-prefix=$(*F)_
+else
+  ifeq ($(bisonmaj),2)
+    ifneq ($(findstring $(bisonmin),"0 1 2 3 4 5"),)
+      BISON_DEFINES = --name-prefix=$(*F)_
+    else
+      BISON_DEFINES = --define=api.prefix=$(*F)_
+    endif
+  else
+    BISON_DEFINES = --define=api.prefix={$(*F)_}
+  endif
+endif
+
+$(BUILDDIR)/%-parser.c $(BUILDDIR)/%-parser.h: src/%-parser.y
+       $(VQ)$(ECHO) "   BISON: $<"
+       $(Q)$(BISON) -d -t $(BISON_DEFINES) --report=all 
--output=$(BUILDDIR)/$(*F)-parser.c --defines=$(BUILDDIR)/$(*F)-parser.h $<
+
 include $(NSBUILD)/Makefile.subdir
diff --git a/src/filter-lexer.l b/src/filter-lexer.l
new file mode 100644
index 0000000..5f75d29
--- /dev/null
+++ b/src/filter-lexer.l
@@ -0,0 +1,84 @@
+%{
+
+/* This is a lexer for libnslog filter syntax
+ *
+ * This file is part of libnslog.
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2017 Daniel Silverstone <[email protected]>
+ *
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "nslog/nslog.h"
+
+#include "filter-parser.h"
+
+/* Ensure compatability with bison 2.6 and later */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED && defined 
FILTER_STYPE_IS_DECLARED
+#define YYSTYPE FILTER_STYPE
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED && defined 
FILTER_LTYPE_IS_DECLARED
+#define YYLTYPE FILTER_LTYPE
+#endif
+
+%}
+
+
+/* lexer options */
+%option never-interactive
+%option bison-bridge
+%option bison-locations
+%option warn
+%option prefix="filter_"
+%option nounput
+%option noinput
+%option noyywrap
+
+whitespace     [ \t]+
+
+pattern                [^ \t]+
+
+%x             st_patt
+
+%%
+
+{whitespace}   { /* nothing */ }
+
+level:         { return T_LEVEL_SPECIFIER; }
+lvl:           { return T_LEVEL_SPECIFIER; }
+
+cat:           { BEGIN(st_patt); return T_CATEGORY_SPECIFIER; }
+category:      { BEGIN(st_patt); return T_CATEGORY_SPECIFIER; }
+file:          { BEGIN(st_patt); return T_FILENAME_SPECIFIER; }
+filename:      { BEGIN(st_patt); return T_FILENAME_SPECIFIER; }
+dir:           { BEGIN(st_patt); return T_DIRNAME_SPECIFIER; }
+dirname:       { BEGIN(st_patt); return T_DIRNAME_SPECIFIER; }
+func:          { BEGIN(st_patt); return T_FUNCNAME_SPECIFIER; }
+funcname:      { BEGIN(st_patt); return T_FUNCNAME_SPECIFIER; }
+
+"&&"           { return T_OP_AND; }
+"||"           { return T_OP_OR; }
+
+DEEPDEBUG      { yylval->level = NSLOG_LEVEL_DEEPDEBUG; return T_LEVEL; }
+DDEBUG         { yylval->level = NSLOG_LEVEL_DEEPDEBUG; return T_LEVEL; }
+DD             { yylval->level = NSLOG_LEVEL_DEEPDEBUG; return T_LEVEL; }
+DEBUG          { yylval->level = NSLOG_LEVEL_DEBUG; return T_LEVEL; }
+DBG            { yylval->level = NSLOG_LEVEL_DEBUG; return T_LEVEL; }
+VERBOSE                { yylval->level = NSLOG_LEVEL_VERBOSE; return T_LEVEL; }
+CHAT           { yylval->level = NSLOG_LEVEL_VERBOSE; return T_LEVEL; }
+INFO           { yylval->level = NSLOG_LEVEL_INFO; return T_LEVEL; }
+WARNING                { yylval->level = NSLOG_LEVEL_WARNING; return T_LEVEL; }
+WARN           { yylval->level = NSLOG_LEVEL_WARNING; return T_LEVEL; }
+ERROR          { yylval->level = NSLOG_LEVEL_ERROR; return T_LEVEL; }
+ERR            { yylval->level = NSLOG_LEVEL_ERROR; return T_LEVEL; }
+CRITICAL       { yylval->level = NSLOG_LEVEL_CRITICAL; return T_LEVEL; }
+CRIT           { yylval->level = NSLOG_LEVEL_CRITICAL; return T_LEVEL; }
+
+<st_patt>{pattern}     { yylval->patt = yytext; BEGIN(INITIAL); return 
T_PATTERN; }
+
+.              { return (int) yytext[0]; }
diff --git a/src/filter-parser.y b/src/filter-parser.y
new file mode 100644
index 0000000..bb225b6
--- /dev/null
+++ b/src/filter-parser.y
@@ -0,0 +1,197 @@
+%{
+/* This is a bison parser for libnslog's filter syntax
+ *
+ * This file is part of libnslog.
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2017 Daniel Silverstone <[email protected]>
+ *
+ */
+
+#include "nslog/nslog.h"
+#include <assert.h>
+
+#include "filter-parser.h"
+#include "filter-lexer.h"
+
+static void filter_error(FILTER_LTYPE *loc, nslog_filter_t **output, const 
char *msg)
+{
+       (void)loc;
+       (void)output;
+       (void)msg;
+}
+
+%}
+
+%locations
+%pure-parser
+%parse-param { nslog_filter_t **output }
+
+%union {
+       char *patt;
+       nslog_level level;
+       nslog_filter_t *filter;
+}
+
+%token <patt> T_PATTERN
+%token <level> T_LEVEL
+
+%token T_CATEGORY_SPECIFIER
+%token T_FILENAME_SPECIFIER
+%token T_LEVEL_SPECIFIER
+%token T_DIRNAME_SPECIFIER
+%token T_FUNCNAME_SPECIFIER
+
+%token T_OP_AND
+%token T_OP_OR
+
+%type <filter> level_filter
+%type <filter> category_filter
+%type <filter> filename_filter
+%type <filter> dirname_filter
+%type <filter> funcname_filter
+%type <filter> basic_filter
+
+%type <filter> and_filter
+%type <filter> or_filter
+%type <filter> xor_filter
+%type <filter> binary_filter
+%type <filter> not_filter
+
+%type <filter> filter
+%type <filter> toplevel
+
+%start toplevel
+
+%%
+
+ /*
+   part ::= [^: \t\n]+
+level-name ::= 'DEEPDEBUG' | 'DD' | 'DEBUG' | 'VERBOSE' | 'CHAT' |
+               'WARNING' | 'WARN' | 'ERROR' | 'ERR' | 'CRITICAL' | 'CRIT'
+
+category-filter ::= 'cat:' part
+level-filter ::= 'level:' level-name
+file-filter ::= 'file:' part
+dir-filter ::= 'dir:' dir
+
+factor ::= category-filter | level-filter | file-filter | dir-filter |
+           '(' expression ')'
+
+op ::= '&&' | '||' | '^' | 'and' | 'or' | 'xor' | 'eor'
+
+term ::= factor {op factor}
+
+expression ::= term | '!' term
+ */
+
+level_filter:
+       T_LEVEL_SPECIFIER T_LEVEL
+       {
+               assert(nslog_filter_level_new($2, &$$) == NSLOG_NO_ERROR);
+       }
+       ;
+
+category_filter:
+       T_CATEGORY_SPECIFIER T_PATTERN
+       {
+               assert(nslog_filter_category_new($2, &$$) == NSLOG_NO_ERROR);
+       }
+       ;
+
+filename_filter:
+       T_FILENAME_SPECIFIER T_PATTERN
+       {
+               assert(nslog_filter_filename_new($2, &$$) == NSLOG_NO_ERROR);
+       }
+       ;
+
+dirname_filter:
+       T_DIRNAME_SPECIFIER T_PATTERN
+       {
+               assert(nslog_filter_dirname_new($2, &$$) == NSLOG_NO_ERROR);
+       }
+       ;
+
+funcname_filter:
+       T_FUNCNAME_SPECIFIER T_PATTERN
+       {
+               assert(nslog_filter_funcname_new($2, &$$) == NSLOG_NO_ERROR);
+       }
+       ;
+
+basic_filter:
+       level_filter
+       |
+       category_filter
+       |
+       filename_filter
+       |
+       dirname_filter
+       |
+       funcname_filter
+       ;
+
+and_filter:
+       '(' filter T_OP_AND filter ')'
+       {
+               assert(nslog_filter_and_new($2, $4, &$$) == NSLOG_NO_ERROR);
+               nslog_filter_unref($2);
+               nslog_filter_unref($4);
+       }
+       ;
+
+or_filter:
+       '(' filter T_OP_OR filter ')'
+       {
+               assert(nslog_filter_or_new($2, $4, &$$) == NSLOG_NO_ERROR);
+               nslog_filter_unref($2);
+               nslog_filter_unref($4);
+       }
+       ;
+
+xor_filter:
+       '(' filter '^' filter ')'
+       {
+               assert(nslog_filter_xor_new($2, $4, &$$) == NSLOG_NO_ERROR);
+               nslog_filter_unref($2);
+               nslog_filter_unref($4);
+       }
+       ;
+
+binary_filter:
+       and_filter
+       |
+       or_filter
+       |
+       xor_filter
+       ;
+
+not_filter:
+       '!' filter
+       {
+               assert(nslog_filter_not_new($2, &$$) == NSLOG_NO_ERROR);
+               nslog_filter_unref($2);
+       }
+       ;
+
+filter:
+       not_filter
+       |
+       binary_filter
+       |
+       basic_filter
+       ;
+
+toplevel:
+       filter
+       {
+               $$ = *output = $1;
+       }
+       |
+       error
+       {
+               (void)yylloc;
+               YYABORT ;
+       }
+       ;
diff --git a/src/filter.c b/src/filter.c
index 1dc4e81..0a478b1 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -14,6 +14,19 @@
 
 #include "nslog_internal.h"
 
+#include "filter-parser.h"
+
+/* Ensure compatability with bison 2.6 and later */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED && defined 
FILTER_STYPE_IS_DECLARED
+#define YYSTYPE FILTER_STYPE
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED && defined 
FILTER_LTYPE_IS_DECLARED
+#define YYLTYPE FILTER_LTYPE
+#endif
+
+#include "filter-lexer.h"
+
 typedef enum {
        /* Fundamentals */
        NSLFK_CATEGORY = 0,
@@ -308,3 +321,74 @@ bool nslog__filter_matches(nslog_entry_context_t *ctx)
                return true;
        return _nslog__filter_matches(ctx, nslog__active_filter);
 }
+
+char *nslog_filter_sprintf(nslog_filter_t *filter)
+{
+       char *ret = NULL;
+       switch (filter->kind) {
+       case NSLFK_CATEGORY:
+               ret = calloc(filter->params.str.len + 5, 1);
+               sprintf(ret, "cat:%s", filter->params.str.ptr);
+               break;
+       case NSLFK_LEVEL: {
+               const char *lvl = nslog_level_name(filter->params.level);
+               ret = calloc(strlen(lvl) + 5, 1);
+               sprintf(ret, "lvl:%s", lvl);
+               break;
+       }
+       case NSLFK_FILENAME:
+               ret = calloc(filter->params.str.len + 6, 1);
+               sprintf(ret, "file:%s", filter->params.str.ptr);
+               break;
+       case NSLFK_DIRNAME:
+               ret = calloc(filter->params.str.len + 5, 1);
+               sprintf(ret, "dir:%s", filter->params.str.ptr);
+               break;
+       case NSLFK_FUNCNAME:
+               ret = calloc(filter->params.str.len + 6, 1);
+               sprintf(ret, "func:%s", filter->params.str.ptr);
+               break;
+       case NSLFK_AND:
+       case NSLFK_OR:
+       case NSLFK_XOR: {
+               char *left = nslog_filter_sprintf(filter->params.binary.input1);
+               char *right = 
nslog_filter_sprintf(filter->params.binary.input2);
+               const char *op =
+                       (filter->kind == NSLFK_AND) ? "&&" :
+                       (filter->kind == NSLFK_OR) ? "||" : "^";
+               ret = calloc(strlen(left) + strlen(right) + 7, 1);
+               sprintf(ret, "(%s %s %s)", left, op, right);
+               free(left);
+               free(right);
+               break;
+       }
+       case NSLFK_NOT: {
+               char *input = nslog_filter_sprintf(filter->params.unary_input);
+               ret = calloc(strlen(input) + 2, 1);
+               sprintf(ret, "!%s", input);
+               free(input);
+               break;
+       }
+       default:
+               assert("Unexpected kind" == NULL);
+               return strdup("***ERROR***");
+       }
+       return ret;
+}
+
+nslog_error nslog_filter_from_text(const char *input,
+                                  nslog_filter_t **output)
+{
+       int ret;
+       YY_BUFFER_STATE buffer = filter__scan_string((char *)input);
+       filter_push_buffer_state(buffer);
+       ret = filter_parse(output);
+       filter_lex_destroy();
+       switch (ret) {
+       case 0:
+               return NSLOG_NO_ERROR;
+       case 2:
+               return NSLOG_NO_MEMORY;
+       }
+       return NSLOG_PARSE_ERROR;
+}
diff --git a/test/Makefile b/test/Makefile
index 36d5092..5ebac01 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c
+DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c parse:parse.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/test/basictests.c b/test/basictests.c
index b83ed9f..d74df87 100644
--- a/test/basictests.c
+++ b/test/basictests.c
@@ -171,7 +171,7 @@ START_TEST (test_nslog_simple_filter_corked_message)
                    "Captured message wasn't correct filename");
        fail_unless(strcmp(captured_context.funcname, 
"test_nslog_simple_filter_corked_message") == 0,
                    "Captured message wasn't correct function name");
-       
+
 }
 END_TEST
 
@@ -198,7 +198,34 @@ START_TEST (test_nslog_simple_filter_uncorked_message)
                    "Captured message wasn't correct filename");
        fail_unless(strcmp(captured_context.funcname, 
"test_nslog_simple_filter_uncorked_message") == 0,
                    "Captured message wasn't correct function name");
-       
+
+}
+END_TEST
+
+START_TEST (test_nslog_basic_filter_sprintf)
+{
+       char *ct = nslog_filter_sprintf(cat_test);
+       fail_unless(ct != NULL, "Unable to sprintf");
+       fail_unless(strcmp(ct, "cat:test") == 0,
+                   "Printed category test is wrong");
+       free(ct);
+       ct = nslog_filter_sprintf(cat_another);
+       fail_unless(ct != NULL, "Unable to sprintf");
+       fail_unless(strcmp(ct, "cat:another") == 0,
+                   "Printed category another is wrong");
+       free(ct);
+}
+END_TEST
+
+START_TEST (test_nslog_parse_and_sprintf)
+{
+       nslog_filter_t *filt;
+       fail_unless(nslog_filter_from_text("cat:test", &filt) == NSLOG_NO_ERROR,
+                   "Unable to parse cat:test");
+       char *ct = nslog_filter_sprintf(filt);
+       nslog_filter_unref(filt);
+       fail_unless(strcmp(ct, "cat:test") == 0,
+                   "Printed parsed cat:test not right");
 }
 END_TEST
 
@@ -209,22 +236,24 @@ nslog_basic_suite(SRunner *sr)
 {
         Suite *s = suite_create("libnslog: Basic tests");
         TCase *tc_basic = NULL;
-       
+
        tc_basic = tcase_create("Simple log checks, no filters");
-        
+
         tcase_add_checked_fixture(tc_basic, with_simple_context_setup,
                                   with_simple_context_teardown);
         tcase_add_test(tc_basic, test_nslog_trivial_corked_message);
         tcase_add_test(tc_basic, test_nslog_trivial_uncorked_message);
         suite_add_tcase(s, tc_basic);
-        
+
         tc_basic = tcase_create("Simple filter checks");
-        
+
         tcase_add_checked_fixture(tc_basic, with_simple_filter_context_setup,
                                   with_simple_filter_context_teardown);
         tcase_add_test(tc_basic, test_nslog_simple_filter_corked_message);
         tcase_add_test(tc_basic, test_nslog_simple_filter_uncorked_message);
+        tcase_add_test(tc_basic, test_nslog_basic_filter_sprintf);
+        tcase_add_test(tc_basic, test_nslog_parse_and_sprintf);
         suite_add_tcase(s, tc_basic);
-        
+
         srunner_add_suite(sr, s);
 }
diff --git a/test/parse.c b/test/parse.c
new file mode 100644
index 0000000..9fca97b
--- /dev/null
+++ b/test/parse.c
@@ -0,0 +1,25 @@
+#include "nslog/nslog.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+       if (argc != 2) {
+               fprintf(stderr, "usage: parse 'filtertext'\n");
+               return 1;
+       }
+       nslog_filter_t *filt;
+       nslog_error err;
+
+       err = nslog_filter_from_text(argv[1], &filt);
+       if (err != NSLOG_NO_ERROR) {
+               fprintf(stderr, "Unable to parse.\n");
+               return 2;
+       }
+       char *ct = nslog_filter_sprintf(filt);
+       filt = nslog_filter_unref(filt);
+       printf("%s\n", ct);
+       free(ct);
+       return 0;
+}


commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=602a6b133f83e2349a4b233536fdca90446638cd
commit 602a6b133f83e2349a4b233536fdca90446638cd
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Remove assert stuff, we don't need it, add more test

diff --git a/test/basictests.c b/test/basictests.c
index 4d94059..b83ed9f 100644
--- a/test/basictests.c
+++ b/test/basictests.c
@@ -18,12 +18,6 @@
 #define UNUSED(x) (void)(x)
 #endif
 
-#ifndef NDEBUG
-
-/* Tests go here which need assert() to be checked */
-
-#endif
-
 NSLOG_DEFINE_CATEGORY(test, "Top level test category");
 
 static void *captured_render_context = NULL;
@@ -181,25 +175,42 @@ START_TEST (test_nslog_simple_filter_corked_message)
 }
 END_TEST
 
+START_TEST (test_nslog_simple_filter_uncorked_message)
+{
+       fail_unless(nslog_filter_set_active(cat_test, NULL) == NSLOG_NO_ERROR,
+                   "Unable to set active filter to cat:test");
+       fail_unless(nslog_uncork() == NSLOG_NO_ERROR,
+                   "Unable to uncork");
+       NSLOG(test, INFO, "Hello world");
+       fail_unless(captured_message_count == 1,
+                   "Captured message count was wrong");
+       fail_unless(captured_render_context == anchor_context_2,
+                   "Captured context wasn't passed through");
+       fail_unless(strcmp(captured_context.category->name, "test") == 0,
+                   "Captured context category wasn't normalised");
+       fail_unless(captured_context.category == &__nslog_category_test,
+                   "Captured context category wasn't the one we wanted");
+       fail_unless(captured_rendered_message_length == 11,
+                   "Captured message wasn't correct length");
+       fail_unless(strcmp(captured_rendered_message, "Hello world") == 0,
+                   "Captured message wasn't correct");
+       fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0,
+                   "Captured message wasn't correct filename");
+       fail_unless(strcmp(captured_context.funcname, 
"test_nslog_simple_filter_uncorked_message") == 0,
+                   "Captured message wasn't correct function name");
+       
+}
+END_TEST
+
 /**** And the suites are set up here ****/
 
 void
 nslog_basic_suite(SRunner *sr)
 {
         Suite *s = suite_create("libnslog: Basic tests");
-        TCase *tc_basic = tcase_create("Abort checking");
-        
-#ifndef NDEBUG
-       /*
-        tcase_add_test_raise_signal(tc_basic,
-                                    test_lwc_string_hash_value_aborts,
-                                    SIGABRT);
-       */
-#endif
-        
-        suite_add_tcase(s, tc_basic);
-        
-        tc_basic = tcase_create("Simple log checks, no filters");
+        TCase *tc_basic = NULL;
+       
+       tc_basic = tcase_create("Simple log checks, no filters");
         
         tcase_add_checked_fixture(tc_basic, with_simple_context_setup,
                                   with_simple_context_teardown);
@@ -212,6 +223,7 @@ nslog_basic_suite(SRunner *sr)
         tcase_add_checked_fixture(tc_basic, with_simple_filter_context_setup,
                                   with_simple_filter_context_teardown);
         tcase_add_test(tc_basic, test_nslog_simple_filter_corked_message);
+        tcase_add_test(tc_basic, test_nslog_simple_filter_uncorked_message);
         suite_add_tcase(s, tc_basic);
         
         srunner_add_suite(sr, s);
diff --git a/test/testmain.c b/test/testmain.c
index 9a6b257..38a4ace 100644
--- a/test/testmain.c
+++ b/test/testmain.c
@@ -15,18 +15,6 @@
 #define UNUSED(x) ((x) = (x))
 #endif
 
-/* This means that assertion failures are silent in tests */
-#ifndef NDEBUG
-void __assert_fail(const char *__assertion, const char *__file,
-                  unsigned int __line, const char *__function) {
-       (void)__assertion;
-       (void)__file;
-       (void)__line;
-       (void)__function;
-       abort();
-}
-#endif
-
 int
 main(int argc, char **argv)
 {
@@ -35,16 +23,16 @@ main(int argc, char **argv)
 
        UNUSED(argc);
        UNUSED(argv);
-  
+
         sr = srunner_create(suite_create("Test suite for libnslog"));
-        
+
         nslog_basic_suite(sr);
-        
+
         srunner_set_fork_status(sr, CK_FORK);
         srunner_run_all(sr, CK_ENV);
         number_failed = srunner_ntests_failed(sr);
-        
+
         srunner_free(sr);
-        
+
         return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }


commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=43f7f54dadecb1d11b4fd9cd2af4889043865490
commit 43f7f54dadecb1d11b4fd9cd2af4889043865490
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Switch to a check based test suite, start fixing bugs

diff --git a/Makefile b/Makefile
index 184f9d4..26cf49f 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ 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)
+TESTRUNNER = $(BUILDDIR)/test_testrunner$(EXEEXT)
 
 # Toolchain flags
 WARNFLAGS := -Wall -W -Wundef -Wpointer-arith -Wcast-align \
@@ -48,6 +48,15 @@ TESTLDFLAGS := -lm -l$(COMPONENT) $(TESTLDFLAGS)
 
 include $(NSBUILD)/Makefile.top
 
+ifeq ($(WANT_TEST),yes)
+  ifneq ($(PKGCONFIG),)
+    TESTCFLAGS := $(TESTCFLAGS) $(shell $(PKGCONFIG) --cflags check)
+    TESTLDFLAGS := $(TESTLDFLAGS) $(shell $(PKGCONFIG) --libs check)
+  else
+    TESTLDFLAGS := $(TESTLDFLAGS) -lcheck
+  endif
+endif
+
 # Extra installation rules
 I := /$(INCLUDEDIR)/nslog
 INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/nslog/nslog.h
diff --git a/include/nslog/nslog.h b/include/nslog/nslog.h
index 550bffb..fc3ead4 100644
--- a/include/nslog/nslog.h
+++ b/include/nslog/nslog.h
@@ -104,6 +104,7 @@ void nslog__log(nslog_entry_context_t *ctx,
 typedef enum {
        NSLOG_NO_ERROR = 0,
        NSLOG_NO_MEMORY = 1,
+       NSLOG_UNCORKED = 2,
 } nslog_error;
 
 typedef void (*nslog_callback)(void *context, nslog_entry_context_t *ctx,
diff --git a/src/core.c b/src/core.c
index 978f169..95d06c2 100644
--- a/src/core.c
+++ b/src/core.c
@@ -73,7 +73,7 @@ static void nslog__log_corked(nslog_entry_context_t *ctx,
                              va_list args)
 {
        /* If corked, we need to store a copy */
-       struct nslog_cork_chain *newcork = malloc(sizeof(*newcork) + 
measured_len + 1);
+       struct nslog_cork_chain *newcork = calloc(sizeof(struct 
nslog_cork_chain) + measured_len + 1, 1);
        if (newcork == NULL) {
                /* Wow, something went wrong */
                return;
@@ -157,6 +157,8 @@ nslog_error nslog_uncork()
                        free(ent);
                }
                nslog__corked = false;
+               return NSLOG_NO_ERROR;
+       } else {
+               return NSLOG_UNCORKED;
        }
-       return NSLOG_NO_ERROR;
 }
diff --git a/test/Makefile b/test/Makefile
index 033033f..36d5092 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := basic:basic.c explicitfilter:explicitfilter.c
+DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/test/basic.c b/test/basic.c
deleted file mode 100644
index d514814..0000000
--- a/test/basic.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2017 Daniel Silverstone <[email protected]>
- *
- * 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_context_t *ctx,
-       const char *fmt, va_list args)
-{
-       (void)ctx;
-       fprintf(stderr, "%s %s:%d [%s] %s() ",
-               nslog_level_name(ctx->level),
-               ctx->filename, ctx->lineno,
-               ctx->category->name,
-               ctx->funcname);
-       vfprintf(stderr, fmt, args);
-       fprintf(stderr, "\n");
-}
-
-int main(int argc, char **argv)
-{
-       nslog_set_render_callback(test_render_function, NULL);
-       NSLOG(test, INFO, "Pre-uncorking");
-       fprintf(stderr, "About to nslog_uncork()\n");
-       nslog_uncork();
-       fprintf(stderr, "Uncorked now\n");
-       NSLOG(test, WARN, "argc=%d", argc);
-       for (int i = 0; i < argc; ++i)
-               NSLOG(test, WARN, "argv[%d] = %s", i, argv[i]);
-       return 0;
-}
diff --git a/test/basictests.c b/test/basictests.c
new file mode 100644
index 0000000..4d94059
--- /dev/null
+++ b/test/basictests.c
@@ -0,0 +1,218 @@
+/* test/basictests.c
+ *
+ * Basic tests for the test suite for libnslog
+ *
+ * Copyright 2009,2017 The NetSurf Browser Project
+ *                Daniel Silverstone <[email protected]>
+ */
+
+#include <check.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "tests.h"
+
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
+#ifndef NDEBUG
+
+/* Tests go here which need assert() to be checked */
+
+#endif
+
+NSLOG_DEFINE_CATEGORY(test, "Top level test category");
+
+static void *captured_render_context = NULL;
+static nslog_entry_context_t captured_context = { 0 };
+static char captured_rendered_message[4096] = { 0 };
+static int captured_rendered_message_length = 0;
+static int captured_message_count = 0;
+
+static const char* anchor_context_1 = "1";
+
+static void
+nslog__test__render_function(void *_ctx, nslog_entry_context_t *ctx,
+                            const char *fmt, va_list args)
+{
+       captured_context = *ctx;
+       captured_render_context = _ctx;
+       captured_rendered_message_length =
+               vsnprintf(captured_rendered_message,
+                         sizeof(captured_rendered_message),
+                         fmt, args);
+       captured_message_count++;
+}
+
+/**** The next set of tests need a fixture set ****/
+
+static void
+with_simple_context_setup(void)
+{
+       captured_render_context = NULL;
+       memset(&captured_context, 0, sizeof(captured_context));
+       memset(captured_rendered_message, 0, sizeof(captured_rendered_message));
+       captured_rendered_message_length = 0;
+       captured_message_count = 0;
+       fail_unless(nslog_set_render_callback(
+                           nslog__test__render_function,
+                           (void *)anchor_context_1) == NSLOG_NO_ERROR,
+                   "Unable to set up render callback");
+}
+
+static void
+with_simple_context_teardown(void)
+{
+        /* Nothing to do to tear down */
+}
+
+START_TEST (test_nslog_trivial_corked_message)
+{
+       NSLOG(test, INFO, "Hello %s", "world");
+       fail_unless(nslog_uncork() == NSLOG_NO_ERROR,
+                   "Unable to uncork");
+       fail_unless(captured_message_count == 1,
+                   "Captured message count was wrong");
+       fail_unless(captured_render_context == anchor_context_1,
+                   "Captured context wasn't passed through");
+       fail_unless(strcmp(captured_context.category->name, "test") == 0,
+                   "Captured context category wasn't normalised");
+       fail_unless(captured_context.category == &__nslog_category_test,
+                   "Captured context category wasn't the one we wanted");
+       fail_unless(captured_rendered_message_length == 11,
+                   "Captured message wasn't correct length");
+       fail_unless(strcmp(captured_rendered_message, "Hello world") == 0,
+                   "Captured message wasn't correct");
+       fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0,
+                   "Captured message wasn't correct filename");
+       fail_unless(strcmp(captured_context.funcname, 
"test_nslog_trivial_corked_message") == 0,
+                   "Captured message wasn't correct function name");
+}
+END_TEST
+
+START_TEST (test_nslog_trivial_uncorked_message)
+{
+       fail_unless(nslog_uncork() == NSLOG_NO_ERROR,
+                   "Unable to uncork");
+       fail_unless(captured_message_count == 0,
+                   "Unusual, we had messages from before uncorking");
+       NSLOG(test, INFO, "Hello %s", "world");
+       fail_unless(captured_message_count == 1,
+                   "Captured message count was wrong");
+       fail_unless(captured_render_context == anchor_context_1,
+                   "Captured context wasn't passed through");
+       fail_unless(strcmp(captured_context.category->name, "test") == 0,
+                   "Captured context category wasn't normalised");
+       fail_unless(captured_context.category == &__nslog_category_test,
+                   "Captured context category wasn't the one we wanted");
+       fail_unless(captured_rendered_message_length == 11,
+                   "Captured message wasn't correct length");
+       fail_unless(strcmp(captured_rendered_message, "Hello world") == 0,
+                   "Captured message wasn't correct");
+       fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0,
+                   "Captured message wasn't correct filename");
+       fail_unless(strcmp(captured_context.funcname, 
"test_nslog_trivial_uncorked_message") == 0,
+                   "Captured message wasn't correct function name");
+}
+END_TEST
+
+/**** The next set of tests need a fixture set for filters ****/
+
+static nslog_filter_t *cat_test = NULL;
+static nslog_filter_t *cat_another = NULL;
+
+static const char *anchor_context_2 = "2";
+
+static void
+with_simple_filter_context_setup(void)
+{
+       captured_render_context = NULL;
+       memset(&captured_context, 0, sizeof(captured_context));
+       memset(captured_rendered_message, 0, sizeof(captured_rendered_message));
+       captured_rendered_message_length = 0;
+       captured_message_count = 0;
+       fail_unless(nslog_set_render_callback(
+                           nslog__test__render_function,
+                           (void *)anchor_context_2) == NSLOG_NO_ERROR,
+                   "Unable to set up render callback");
+       fail_unless(nslog_filter_category_new("test", &cat_test) == 
NSLOG_NO_ERROR,
+                   "Unable to create a category filter for 'test'");
+       fail_unless(nslog_filter_category_new("another", &cat_another) == 
NSLOG_NO_ERROR,
+                   "Unable to create a category filter for 'another'");
+}
+
+static void
+with_simple_filter_context_teardown(void)
+{
+        /* Nothing to do to tear down */
+       fail_unless(nslog_filter_set_active(NULL, NULL) == NSLOG_NO_ERROR,
+                   "Unable to clear active filter");
+       cat_test = nslog_filter_unref(cat_test);
+       cat_another = nslog_filter_unref(cat_another);
+}
+
+START_TEST (test_nslog_simple_filter_corked_message)
+{
+       NSLOG(test, INFO, "Hello world");
+       fail_unless(nslog_filter_set_active(cat_test, NULL) == NSLOG_NO_ERROR,
+                   "Unable to set active filter to cat:test");
+       fail_unless(nslog_uncork() == NSLOG_NO_ERROR,
+                   "Unable to uncork");
+       fail_unless(captured_message_count == 1,
+                   "Captured message count was wrong");
+       fail_unless(captured_render_context == anchor_context_2,
+                   "Captured context wasn't passed through");
+       fail_unless(strcmp(captured_context.category->name, "test") == 0,
+                   "Captured context category wasn't normalised");
+       fail_unless(captured_context.category == &__nslog_category_test,
+                   "Captured context category wasn't the one we wanted");
+       fail_unless(captured_rendered_message_length == 11,
+                   "Captured message wasn't correct length");
+       fail_unless(strcmp(captured_rendered_message, "Hello world") == 0,
+                   "Captured message wasn't correct");
+       fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0,
+                   "Captured message wasn't correct filename");
+       fail_unless(strcmp(captured_context.funcname, 
"test_nslog_simple_filter_corked_message") == 0,
+                   "Captured message wasn't correct function name");
+       
+}
+END_TEST
+
+/**** And the suites are set up here ****/
+
+void
+nslog_basic_suite(SRunner *sr)
+{
+        Suite *s = suite_create("libnslog: Basic tests");
+        TCase *tc_basic = tcase_create("Abort checking");
+        
+#ifndef NDEBUG
+       /*
+        tcase_add_test_raise_signal(tc_basic,
+                                    test_lwc_string_hash_value_aborts,
+                                    SIGABRT);
+       */
+#endif
+        
+        suite_add_tcase(s, tc_basic);
+        
+        tc_basic = tcase_create("Simple log checks, no filters");
+        
+        tcase_add_checked_fixture(tc_basic, with_simple_context_setup,
+                                  with_simple_context_teardown);
+        tcase_add_test(tc_basic, test_nslog_trivial_corked_message);
+        tcase_add_test(tc_basic, test_nslog_trivial_uncorked_message);
+        suite_add_tcase(s, tc_basic);
+        
+        tc_basic = tcase_create("Simple filter checks");
+        
+        tcase_add_checked_fixture(tc_basic, with_simple_filter_context_setup,
+                                  with_simple_filter_context_teardown);
+        tcase_add_test(tc_basic, test_nslog_simple_filter_corked_message);
+        suite_add_tcase(s, tc_basic);
+        
+        srunner_add_suite(sr, s);
+}
diff --git a/test/explicitfilter.c b/test/explicitfilter.c
deleted file mode 100644
index c7aca8a..0000000
--- a/test/explicitfilter.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 Daniel Silverstone <[email protected]>
- *
- * 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>
-#include <assert.h>
-
-NSLOG_DEFINE_CATEGORY(test, "Test category");
-
-static void test_render_function(
-       void *_ctx, nslog_entry_context_t *ctx,
-       const char *fmt, va_list args)
-{
-       (void)ctx;
-       fprintf(stderr, "%s %s:%d [%s] %s() ",
-               nslog_level_name(ctx->level),
-               ctx->filename, ctx->lineno,
-               ctx->category->name,
-               ctx->funcname);
-       vfprintf(stderr, fmt, args);
-       fprintf(stderr, "\n");
-}
-
-int main(int argc, char **argv)
-{
-       nslog_set_render_callback(test_render_function, NULL);
-       nslog_uncork();
-
-       nslog_filter_t *cat_test, *cat_another;
-
-       assert(nslog_filter_category_new("test", &cat_test) == NSLOG_NO_ERROR);
-       assert(nslog_filter_category_new("another", &cat_another) == 
NSLOG_NO_ERROR);
-
-       NSLOG(test, INFO, "Hurrah, a message!");
-       assert(nslog_filter_set_active(cat_test, NULL) == NSLOG_NO_ERROR);
-       NSLOG(test, INFO, "You should see me.");
-       assert(nslog_filter_set_active(cat_another, NULL) == NSLOG_NO_ERROR);
-       NSLOG(test, INFO, "You should not see me!");
-       assert(nslog_filter_set_active(NULL, NULL) == NSLOG_NO_ERROR);
-       NSLOG(test, INFO, "You should see this one though.");
-
-       return 0;
-}
diff --git a/test/testmain.c b/test/testmain.c
new file mode 100644
index 0000000..9a6b257
--- /dev/null
+++ b/test/testmain.c
@@ -0,0 +1,50 @@
+/* test/testmain.c
+ *
+ * Core of the test suite for libnslog
+ *
+ * Copyright 2009, 2017 The NetSurf Browser Project
+ *                Daniel Silverstone <[email protected]>
+ */
+
+#include <check.h>
+#include <stdlib.h>
+
+#include "tests.h"
+
+#ifndef UNUSED
+#define UNUSED(x) ((x) = (x))
+#endif
+
+/* This means that assertion failures are silent in tests */
+#ifndef NDEBUG
+void __assert_fail(const char *__assertion, const char *__file,
+                  unsigned int __line, const char *__function) {
+       (void)__assertion;
+       (void)__file;
+       (void)__line;
+       (void)__function;
+       abort();
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+        int number_failed = 0;
+        SRunner *sr;
+
+       UNUSED(argc);
+       UNUSED(argv);
+  
+        sr = srunner_create(suite_create("Test suite for libnslog"));
+        
+        nslog_basic_suite(sr);
+        
+        srunner_set_fork_status(sr, CK_FORK);
+        srunner_run_all(sr, CK_ENV);
+        number_failed = srunner_ntests_failed(sr);
+        
+        srunner_free(sr);
+        
+        return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test/tests.h b/test/tests.h
new file mode 100644
index 0000000..37cdd8d
--- /dev/null
+++ b/test/tests.h
@@ -0,0 +1,21 @@
+/* test/tests.h
+ *
+ * Set of test suites for libnslog
+ *
+ * Copyright 2009,2017 The NetSurf Browser Project
+ *                Daniel Silverstone <[email protected]>
+ */
+
+#ifndef nslog_tests_h_
+#define nslog_tests_h_
+
+#include <assert.h>
+#include <signal.h>
+
+#include <check.h>
+
+#include "nslog/nslog.h"
+
+extern void nslog_basic_suite(SRunner *);
+
+#endif /* nslog_tests_h_ */


commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=8b4ce0ba86d0396bde2546dd248c863876da4106
commit 8b4ce0ba86d0396bde2546dd248c863876da4106
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Another step toward filters working

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f24cd50
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+# This is an EditorConfig file
+# Learn more at http://editorconfig.org
+
+root = true
+
+# All files are UNIX-style and UTF-8
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+trim_trailing_whitespace = true
+
+# Makefiles use tabs
+[Makefile]
+indent_style = tab
+
+# C code uses tabs
+[*.{c,h}]
+indent_style = tab
diff --git a/include/nslog/nslog.h b/include/nslog/nslog.h
index ffa87bd..550bffb 100644
--- a/include/nslog/nslog.h
+++ b/include/nslog/nslog.h
@@ -4,7 +4,7 @@
  * This file is part of libnslog.
  *
  * Licensed under the MIT License,
- *                http://www.opensource.org/licenses/mit-license.php
+ *               http://www.opensource.org/licenses/mit-license.php
  */
 
 /**
@@ -18,41 +18,44 @@
 #include <stdarg.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_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
+#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;
+       const char *cat_name;
+       const char *description;
+       struct nslog_category_s *parent;
+       char *name;
+       int namelen;
+       struct nslog_category_s *next;
 } nslog_category_t;
 
 typedef struct nslog_entry_context_s {
-        nslog_category_t *category;
-        nslog_level level;
-        const char *filename;
+       nslog_category_t *category;
+       nslog_level level;
+       const char *filename;
+       int filenamelen;
        const char *funcname;
-        int lineno;
+       int funcnamelen;
+       int lineno;
 } nslog_entry_context_t;
 
 #define NSLOG_DECLARE_CATEGORY(catname)                                \
@@ -64,6 +67,7 @@ typedef struct nslog_entry_context_s {
                description,                            \
                NULL,                                   \
                NULL,                                   \
+               0,                                      \
                NULL,                                   \
        }
 
@@ -73,6 +77,7 @@ typedef struct nslog_entry_context_s {
                description,                                            \
                &__nslog_category_##parentcatname,                      \
                NULL,                                                   \
+               0,                                                      \
                NULL,                                                   \
        }
 
@@ -83,7 +88,9 @@ typedef struct nslog_entry_context_s {
                                &__nslog_category_##catname,            \
                                NSLOG_LEVEL_##level,                    \
                                __FILE__,                               \
+                               sizeof(__FILE__) - 1,                   \
                                __PRETTY_FUNCTION__,                    \
+                               sizeof(__PRETTY_FUNCTION__) - 1,        \
                                __LINE__,                               \
                        };                                              \
                        nslog__log(&ctx, logmsg, ##args);               \
@@ -106,4 +113,35 @@ nslog_error nslog_set_render_callback(nslog_callback cb, 
void *context);
 
 nslog_error nslog_uncork(void);
 
+typedef struct nslog_filter_s nslog_filter_t;
+
+nslog_error nslog_filter_category_new(const char *catname,
+                                     nslog_filter_t **filter);
+nslog_error nslog_filter_level_new(nslog_level level,
+                                  nslog_filter_t **filter);
+nslog_error nslog_filter_filename_new(const char *filename,
+                                     nslog_filter_t **filter);
+nslog_error nslog_filter_dirname_new(const char *dirname,
+                                    nslog_filter_t **filter);
+nslog_error nslog_filter_funcname_new(const char *funcname,
+                                     nslog_filter_t **filter);
+
+nslog_error nslog_filter_and_new(nslog_filter_t *left,
+                                nslog_filter_t *right,
+                                nslog_filter_t **filter);
+nslog_error nslog_filter_or_new(nslog_filter_t *left,
+                               nslog_filter_t *right,
+                               nslog_filter_t **filter);
+nslog_error nslog_filter_xor_new(nslog_filter_t *left,
+                                nslog_filter_t *right,
+                                nslog_filter_t **filter);
+nslog_error nslog_filter_not_new(nslog_filter_t *input,
+                                nslog_filter_t **filter);
+
+nslog_filter_t *nslog_filter_ref(nslog_filter_t *filter);
+nslog_filter_t *nslog_filter_unref(nslog_filter_t *filter);
+
+nslog_error nslog_filter_set_active(nslog_filter_t *filter,
+                                   nslog_filter_t **prev);
+
 #endif /* NSLOG_NSLOG_H_ */
diff --git a/src/Makefile b/src/Makefile
index 45ecb90..7fbad1c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,3 +1,3 @@
-DIR_SOURCES := core.c
+DIR_SOURCES := core.c filter.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/src/core.c b/src/core.c
index ee5f2bc..978f169 100644
--- a/src/core.c
+++ b/src/core.c
@@ -4,7 +4,7 @@
  * This file is part of libnslog.
  *
  * Licensed under the MIT License,
- *                http://www.opensource.org/licenses/mit-license.php
+ *               http://www.opensource.org/licenses/mit-license.php
  */
 
 /**
@@ -12,21 +12,14 @@
  * NetSurf Logging Core
  */
 
-#include "nslog/nslog.h"
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
+#include "nslog_internal.h"
 
 static bool nslog__corked = true;
 
 static struct nslog_cork_chain {
        struct nslog_cork_chain *next;
        nslog_entry_context_t context;
-        char message[0]; /* NUL terminated */
+       char message[0]; /* NUL terminated */
 } *nslog__cork_chain = NULL, *nslog__cork_chain_last = NULL;
 
 static nslog_callback nslog__cb = NULL;
@@ -52,7 +45,7 @@ const char *nslog_level_name(nslog_level level)
        case NSLOG_LEVEL_CRITICAL:
                return "CRITICAL";
        };
-       
+
        return "**UNKNOWN**";
 }
 
@@ -61,6 +54,7 @@ static void nslog__normalise_category(nslog_category_t *cat)
 {
        if (cat->parent == NULL) {
                cat->name = strdup(cat->cat_name);
+               cat->namelen = strlen(cat->name);
        } else {
                nslog__normalise_category(cat->parent);
                cat->name = malloc(strlen(cat->parent->name) + 
strlen(cat->cat_name) + 2);
@@ -68,6 +62,7 @@ static void nslog__normalise_category(nslog_category_t *cat)
                strcat(cat->name, "/");
                strcat(cat->name, cat->cat_name);
                cat->next = nslog__all_categories;
+               cat->namelen = strlen(cat->name);
                nslog__all_categories = cat;
        }
 }
@@ -102,7 +97,8 @@ static void nslog__log_uncorked(nslog_entry_context_t *ctx,
                if (ctx->category->name == NULL) {
                        nslog__normalise_category(ctx->category);
                }
-               (*nslog__cb)(nslog__cb_ctx, ctx, fmt, args);
+               if (nslog__filter_matches(ctx))
+                       (*nslog__cb)(nslog__cb_ctx, ctx, fmt, args);
        }
 }
 
@@ -129,7 +125,7 @@ nslog_error nslog_set_render_callback(nslog_callback cb, 
void *context)
 {
        nslog__cb = cb;
        nslog__cb_ctx = context;
-       
+
        return NSLOG_NO_ERROR;
 }
 
@@ -155,12 +151,12 @@ nslog_error nslog_uncork()
                        if (ent->context.category->name == NULL) {
                                
nslog__normalise_category(ent->context.category);
                        }
-                       __nslog__deliver_corked_entry(&ent->context,
-                                                     "%s", ent->message);
+                       if (nslog__filter_matches(&ent->context))
+                               __nslog__deliver_corked_entry(&ent->context,
+                                                             "%s", 
ent->message);
                        free(ent);
                }
                nslog__corked = false;
        }
        return NSLOG_NO_ERROR;
 }
-
diff --git a/src/filter.c b/src/filter.c
new file mode 100644
index 0000000..1dc4e81
--- /dev/null
+++ b/src/filter.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2017 Daniel Silverstone <[email protected]>
+ *
+ * This file is part of libnslog.
+ *
+ * Licensed under the MIT License,
+ *               http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * NetSurf Logging Filters
+ */
+
+#include "nslog_internal.h"
+
+typedef enum {
+       /* Fundamentals */
+       NSLFK_CATEGORY = 0,
+       NSLFK_LEVEL,
+       NSLFK_FILENAME,
+       NSLFK_DIRNAME,
+       NSLFK_FUNCNAME,
+       /* logical operations */
+       NSLFK_AND,
+       NSLFK_OR,
+       NSLFK_XOR,
+       NSLFK_NOT,
+} nslog_filter_kind;
+
+struct nslog_filter_s {
+       nslog_filter_kind kind;
+       int refcount;
+       union {
+               struct {
+                       char *ptr;
+                       int len;
+               } str;
+               nslog_level level;
+               nslog_filter_t *unary_input;
+               struct {
+                       nslog_filter_t *input1;
+                       nslog_filter_t *input2;
+               } binary;
+       } params;
+};
+
+static nslog_filter_t *nslog__active_filter = NULL;
+
+nslog_error nslog_filter_category_new(const char *catname,
+                                     nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_CATEGORY;
+       ret->refcount = 1;
+       ret->params.str.ptr = strdup(catname);
+       ret->params.str.len = strlen(catname);
+       if (ret->params.str.ptr == NULL) {
+               free(ret);
+               return NSLOG_NO_MEMORY;
+       }
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_level_new(nslog_level level,
+                                  nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_LEVEL;
+       ret->refcount = 1;
+       ret->params.level = level;
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_filename_new(const char *filename,
+                                     nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_FILENAME;
+       ret->refcount = 1;
+       ret->params.str.ptr = strdup(filename);
+       ret->params.str.len = strlen(filename);
+       if (ret->params.str.ptr == NULL) {
+               free(ret);
+               return NSLOG_NO_MEMORY;
+       }
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_dirname_new(const char *dirname,
+                                    nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_DIRNAME;
+       ret->refcount = 1;
+       ret->params.str.ptr = strdup(dirname);
+       ret->params.str.len = strlen(dirname);
+       if (ret->params.str.ptr == NULL) {
+               free(ret);
+               return NSLOG_NO_MEMORY;
+       }
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_funcname_new(const char *funcname,
+                                     nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_FUNCNAME;
+       ret->refcount = 1;
+       ret->params.str.ptr = strdup(funcname);
+       ret->params.str.len = strlen(funcname);
+       if (ret->params.str.ptr == NULL) {
+               free(ret);
+               return NSLOG_NO_MEMORY;
+       }
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+
+nslog_error nslog_filter_and_new(nslog_filter_t *left,
+                                nslog_filter_t *right,
+                                nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_AND;
+       ret->refcount = 1;
+       ret->params.binary.input1 = nslog_filter_ref(left);
+       ret->params.binary.input2 = nslog_filter_ref(right);
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_or_new(nslog_filter_t *left,
+                               nslog_filter_t *right,
+                               nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_OR;
+       ret->refcount = 1;
+       ret->params.binary.input1 = nslog_filter_ref(left);
+       ret->params.binary.input2 = nslog_filter_ref(right);
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_xor_new(nslog_filter_t *left,
+                                nslog_filter_t *right,
+                                nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_XOR;
+       ret->refcount = 1;
+       ret->params.binary.input1 = nslog_filter_ref(left);
+       ret->params.binary.input2 = nslog_filter_ref(right);
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+nslog_error nslog_filter_not_new(nslog_filter_t *input,
+                                nslog_filter_t **filter)
+{
+       nslog_filter_t *ret = calloc(sizeof(*ret), 1);
+       if (ret == NULL)
+               return NSLOG_NO_MEMORY;
+       ret->kind = NSLFK_NOT;
+       ret->refcount = 1;
+       ret->params.unary_input = nslog_filter_ref(input);
+       *filter = ret;
+       return NSLOG_NO_ERROR;
+}
+
+
+nslog_filter_t *nslog_filter_ref(nslog_filter_t *filter)
+{
+       if (filter != NULL)
+               filter->refcount++;
+
+       return filter;
+}
+
+nslog_filter_t *nslog_filter_unref(nslog_filter_t *filter)
+{
+       if (filter != NULL && filter->refcount-- == 1) {
+               switch(filter->kind) {
+               case NSLFK_CATEGORY:
+               case NSLFK_FILENAME:
+               case NSLFK_DIRNAME:
+               case NSLFK_FUNCNAME:
+                       free(filter->params.str.ptr);
+                       break;
+               case NSLFK_AND:
+               case NSLFK_OR:
+               case NSLFK_XOR:
+                       nslog_filter_unref(filter->params.binary.input1);
+                       nslog_filter_unref(filter->params.binary.input2);
+                       break;
+               case NSLFK_NOT:
+                       nslog_filter_unref(filter->params.unary_input);
+                       break;
+               default:
+                       /* Nothing to do for the other kind(s) */
+                       break;
+               }
+               free(filter);
+       }
+
+       return NULL;
+}
+
+nslog_error nslog_filter_set_active(nslog_filter_t *filter,
+                                   nslog_filter_t **prev)
+{
+       if (prev != NULL)
+               *prev = nslog__active_filter;
+       else
+               nslog_filter_unref(nslog__active_filter);
+
+       nslog__active_filter = nslog_filter_ref(filter);
+
+       return NSLOG_NO_ERROR;
+}
+
+static bool _nslog__filter_matches(nslog_entry_context_t *ctx,
+                                  nslog_filter_t *filter)
+{
+       switch (filter->kind) {
+       case NSLFK_CATEGORY:
+               if (filter->params.str.len > ctx->category->namelen)
+                       return false;
+               if (ctx->category->name[filter->params.str.len] != '\0' &&
+                   ctx->category->name[filter->params.str.len] != '/')
+                       return false;
+               return (strncmp(filter->params.str.ptr,
+                               ctx->category->name,
+                               filter->params.str.len) == 0);
+
+       case NSLFK_LEVEL:
+               return (ctx->level >= filter->params.level);
+       case NSLFK_FILENAME:
+               if (filter->params.str.len > ctx->filenamelen)
+                       return false;
+               if ((filter->params.str.len == ctx->filenamelen) &&
+                   (strcmp(filter->params.str.ptr, ctx->filename) == 0))
+                       return true;
+               if ((ctx->filename[ctx->filenamelen - filter->params.str.len - 
1] == '/')
+                   && (strcmp(filter->params.str.ptr,
+                              ctx->filename + ctx->filenamelen - 
filter->params.str.len) == 0))
+                       return true;
+               return false;
+       case NSLFK_DIRNAME:
+               if (filter->params.str.len >= ctx->filenamelen)
+                       return false;
+               if ((ctx->filename[filter->params.str.len] == '/')
+                   && (strncmp(filter->params.str.ptr,
+                               ctx->filename,
+                               filter->params.str.len) == 0))
+                       return true;
+               return false;
+       case NSLFK_FUNCNAME:
+               return (filter->params.str.len == ctx->funcnamelen &&
+                       strcmp(ctx->funcname, filter->params.str.ptr) == 0);
+       case NSLFK_AND:
+               return (_nslog__filter_matches(ctx, 
filter->params.binary.input1)
+                       &&
+                       _nslog__filter_matches(ctx, 
filter->params.binary.input2));
+       case NSLFK_OR:
+               return (_nslog__filter_matches(ctx, 
filter->params.binary.input1)
+                       ||
+                       _nslog__filter_matches(ctx, 
filter->params.binary.input2));
+       case NSLFK_XOR:
+               return (_nslog__filter_matches(ctx, 
filter->params.binary.input1)
+                       ^
+                       _nslog__filter_matches(ctx, 
filter->params.binary.input2));
+       case NSLFK_NOT:
+               return !_nslog__filter_matches(ctx, filter->params.unary_input);
+       default:
+               /* unknown */
+               assert("Unknown filter kind" == NULL);
+               return false;
+       }
+}
+
+bool nslog__filter_matches(nslog_entry_context_t *ctx)
+{
+       if (nslog__active_filter == NULL)
+               return true;
+       return _nslog__filter_matches(ctx, nslog__active_filter);
+}
diff --git a/src/nslog_internal.h b/src/nslog_internal.h
new file mode 100644
index 0000000..d5519e7
--- /dev/null
+++ b/src/nslog_internal.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017 Daniel Silverstone <[email protected]>
+ *
+ * This file is part of libnslog.
+ *
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * NetSurf Logging
+ */
+
+#ifndef NSLOG_INTERNAL_H_
+#define NSLOG_INTERNAL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "nslog/nslog.h"
+
+bool nslog__filter_matches(nslog_entry_context_t *ctx);
+
+#endif /* NSLOG_INTERNAL_H_ */
diff --git a/test/Makefile b/test/Makefile
index 0cebdaa..033033f 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := basic:basic.c
+DIR_TEST_ITEMS := basic:basic.c explicitfilter:explicitfilter.c
 
 include $(NSBUILD)/Makefile.subdir
diff --git a/test/basic.c b/test/basic.c
index 7626dd8..d514814 100644
--- a/test/basic.c
+++ b/test/basic.c
@@ -4,7 +4,7 @@
  * This file is part of libnslog.
  *
  * Licensed under the MIT License,
- *                http://www.opensource.org/licenses/mit-license.php
+ *               http://www.opensource.org/licenses/mit-license.php
  */
 
 #include "nslog/nslog.h"
@@ -18,10 +18,10 @@ static void test_render_function(
        const char *fmt, va_list args)
 {
        (void)ctx;
-        fprintf(stderr, "%s %s:%d [%s] %s() ",
-                nslog_level_name(ctx->level),
-                ctx->filename, ctx->lineno,
-                ctx->category->name,
+       fprintf(stderr, "%s %s:%d [%s] %s() ",
+               nslog_level_name(ctx->level),
+               ctx->filename, ctx->lineno,
+               ctx->category->name,
                ctx->funcname);
        vfprintf(stderr, fmt, args);
        fprintf(stderr, "\n");
diff --git a/test/explicitfilter.c b/test/explicitfilter.c
new file mode 100644
index 0000000..c7aca8a
--- /dev/null
+++ b/test/explicitfilter.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017 Daniel Silverstone <[email protected]>
+ *
+ * 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>
+#include <assert.h>
+
+NSLOG_DEFINE_CATEGORY(test, "Test category");
+
+static void test_render_function(
+       void *_ctx, nslog_entry_context_t *ctx,
+       const char *fmt, va_list args)
+{
+       (void)ctx;
+       fprintf(stderr, "%s %s:%d [%s] %s() ",
+               nslog_level_name(ctx->level),
+               ctx->filename, ctx->lineno,
+               ctx->category->name,
+               ctx->funcname);
+       vfprintf(stderr, fmt, args);
+       fprintf(stderr, "\n");
+}
+
+int main(int argc, char **argv)
+{
+       nslog_set_render_callback(test_render_function, NULL);
+       nslog_uncork();
+
+       nslog_filter_t *cat_test, *cat_another;
+
+       assert(nslog_filter_category_new("test", &cat_test) == NSLOG_NO_ERROR);
+       assert(nslog_filter_category_new("another", &cat_another) == 
NSLOG_NO_ERROR);
+
+       NSLOG(test, INFO, "Hurrah, a message!");
+       assert(nslog_filter_set_active(cat_test, NULL) == NSLOG_NO_ERROR);
+       NSLOG(test, INFO, "You should see me.");
+       assert(nslog_filter_set_active(cat_another, NULL) == NSLOG_NO_ERROR);
+       NSLOG(test, INFO, "You should not see me!");
+       assert(nslog_filter_set_active(NULL, NULL) == NSLOG_NO_ERROR);
+       NSLOG(test, INFO, "You should see this one though.");
+
+       return 0;
+}
diff --git a/test/runtest.sh b/test/runtest.sh
index 1b67a97..3bf903e 100755
--- a/test/runtest.sh
+++ b/test/runtest.sh
@@ -5,7 +5,7 @@ set -e
 TEST_PATH=$1
 TEST_PFX=$4
 
-for TEST in basic; do
+for TEST in basic explicitfilter; do
     ${TEST_PATH}/${TEST_PFX}${TEST}
 done
 


commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=8052642eadfb95b244f978b10889dff51f9133f5
commit 8052642eadfb95b244f978b10889dff51f9133f5
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Rework to only allocate one thing in the corked state and nothing in the 
uncorked state

diff --git a/include/nslog/nslog.h b/include/nslog/nslog.h
index fff31a7..ffa87bd 100644
--- a/include/nslog/nslog.h
+++ b/include/nslog/nslog.h
@@ -15,6 +15,8 @@
 #ifndef NSLOG_NSLOG_H_
 #define NSLOG_NSLOG_H_
 
+#include <stdarg.h>
+
 typedef enum {
         NSLOG_LEVEL_DEEPDEBUG = 0,
         NSLOG_LEVEL_DEBUG = 1,
@@ -45,16 +47,15 @@ typedef struct nslog_category_s {
         struct nslog_category_s *next;
 } nslog_category_t;
 
-typedef struct nslog_entry_s {
+typedef struct nslog_entry_context_s {
         nslog_category_t *category;
         nslog_level level;
         const char *filename;
        const char *funcname;
         int lineno;
-        char message[0]; /* NUL terminated */
-} nslog_entry_t;
+} nslog_entry_context_t;
 
-#define NSLOG_DECLARE_CATEGORY(catname)                \
+#define NSLOG_DECLARE_CATEGORY(catname)                                \
        extern nslog_category_t __nslog_category_##catname
 
 #define NSLOG_DEFINE_CATEGORY(catname, description)    \
@@ -75,31 +76,31 @@ typedef struct nslog_entry_s {
                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,
+#define NSLOG(catname, level, logmsg, args...)                         \
+       do {                                                            \
+               if (NSLOG_LEVEL_##level >= NSLOG_COMPILED_MIN_LEVEL) {  \
+                       nslog_entry_context_t ctx = {                   \
+                               &__nslog_category_##catname,            \
+                               NSLOG_LEVEL_##level,                    \
+                               __FILE__,                               \
+                               __PRETTY_FUNCTION__,                    \
+                               __LINE__,                               \
+                       };                                              \
+                       nslog__log(&ctx, logmsg, ##args);               \
+               }                                                       \
+       } while(0)
+
+void nslog__log(nslog_entry_context_t *ctx,
                const char *pattern,
-               ...) __attribute__ ((format (printf, 6, 7)));
+               ...) __attribute__ ((format (printf, 2, 3)));
 
 typedef enum {
        NSLOG_NO_ERROR = 0,
        NSLOG_NO_MEMORY = 1,
 } nslog_error;
 
-typedef void (*nslog_callback)(void *context, nslog_entry_t *msg);
+typedef void (*nslog_callback)(void *context, nslog_entry_context_t *ctx,
+                              const char *fmt, va_list args);
 
 nslog_error nslog_set_render_callback(nslog_callback cb, void *context);
 
diff --git a/src/core.c b/src/core.c
index 0665195..ee5f2bc 100644
--- a/src/core.c
+++ b/src/core.c
@@ -20,12 +20,14 @@
 #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;
+       nslog_entry_context_t context;
+        char message[0]; /* NUL terminated */
+} *nslog__cork_chain = NULL, *nslog__cork_chain_last = NULL;
 
 static nslog_callback nslog__cb = NULL;
 static void *nslog__cb_ctx = NULL;
@@ -70,58 +72,56 @@ static void nslog__normalise_category(nslog_category_t *cat)
        }
 }
 
-static void nslog__deliver(nslog_entry_t *entry)
+static void nslog__log_corked(nslog_entry_context_t *ctx,
+                             int measured_len,
+                             const char *fmt,
+                             va_list args)
+{
+       /* If corked, we need to store a copy */
+       struct nslog_cork_chain *newcork = malloc(sizeof(*newcork) + 
measured_len + 1);
+       if (newcork == NULL) {
+               /* Wow, something went wrong */
+               return;
+       }
+       newcork->context = *ctx;
+       vsprintf(newcork->message, fmt, args);
+       if (nslog__cork_chain == NULL) {
+               nslog__cork_chain = nslog__cork_chain_last = newcork;
+       } else {
+               nslog__cork_chain_last->next = newcork;
+               nslog__cork_chain_last = newcork;
+       }
+}
+
+static void nslog__log_uncorked(nslog_entry_context_t *ctx,
+                               const char *fmt,
+                               va_list args)
 {
        /* TODO: Add filtering here */
        if (nslog__cb != NULL) {
-               if (entry->category->name == NULL) {
-                       nslog__normalise_category(entry->category);
+               if (ctx->category->name == NULL) {
+                       nslog__normalise_category(ctx->category);
                }
-               (*nslog__cb)(nslog__cb_ctx, entry);
+               (*nslog__cb)(nslog__cb_ctx, ctx, fmt, args);
        }
 }
 
-void nslog__log(nslog_category_t *category,
-               nslog_level level,
-               const char *filename,
-               int lineno,
-               const char *funcname,
+void nslog__log(nslog_entry_context_t *ctx,
                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;
+               va_list ap2;
+               va_copy(ap2, ap);
+               int slen = vsnprintf(NULL, 0, pattern, ap);
+               va_end(ap);
+               nslog__log_corked(ctx, slen, pattern, ap2);
+               va_end(ap2);
        } else {
-               /* Not corked */
-               nslog__deliver(entry);
-               free(entry);
+               nslog__log_uncorked(ctx, pattern, ap);
+               va_end(ap);
        }
 }
 
@@ -133,14 +133,30 @@ nslog_error nslog_set_render_callback(nslog_callback cb, 
void *context)
        return NSLOG_NO_ERROR;
 }
 
+
+static void __nslog__deliver_corked_entry(nslog_entry_context_t *ctx,
+                                         const char *fmt,
+                                         ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       if (nslog__cb != NULL) {
+               (*nslog__cb)(nslog__cb_ctx, ctx, fmt, args);
+       }
+       va_end(args);
+}
+
 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);
+                       if (ent->context.category->name == NULL) {
+                               
nslog__normalise_category(ent->context.category);
+                       }
+                       __nslog__deliver_corked_entry(&ent->context,
+                                                     "%s", ent->message);
                        free(ent);
                }
                nslog__corked = false;
diff --git a/test/basic.c b/test/basic.c
index fd40633..7626dd8 100644
--- a/test/basic.c
+++ b/test/basic.c
@@ -13,21 +13,29 @@
 
 NSLOG_DEFINE_CATEGORY(test, "Test category");
 
-static void test_render_function(void *ctx, nslog_entry_t *log)
+static void test_render_function(
+       void *_ctx, nslog_entry_context_t *ctx,
+       const char *fmt, va_list args)
 {
        (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);
+        fprintf(stderr, "%s %s:%d [%s] %s() ",
+                nslog_level_name(ctx->level),
+                ctx->filename, ctx->lineno,
+                ctx->category->name,
+               ctx->funcname);
+       vfprintf(stderr, fmt, args);
+       fprintf(stderr, "\n");
 }
 
 int main(int argc, char **argv)
 {
        nslog_set_render_callback(test_render_function, NULL);
+       NSLOG(test, INFO, "Pre-uncorking");
+       fprintf(stderr, "About to nslog_uncork()\n");
        nslog_uncork();
+       fprintf(stderr, "Uncorked now\n");
        NSLOG(test, WARN, "argc=%d", argc);
+       for (int i = 0; i < argc; ++i)
+               NSLOG(test, WARN, "argv[%d] = %s", i, argv[i]);
        return 0;
 }


commitdiff 
http://git.netsurf-browser.org/libnslog.git/commit/?id=551cf378a93588d42732983ec30716e14afef945
commit 551cf378a93588d42732983ec30716e14afef945
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Initial version

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 <[email protected]>
+
+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 <[email protected]>
+# Copyright 2017 Daniel Silverstone <[email protected]>
+
+# 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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


-----------------------------------------------------------------------


-- 
NetSurf Parametric Logging Library

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to