Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4363 → Rev 4364

/contrib/network/netsurf/libwapcaplet/.gitignore
0,0 → 1,3
build-*
Makefile.config.override
 
/contrib/network/netsurf/libwapcaplet/COPYING
0,0 → 1,19
Copyright 2009 The NetSurf Browser Project
 
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.
/contrib/network/netsurf/libwapcaplet/Makefile
0,0 → 1,47
# Component settings
COMPONENT := wapcaplet
COMPONENT_VERSION := 0.1.1
# 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 = $(BUILDDIR)/test_testrunner$(EXEEXT)
 
# Toolchain flags
WARNFLAGS := -Wall -W -Wundef -Wpointer-arith -Wcast-align \
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wnested-externs
# BeOS/Haiku standard library headers issue warnings
ifneq ($(TARGET),beos)
WARNFLAGS := $(WARNFLAGS) -Werror
endif
CFLAGS := -D_BSD_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
 
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 := /include/libwapcaplet
INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/libwapcaplet/libwapcaplet.h
INSTALL_ITEMS := $(INSTALL_ITEMS) /lib/pkgconfig:lib$(COMPONENT).pc.in
INSTALL_ITEMS := $(INSTALL_ITEMS) /lib:$(OUTPUT)
/contrib/network/netsurf/libwapcaplet/README
0,0 → 1,65
LibWapcaplet - a string internment library
==========================================
 
Overview
--------
 
LibWapcaplet provides a reference counted string internment system
designed to store small strings and allow rapid comparison of them in
terms of equality. It supports a caseless comparison where it will
automatically intern a lowercased variant of the string and use that
for comparison if needed.
 
Rationale
---------
 
Prior to LibWapcaplet, LibParserUtils contained a dictionary and hash
implementation along with a red-black tree implementation
internally. These three things were then used by client applications
and libraries such as LibCSS. However, the code was deemed to be
inefficient and the features in the wrong library. The behaviour
required of the client libraries was therefore split out so that
internment would still be able to be shared between different client
libraries in the same application. (E.g. LibCSS and Hubbub)
 
For those interested, The name 'Wapcaplet' is from the Monty Python
sketch in which Mr Simpson (who is not French) attempts to sell
122,000 miles of string which was unfortunately cut up into 3 inch
lengths, and Adrian Wapcaplet comes up with the idea of "Simpson's
individual emperor stringettes - Just the right length!"
 
Requirements
------------
 
To compile LibWapcaplet you need:
 
* GNU Make 3.81 or better
* A version of GCC capable of -MMD -MF (unless you change the build
system)
 
To compile the test suite you need:
 
* Check v0.9.5 or better.
 
Compilation
-----------
 
To build LibWapcaplet in release mode, type 'make'. To build it in
debug mode type 'make BUILD=debug'. To install, run 'make
install'. If you wish to install LibWapcaplet into somewhere other
than /usr/local/ then add PREFIX=/path/to/place to the installation
make command.
 
Verification
------------
 
To build and run the tests, run 'make test'.
 
In release mode, fewer tests will be run as the assert() calls will be
elided.
 
API documentation
-----------------
 
For API documentation see include/libwapcaplet/libwapcaplet.h
 
/contrib/network/netsurf/libwapcaplet/include/libwapcaplet/libwapcaplet.h
0,0 → 1,254
/* libwapcaplet.h
*
* String internment and management tools.
*
* Copyright 2009 The NetSurf Browser Project.
* Daniel Silverstone <dsilvers@netsurf-browser.org>
*/
 
#ifndef libwapcaplet_h_
#define libwapcaplet_h_
 
#ifdef __cplusplus
extern "C"
{
#endif
 
#include <sys/types.h>
#include <stdbool.h>
#include <stdint.h>
 
/**
* The type of a reference counter used in libwapcaplet.
*/
typedef uint32_t lwc_refcounter;
/**
* The type of a hash value used in libwapcaplet.
*/
typedef uint32_t lwc_hash;
 
/**
* An interned string.
*
* NOTE: The contents of this struct are considered *PRIVATE* and may
* change in future revisions. Do not rely on them whatsoever.
* They're only here at all so that the ref, unref and matches etc can
* use them.
*/
typedef struct lwc_string_s {
struct lwc_string_s ** prevptr;
struct lwc_string_s * next;
size_t len;
lwc_hash hash;
lwc_refcounter refcnt;
struct lwc_string_s * insensitive;
} lwc_string;
/**
* String iteration function
*
* @param str A string which has been interned.
* @param pw The private pointer for the allocator.
*/
typedef void (*lwc_iteration_callback_fn)(lwc_string *str, void *pw);
 
/**
* Result codes which libwapcaplet might return.
*/
typedef enum lwc_error_e {
lwc_error_ok = 0, /**< No error. */
lwc_error_oom = 1, /**< Out of memory. */
lwc_error_range = 2 /**< Substring internment out of range. */
} lwc_error;
 
/**
* Intern a string.
*
* Take a copy of the string data referred to by \a s and \a slen and
* intern it. The resulting ::lwc_string can be used for simple and
* caseless comparisons by ::lwc_string_isequal and
* ::lwc_string_caseless_isequal respectively.
*
* @param s Pointer to the start of the string to intern.
* @param slen Length of the string in characters. (Not including any
* terminators)
* @param ret Pointer to ::lwc_string pointer to fill out.
* @return Result of operation, if not OK then the value pointed
* to by \a ret will not be valid.
*
* @note The memory pointed to by \a s is not referenced by the result.
* @note If the string was already present, its reference count is
* incremented rather than allocating more memory.
*
* @note The returned string is currently NULL-terminated but this
* will not necessarily be the case in future. Try not to rely
* on it.
*/
extern lwc_error lwc_intern_string(const char *s, size_t slen,
lwc_string **ret);
 
/**
* Intern a substring.
*
* Intern a subsequence of the provided ::lwc_string.
*
* @param str String to acquire substring from.
* @param ssoffset Substring offset into \a str.
* @param sslen Substring length.
* @param ret Pointer to pointer to ::lwc_string to fill out.
* @return Result of operation, if not OK then the value
* pointed to by \a ret will not be valid.
*/
extern lwc_error lwc_intern_substring(lwc_string *str,
size_t ssoffset, size_t sslen,
lwc_string **ret);
 
/**
* Increment the reference count on an lwc_string.
*
* This increases the reference count on the given string. You should
* use this when copying a string pointer into a persistent data
* structure.
*
* @verb
* myobject->str = lwc_string_ref(myparent->str);
* @endverb
*
* @param str The string to create another reference to.
* @return The string pointer to use in your new data structure.
*
* @note Use this if copying the string and intending both sides to retain
* ownership.
*/
#define lwc_string_ref(str) ({lwc_string *__lwc_s = (str); __lwc_s->refcnt++; __lwc_s;})
 
/**
* Release a reference on an lwc_string.
*
* This decreases the reference count on the given ::lwc_string.
*
* @param str The string to unref.
*
* @note If the reference count reaches zero then the string will be
* freed. (Ref count of 1 where string is its own insensitve match
* will also result in the string being freed.)
*/
#define lwc_string_unref(str) { \
lwc_string *__lwc_s = (str); \
__lwc_s->refcnt--; \
if ((__lwc_s->refcnt == 0) || \
((__lwc_s->refcnt == 1) && (__lwc_s->insensitive == __lwc_s))) \
lwc_string_destroy(__lwc_s); \
}
/**
* Destroy an unreffed lwc_string.
*
* This destroys an lwc_string whose reference count indicates that it should be.
*
* @param str The string to unref.
*/
extern void lwc_string_destroy(lwc_string *str);
 
/**
* Check if two interned strings are equal.
*
* @param str1 The first string in the comparison.
* @param str2 The second string in the comparison.
* @param ret A pointer to a boolean to be filled out with the result.
* @return Result of operation, if not ok then value pointed to
* by \a ret will not be valid.
*/
#define lwc_string_isequal(str1, str2, ret) \
((*(ret) = ((str1) == (str2))), lwc_error_ok)
 
/**
* Check if two interned strings are case-insensitively equal.
*
* @param str1 The first string in the comparison.
* @param str2 The second string in the comparison.
* @param ret A pointer to a boolean to be filled out with the result.
* @return Result of operation, if not ok then value pointed to
* by \a ret will not be valid.
*/
#define lwc_string_caseless_isequal(_str1,_str2,_ret) ({ \
lwc_error __lwc_err = lwc_error_ok; \
lwc_string *__lwc_str1 = (_str1); \
lwc_string *__lwc_str2 = (_str2); \
bool *__lwc_ret = (_ret); \
\
if (__lwc_str1->insensitive == NULL) { \
__lwc_err = lwc__intern_caseless_string(__lwc_str1); \
} \
if (__lwc_err == lwc_error_ok && __lwc_str2->insensitive == NULL) { \
__lwc_err = lwc__intern_caseless_string(__lwc_str2); \
} \
if (__lwc_err == lwc_error_ok) \
*__lwc_ret = (__lwc_str1->insensitive == __lwc_str2->insensitive); \
__lwc_err; \
})
/**
* Intern a caseless copy of the passed string.
*
* @param str The string to intern the caseless copy of.
*
* @return lwc_error_ok if successful, otherwise the
* error code describing the issue.,
*
* @note This is for "internal" use by the caseless comparison
* macro and not for users.
*/
extern lwc_error
lwc__intern_caseless_string(lwc_string *str);
/**
* Retrieve the data pointer for an interned string.
*
* @param str The string to retrieve the data pointer for.
* @return The C string data pointer for \a str.
*
* @note The data we point at belongs to the string and will
* die with the string. Keep a ref if you need it.
* @note You may not rely on the NULL termination of the strings
* in future. Any code relying on it currently should be
* modified to use ::lwc_string_length if possible.
*/
#define lwc_string_data(str) ((const char *)((str)+1))
 
/**
* Retrieve the data length for an interned string.
*
* @param str The string to retrieve the length of.
* @return The length of \a str.
*/
#define lwc_string_length(str) ((str)->len)
 
/**
* Retrieve (or compute if unavailable) a hash value for the content of the string.
*
* @param str The string to get the hash for.
* @return The 32 bit hash of \a str.
*
* @note This API should only be used as a convenient way to retrieve a hash
* value for the string. This hash value should not be relied on to be
* unique within an invocation of the program, nor should it be relied upon
* to be stable between invocations of the program. Never use the hash
* value as a way to directly identify the value of the string.
*/
#define lwc_string_hash_value(str) ((str)->hash)
 
/**
* Iterate the context and return every string in it.
*
* @param cb The callback to give the string to.
* @param pw The private word for the callback.
*/
extern void lwc_iterate_strings(lwc_iteration_callback_fn cb, void *pw);
 
#ifdef __cplusplus
}
#endif
 
#endif /* libwapcaplet_h_ */
/contrib/network/netsurf/libwapcaplet/libwapcaplet.pc.in
0,0 → 1,10
prefix=PREFIX
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
 
Name: libwapcaplet
Description: String internalisation dictionary
Version: VERSION
Libs: -L${libdir} -lwapcaplet
Cflags: -I${includedir}
/contrib/network/netsurf/libwapcaplet/src/Makefile
0,0 → 1,4
OUTFILE = libwapcaplet.a
OBJS = libwapcaplet.o
CFLAGS += -I ../include/
include $(MENUETDEV)/makefiles/Makefile_for_lib
/contrib/network/netsurf/libwapcaplet/src/libwapcaplet.c
0,0 → 1,258
/* libwapcaplet.c
*
* String internment and management tools.
*
* Copyright 2009 The NetSurf Browser Project.
* Daniel Silverstone <dsilvers@netsurf-browser.org>
*/
 
#include <stdlib.h>
#include <string.h>
#include <assert.h>
 
#include "libwapcaplet/libwapcaplet.h"
 
#ifndef UNUSED
#define UNUSED(x) ((x) = (x))
#endif
 
static inline lwc_hash
lwc__calculate_hash(const char *str, size_t len)
{
lwc_hash z = 0x811c9dc5;
 
while (len > 0) {
z *= 0x01000193;
z ^= *str++;
len--;
}
 
return z;
}
 
#define STR_OF(str) ((char *)(str + 1))
#define CSTR_OF(str) ((const char *)(str + 1))
 
#define NR_BUCKETS_DEFAULT (4091)
 
typedef struct lwc_context_s {
lwc_string ** buckets;
lwc_hash bucketcount;
} lwc_context;
 
static lwc_context *ctx = NULL;
 
#define LWC_ALLOC(s) malloc(s)
#define LWC_FREE(p) free(p)
 
typedef lwc_hash (*lwc_hasher)(const char *, size_t);
typedef int (*lwc_strncmp)(const char *, const char *, size_t);
typedef void (*lwc_memcpy)(char *, const char *, size_t);
 
static lwc_error
lwc__initialise(void)
{
if (ctx != NULL)
return lwc_error_ok;
ctx = LWC_ALLOC(sizeof(lwc_context));
if (ctx == NULL)
return lwc_error_oom;
memset(ctx, 0, sizeof(lwc_context));
ctx->bucketcount = NR_BUCKETS_DEFAULT;
ctx->buckets = LWC_ALLOC(sizeof(lwc_string *) * ctx->bucketcount);
if (ctx->buckets == NULL) {
LWC_FREE(ctx);
ctx = NULL;
return lwc_error_oom;
}
memset(ctx->buckets, 0, sizeof(lwc_string *) * ctx->bucketcount);
return lwc_error_ok;
}
 
static lwc_error
lwc__intern(const char *s, size_t slen,
lwc_string **ret,
lwc_hasher hasher,
lwc_strncmp compare,
lwc_memcpy copy)
{
lwc_hash h;
lwc_hash bucket;
lwc_string *str;
lwc_error eret;
assert((s != NULL) || (slen == 0));
assert(ret);
if (ctx == NULL) {
eret = lwc__initialise();
if (eret != lwc_error_ok)
return eret;
}
h = hasher(s, slen);
bucket = h % ctx->bucketcount;
str = ctx->buckets[bucket];
while (str != NULL) {
if ((str->hash == h) && (str->len == slen)) {
if (compare(CSTR_OF(str), s, slen) == 0) {
str->refcnt++;
*ret = str;
return lwc_error_ok;
}
}
str = str->next;
}
/* Add one for the additional NUL. */
*ret = str = LWC_ALLOC(sizeof(lwc_string) + slen + 1);
if (str == NULL)
return lwc_error_oom;
str->prevptr = &(ctx->buckets[bucket]);
str->next = ctx->buckets[bucket];
if (str->next != NULL)
str->next->prevptr = &(str->next);
ctx->buckets[bucket] = str;
 
str->len = slen;
str->hash = h;
str->refcnt = 1;
str->insensitive = NULL;
copy(STR_OF(str), s, slen);
 
/* Guarantee NUL termination */
STR_OF(str)[slen] = '\0';
return lwc_error_ok;
}
 
lwc_error
lwc_intern_string(const char *s, size_t slen,
lwc_string **ret)
{
return lwc__intern(s, slen, ret,
lwc__calculate_hash,
strncmp, (lwc_memcpy)memcpy);
}
 
lwc_error
lwc_intern_substring(lwc_string *str,
size_t ssoffset, size_t sslen,
lwc_string **ret)
{
assert(str);
assert(ret);
if (ssoffset >= str->len)
return lwc_error_range;
if ((ssoffset + sslen) > str->len)
return lwc_error_range;
return lwc_intern_string(CSTR_OF(str) + ssoffset, sslen, ret);
}
 
void
lwc_string_destroy(lwc_string *str)
{
assert(str);
*(str->prevptr) = str->next;
if (str->next != NULL)
str->next->prevptr = str->prevptr;
 
if (str->insensitive != NULL && str->refcnt == 0)
lwc_string_unref(str->insensitive);
 
#ifndef NDEBUG
memset(str, 0xA5, sizeof(*str) + str->len);
#endif
LWC_FREE(str);
}
 
/**** Shonky caseless bits ****/
 
static inline char
lwc__dolower(const char c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
return c;
}
 
static inline lwc_hash
lwc__calculate_lcase_hash(const char *str, size_t len)
{
lwc_hash z = 0x811c9dc5;
 
while (len > 0) {
z *= 0x01000193;
z ^= lwc__dolower(*str++);
len--;
}
 
return z;
}
 
static int
lwc__lcase_strncmp(const char *s1, const char *s2, size_t n)
{
while (n--) {
if (*s1++ != lwc__dolower(*s2++))
/** @todo Test this somehow? */
return 1;
}
return 0;
}
 
static void
lwc__lcase_memcpy(char *target, const char *source, size_t n)
{
while (n--) {
*target++ = lwc__dolower(*source++);
}
}
 
lwc_error
lwc__intern_caseless_string(lwc_string *str)
{
assert(str);
assert(str->insensitive == NULL);
return lwc__intern(CSTR_OF(str),
str->len, &(str->insensitive),
lwc__calculate_lcase_hash,
lwc__lcase_strncmp,
lwc__lcase_memcpy);
}
 
/**** Iteration ****/
 
void
lwc_iterate_strings(lwc_iteration_callback_fn cb, void *pw)
{
lwc_hash n;
lwc_string *str;
if (ctx == NULL)
return;
for (n = 0; n < ctx->bucketcount; ++n) {
for (str = ctx->buckets[n]; str != NULL; str = str->next)
cb(str, pw);
}
}
/contrib/network/netsurf/libwapcaplet/test/Makefile
0,0 → 1,3
DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c
 
include $(NSBUILD)/Makefile.subdir
/contrib/network/netsurf/libwapcaplet/test/basictests.c
0,0 → 1,417
/* test/basictests.c
*
* Basic tests for the test suite for libwapcaplet
*
* Copyright 2009 The NetSurf Browser Project
* Daniel Silverstone <dsilvers@netsurf-browser.org>
*/
 
#include <check.h>
#include <stdlib.h>
#include <string.h>
 
#include "tests.h"
 
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
 
#ifndef NDEBUG
/* All the basic assert() tests */
START_TEST (test_lwc_intern_string_aborts1)
{
lwc_intern_string(NULL, 0, NULL);
}
END_TEST
 
START_TEST (test_lwc_intern_string_aborts2)
{
lwc_intern_string("A", 1, NULL);
}
END_TEST
 
START_TEST (test_lwc_intern_substring_aborts1)
{
lwc_intern_substring(NULL, 0, 0, NULL);
}
END_TEST
 
START_TEST (test_lwc_intern_substring_aborts2)
{
lwc_string *str;
fail_unless(lwc_intern_string("Jam", 3, &str) == lwc_error_ok,
"unable to intern 'Jam'");
lwc_intern_substring(str, 88, 77, NULL);
}
END_TEST
 
START_TEST (test_lwc_string_ref_aborts)
{
lwc_string_ref(NULL);
}
END_TEST
 
START_TEST (test_lwc_string_unref_aborts)
{
lwc_string_unref(NULL);
}
END_TEST
 
START_TEST (test_lwc_string_data_aborts)
{
lwc_string_data(NULL);
}
END_TEST
 
START_TEST (test_lwc_string_length_aborts)
{
lwc_string_length(NULL);
}
END_TEST
 
START_TEST (test_lwc_string_hash_value_aborts)
{
lwc_string_hash_value(NULL);
}
END_TEST
 
#endif
 
/**** The next set of tests need a fixture set ****/
 
static void
with_simple_context_setup(void)
{
/* Nothing to set up */
}
 
static void
with_simple_context_teardown(void)
{
/* Nothing to do to tear down */
}
 
START_TEST (test_lwc_intern_string_ok)
{
lwc_string *str = NULL;
fail_unless(lwc_intern_string("A", 1, &str) == lwc_error_ok,
"Unable to intern a simple string");
fail_unless(str != NULL,
"Returned OK but str was still NULL");
}
END_TEST
 
START_TEST (test_lwc_intern_string_twice_ok)
{
lwc_string *str1 = NULL, *str2 = NULL;
fail_unless(lwc_intern_string("A", 1, &str1) == lwc_error_ok,
"Unable to intern a simple string");
fail_unless(str1 != NULL,
"Returned OK but str was still NULL");
fail_unless(lwc_intern_string("B", 1, &str2) == lwc_error_ok,
"Unable to intern a simple string");
fail_unless(str2 != NULL,
"Returned OK but str was still NULL");
}
END_TEST
 
START_TEST (test_lwc_intern_string_twice_same_ok)
{
lwc_string *str1 = NULL, *str2 = NULL;
fail_unless(lwc_intern_string("A", 1, &str1) == lwc_error_ok,
"Unable to intern a simple string");
fail_unless(str1 != NULL,
"Returned OK but str was still NULL");
fail_unless(lwc_intern_string("A", 1, &str2) == lwc_error_ok,
"Unable to intern a simple string");
fail_unless(str2 != NULL,
"Returned OK but str was still NULL");
}
END_TEST
 
/**** The next set of tests need a fixture set with some strings ****/
 
static lwc_string *intern_one = NULL, *intern_two = NULL, *intern_three = NULL, *intern_YAY = NULL;
 
static void
with_filled_context_setup(void)
{
fail_unless(lwc_intern_string("one", 3, &intern_one) == lwc_error_ok,
"Unable to intern 'one'");
fail_unless(lwc_intern_string("two", 3, &intern_two) == lwc_error_ok,
"Unable to intern 'two'");
fail_unless(lwc_intern_string("three", 5, &intern_three) == lwc_error_ok,
"Unable to intern 'three'");
fail_unless(lwc_intern_string("YAY", 3, &intern_YAY) == lwc_error_ok,
"Unable to intern 'YAY'");
fail_unless(intern_one != intern_two, "'one' == 'two'");
fail_unless(intern_one != intern_three, "'one' == 'three'");
fail_unless(intern_two != intern_three, "'two' == 'three'");
}
 
static void
with_filled_context_teardown(void)
{
lwc_string_unref(intern_one);
lwc_string_unref(intern_two);
lwc_string_unref(intern_three);
lwc_string_unref(intern_YAY);
}
 
START_TEST (test_lwc_interning_works)
{
lwc_string *new_one = NULL;
fail_unless(lwc_intern_string("one", 3, &new_one) == lwc_error_ok,
"Unable to re-intern 'one'");
fail_unless(new_one == intern_one,
"Internalising of the string failed");
}
END_TEST
 
START_TEST (test_lwc_intern_substring)
{
lwc_string *new_hre = NULL, *sub_hre = NULL;
fail_unless(lwc_intern_string("hre", 3, &new_hre) == lwc_error_ok,
"Unable to intern 'hre'");
fail_unless(lwc_intern_substring(intern_three,
1, 3, &sub_hre) == lwc_error_ok,
"Unable to re-intern 'hre' by substring");
fail_unless(new_hre == sub_hre,
"'hre' != 'hre' -- wow!");
}
END_TEST
 
START_TEST (test_lwc_intern_substring_bad_offset)
{
lwc_string *str;
fail_unless(lwc_intern_substring(intern_three, 100, 1, &str) == lwc_error_range,
"Able to intern substring starting out of range");
}
END_TEST
 
START_TEST (test_lwc_intern_substring_bad_size)
{
lwc_string *str;
fail_unless(lwc_intern_substring(intern_three, 1, 100, &str) == lwc_error_range,
"Able to intern substring ending out of range");
}
END_TEST
 
START_TEST (test_lwc_string_ref_ok)
{
fail_unless(lwc_string_ref(intern_one) == intern_one,
"Oddly, reffing a string didn't return it");
}
END_TEST
 
START_TEST (test_lwc_string_unref_ok)
{
lwc_string_unref(intern_one);
}
END_TEST
 
START_TEST (test_lwc_string_ref_unref_ok)
{
lwc_string_ref(intern_one);
lwc_string_unref(intern_one);
}
END_TEST
 
START_TEST (test_lwc_string_isequal_ok)
{
bool result = true;
fail_unless((lwc_string_isequal(intern_one, intern_two, &result)) == lwc_error_ok,
"Failure comparing 'one' and 'two'");
fail_unless(result == false,
"'one' == 'two' ?!");
}
END_TEST
 
START_TEST (test_lwc_string_caseless_isequal_ok1)
{
bool result = true;
lwc_string *new_ONE;
fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok,
"Failure interning 'ONE'");
fail_unless((lwc_string_isequal(intern_one, new_ONE, &result)) == lwc_error_ok);
fail_unless(result == false,
"'one' == 'ONE' ?!");
fail_unless((lwc_string_caseless_isequal(intern_one, new_ONE, &result)) == lwc_error_ok,
"Failure comparing 'one' and 'ONE' caselessly");
fail_unless(result == true,
"'one' !~= 'ONE' ?!");
}
END_TEST
 
START_TEST (test_lwc_string_caseless_isequal_ok2)
{
bool result = true;
lwc_string *new_yay;
fail_unless(lwc_intern_string("yay", 3, &new_yay) == lwc_error_ok,
"Failure interning 'yay'");
fail_unless((lwc_string_isequal(intern_YAY, new_yay, &result)) == lwc_error_ok);
fail_unless(result == false,
"'yay' == 'YAY' ?!");
fail_unless((lwc_string_caseless_isequal(intern_YAY, new_yay, &result)) == lwc_error_ok,
"Failure comparing 'yay' and 'YAY' caselessly");
fail_unless(result == true,
"'yay' !~= 'YAY' ?!");
}
END_TEST
 
START_TEST (test_lwc_string_caseless_isequal_bad)
{
bool result = true;
fail_unless(lwc_string_caseless_isequal(intern_YAY, intern_one, &result) == lwc_error_ok,
"Failure comparing 'YAY' and 'one' caselessly");
fail_unless(result == false,
"'YAY' ~= 'one' ?!");
}
END_TEST
 
START_TEST (test_lwc_extract_data_ok)
{
fail_unless(memcmp("one",
lwc_string_data(intern_one),
lwc_string_length(intern_one)) == 0,
"Extracting data ptr etc failed");
}
END_TEST
 
START_TEST (test_lwc_string_hash_value_ok)
{
(void)lwc_string_hash_value(intern_one);
}
END_TEST
 
START_TEST (test_lwc_string_is_nul_terminated)
{
lwc_string *new_ONE;
 
fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok,
"Failure interning 'ONE'");
 
fail_unless(lwc_string_data(new_ONE)[lwc_string_length(new_ONE)] == '\0',
"Interned string isn't NUL terminated");
}
END_TEST
 
START_TEST (test_lwc_substring_is_nul_terminated)
{
lwc_string *new_ONE;
lwc_string *new_O;
 
fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok,
"Failure interning 'ONE'");
 
fail_unless(lwc_intern_substring(new_ONE, 0, 1, &new_O) == lwc_error_ok,
"Failure interning substring 'O'");
 
fail_unless(lwc_string_data(new_O)[lwc_string_length(new_O)] == '\0',
"Interned substring isn't NUL terminated");
}
END_TEST
 
static void
counting_cb(lwc_string *str, void *pw)
{
UNUSED(str);
*((int *)pw) += 1;
}
 
START_TEST (test_lwc_string_iteration)
{
int counter = 0;
lwc_iterate_strings(counting_cb, (void*)&counter);
fail_unless(counter == 4, "Incorrect string count");
}
END_TEST
 
/**** And the suites are set up here ****/
 
void
lwc_basic_suite(SRunner *sr)
{
Suite *s = suite_create("libwapcaplet: Basic tests");
TCase *tc_basic = tcase_create("Creation/Destruction");
#ifndef NDEBUG
tcase_add_test_raise_signal(tc_basic,
test_lwc_intern_string_aborts1,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_intern_string_aborts2,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_intern_substring_aborts1,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_intern_substring_aborts2,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_string_ref_aborts,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_string_unref_aborts,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_string_data_aborts,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
test_lwc_string_length_aborts,
SIGABRT);
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("Ops with a context");
tcase_add_checked_fixture(tc_basic, with_simple_context_setup,
with_simple_context_teardown);
tcase_add_test(tc_basic, test_lwc_intern_string_ok);
tcase_add_test(tc_basic, test_lwc_intern_string_twice_ok);
tcase_add_test(tc_basic, test_lwc_intern_string_twice_same_ok);
suite_add_tcase(s, tc_basic);
tc_basic = tcase_create("Ops with a filled context");
tcase_add_checked_fixture(tc_basic, with_filled_context_setup,
with_filled_context_teardown);
tcase_add_test(tc_basic, test_lwc_interning_works);
tcase_add_test(tc_basic, test_lwc_intern_substring);
tcase_add_test(tc_basic, test_lwc_string_ref_ok);
tcase_add_test(tc_basic, test_lwc_string_ref_unref_ok);
tcase_add_test(tc_basic, test_lwc_string_unref_ok);
tcase_add_test(tc_basic, test_lwc_string_isequal_ok);
tcase_add_test(tc_basic, test_lwc_string_caseless_isequal_ok1);
tcase_add_test(tc_basic, test_lwc_string_caseless_isequal_ok2);
tcase_add_test(tc_basic, test_lwc_string_caseless_isequal_bad);
tcase_add_test(tc_basic, test_lwc_extract_data_ok);
tcase_add_test(tc_basic, test_lwc_string_hash_value_ok);
tcase_add_test(tc_basic, test_lwc_string_is_nul_terminated);
tcase_add_test(tc_basic, test_lwc_substring_is_nul_terminated);
tcase_add_test(tc_basic, test_lwc_intern_substring_bad_size);
tcase_add_test(tc_basic, test_lwc_intern_substring_bad_offset);
tcase_add_test(tc_basic, test_lwc_string_iteration);
suite_add_tcase(s, tc_basic);
srunner_add_suite(sr, s);
}
/contrib/network/netsurf/libwapcaplet/test/testmain.c
0,0 → 1,43
/* test/testmain.c
*
* Core of the test suite for libwapcaplet
*
* Copyright 2009 The NetSurf Browser Project
* Daniel Silverstone <dsilvers@netsurf-browser.org>
*/
 
#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 */
extern void __assert_fail(void);
void __assert_fail(void) { abort(); }
 
int
main(int argc, char **argv)
{
int number_failed = 0;
SRunner *sr;
 
UNUSED(argc);
UNUSED(argv);
sr = srunner_create(suite_create("Test suite for libwapcaplet"));
lwc_basic_suite(sr);
// lwc_memory_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;
}
/contrib/network/netsurf/libwapcaplet/test/tests.h
0,0 → 1,21
/* test/tests.h
*
* Set of test suites for libwapcaplet
*
* Copyright 2009 The NetSurf Browser Project
* Daniel Silverstone <dsilvers@netsurf-browser.org>
*/
 
#ifndef lwc_tests_h_
#define lwc_tests_h_
 
#include <signal.h>
 
#include <check.h>
 
#include "libwapcaplet/libwapcaplet.h"
 
extern void lwc_basic_suite(SRunner *);
extern void lwc_memory_suite(SRunner *);
 
#endif /* lwc_tests_h_ */