Index: uspace/lib/pcut/Makefile
===================================================================
--- uspace/lib/pcut/Makefile	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/Makefile	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,10 @@
+#
+# This file was generated by call to update-from-master.sh
+#
+
+USPACE_PREFIX = ../..
+
+include helenos.mak
+
+include $(USPACE_PREFIX)/Makefile.common
+
Index: uspace/lib/pcut/README.rst
===================================================================
--- uspace/lib/pcut/README.rst	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/README.rst	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,101 @@
+PCUT: Plain C Unit Testing mini-framework
+=========================================
+
+PCUT is a very simple framework for unit testing of C code.
+Unlike many other frameworks where you need to specify manually which
+functions belong to a particular test, PCUT provides several smart
+macros that hides this and lets you focus on the most important
+part of testing only: that is, coding the test cases.
+
+This mini-framework is definitely not complete but it offers the basic
+functionality needed for writing unit tests.
+This includes the possibility to group tests into test suites, optionally
+having set-up and tear-down functions.
+There are several assert macros for evaluating the results, their highlight
+is very detailed information about the problem.
+
+The output of the test can come in two forms: either as an XML output suited
+for later processing or in the form of Test-Anything-Protocol.
+PCUT is able to capture standard output and display it together with test
+results.
+And by running each test in a separate process, the whole framework is pretty
+safe against unexpected crashes, such as null pointer dereference.
+
+More details can be found on PCUT wiki on GitHub.
+
+					https://github.com/vhotspur/pcut/wiki
+
+
+Main goal - simple to use
+-------------------------
+
+Let's illustrate how PCUT aims to be simple when creating unit tests for
+function ``intmin`` that ought to return smaller of its two arguments.::
+
+	int intmin(int a, int b) {
+		return a > b ? b : a;
+	}
+	
+Individual test-cases for such method could cover following cases: getting
+minimal of
+
+- two same numbers
+- negative and positive number
+- two negative numbers
+- two positive numbers
+- "corner case" numbers, such as minimal and maximal represented number
+
+In PCUT, that would be translated to the following code:::
+
+	#include <pcut/test.h>
+	#include <limits.h>
+	/* Other include to have declaration of intmin */
+	
+	PCUT_INIT
+
+	PCUT_TEST_SUITE(intmin_tests);
+
+	PCUT_TEST(same_number) {
+		PCUT_ASSERT_INT_EQUALS(719, intmin(719, 719) );
+		PCUT_ASSERT_INT_EQUALS(-4589, intmin(-4589, -4589) );
+	}
+	
+	PCUT_TEST(positive_and_negative) {
+		PCUT_ASSERT_INT_EQUALS(-5, intmin(-5, 71) );
+		PCUT_ASSERT_INT_EQUALS(-17, intmin(423, -17) );
+	}
+	
+	PCUT_TEST(same_sign) {
+		PCUT_ASSERT_INT_EQUALS(22, intmin(129, 22) );
+		PCUT_ASSERT_INT_EQUALS(-37, intmin(-37, -1) );
+	}
+	
+	PCUT_TEST(corner_cases) {
+		PCUT_ASSERT_INT_EQUALS(INT_MIN, intmin(INT_MIN, -1234) );
+		PCUT_ASSERT_INT_EQUALS(9876, intmin(9876, INT_MAX) );
+	}
+
+	PCUT_MAIN()
+
+And that's all.
+You do not need to manually specify which tests to run etc., 
+everything is done magically via the ``PCUT_INIT``, ``PCUT_MAIN`` and
+``PCUT_TEST`` macros.
+All you need to do is to compile this code and link it with ``libpcut``.
+Result of the linking would be an executable that runs the tests and
+reports the results.
+
+
+Examples
+--------
+
+More examples, in the form of self-tests, are available in the ``tests/``
+subdirectory.
+
+
+Building and installing
+-----------------------
+
+On Unix systems, running ``make`` and ``make install`` shall do the job.
+
+More details can be found on https://github.com/vhotspur/pcut/wiki/Building.
Index: uspace/lib/pcut/base.mak
===================================================================
--- uspace/lib/pcut/base.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/base.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+
+PCUT_INCLUDE = include
+PCUT_CFLAGS = -Wall -Wextra -std=c99 -Werror -I$(PCUT_INCLUDE)
+
+PCUT_SOURCES = \
+	src/assert.c \
+	src/list.c \
+	src/main.c \
+	src/print.c \
+	src/report/report.c \
+	src/report/tap.c \
+	src/report/xml.c \
+	src/run.c \
+	$(PCUT_TARGET_SOURCES)
+
Index: uspace/lib/pcut/contrib/devcpp.mak
===================================================================
--- uspace/lib/pcut/contrib/devcpp.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/contrib/devcpp.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Makefile to be used by Orwell (formerly Bloodshed) Dev C++ editor
+#
+
+TEST_CFLAGS = $(CFLAGS)
+TEST_LDFLAGS = -L. -lpcut $(CFLAGS)
+EXE_EXT = exe
+TEST_BASE = tests/
+
+PCUT_LIB = pcut.lib
+
+all-after: check-build
+clean-custom: pcut-clean
Index: uspace/lib/pcut/contrib/pcut.dev
===================================================================
--- uspace/lib/pcut/contrib/pcut.dev	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/contrib/pcut.dev	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,189 @@
+[Project]
+FileName=pcut.dev
+Name=PCUT
+Type=2
+Ver=2
+ObjFiles=
+Includes=include
+Libs=
+PrivateResource=
+ResourceIncludes=
+MakeIncludes=windows.mak;contrib/devcpp.mak
+Compiler=-std=c99_@@_
+IsCpp=0
+OverrideOutputName=pcut.lib
+OverrideOutput=1
+UseCustomMakefile=0
+Folders=Sources
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=3
+CompilerSettings=0000000100000000000000000
+UnitCount=17
+
+[Unit1]
+FileName=src\assert.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=src\helper.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit3]
+FileName=src\internal.h
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit4]
+FileName=src\list.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit5]
+FileName=src\main.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit6]
+FileName=src\print.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit7]
+FileName=src\run.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit8]
+FileName=src\report\report.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit9]
+FileName=src\report\report.h
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit10]
+FileName=src\report\tap.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit11]
+FileName=src\report\xml.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit12]
+FileName=src\os\generic.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit13]
+FileName=src\os\stdc.c
+CompileCpp=0
+Folder=Sources
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit14]
+FileName=README.rst
+Folder=PCUT
+Compile=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit15]
+FileName=windows.mak
+Folder=PCUT
+Compile=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit16]
+FileName=contrib\devcpp.mak
+Folder=PCUT
+Compile=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit17]
+FileName=pcut.mak
+Folder=PCUT
+Compile=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
Index: uspace/lib/pcut/helenos.mak
===================================================================
--- uspace/lib/pcut/helenos.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/helenos.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+PCUT_TARGET_SOURCES = src/os/helenos.c
+
+-include base.mak
+
+SOURCES = $(PCUT_SOURCES)
+EXTRA_CFLAGS = -D__helenos__ -Iinclude
+LIBRARY = libpcut
Index: uspace/lib/pcut/include/pcut/impl.h
===================================================================
--- uspace/lib/pcut/include/pcut/impl.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/include/pcut/impl.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if !defined(PCUT_TEST_H_GUARD) && !defined(PCUT_INTERNAL)
+#error "You cannot include this file directly."
+#endif
+
+#ifndef PCUT_IMPL_H_GUARD
+#define PCUT_IMPL_H_GUARD
+
+#include "prevs.h"
+#include <stdlib.h>
+
+enum {
+	PCUT_KIND_SKIP,
+	PCUT_KIND_NESTED,
+	PCUT_KIND_SETUP,
+	PCUT_KIND_TEARDOWN,
+	PCUT_KIND_TESTSUITE,
+	PCUT_KIND_TEST
+};
+
+typedef struct pcut_item pcut_item_t;
+typedef void (*pcut_test_func_t)(void);
+typedef void (*pcut_setup_func_t)(void);
+
+struct pcut_item {
+	pcut_item_t *previous;
+	pcut_item_t *next;
+	int id;
+	int kind;
+	union {
+		struct {
+			const char *name;
+			pcut_setup_func_t setup;
+			pcut_setup_func_t teardown;
+		} suite;
+		struct {
+			const char *name;
+			pcut_test_func_t func;
+		} test;
+		/* setup is used for both set-up and tear-down */
+		struct {
+			pcut_setup_func_t func;
+		} setup;
+		struct {
+			pcut_item_t *last;
+		} nested;
+		struct {
+			int dummy;
+		} meta;
+	};
+};
+
+void pcut_failed_assertion(const char *message);
+void pcut_failed_assertion_fmt(const char *fmt, ...);
+int pcut_str_equals(const char *a, const char *b);
+int pcut_main(pcut_item_t *last, int argc, char *argv[]);
+
+#define PCUT_ASSERTION_FAILED(fmt, ...) \
+	pcut_failed_assertion_fmt(__FILE__ ":%d: " fmt, __LINE__, ##__VA_ARGS__)
+
+#define PCUT_JOIN_IMPL(a, b) a##b
+#define PCUT_JOIN(a, b) PCUT_JOIN_IMPL(a, b)
+
+#define PCUT_ITEM_NAME(number) \
+	PCUT_JOIN(pcut_item_, number)
+
+#define PCUT_ITEM_NAME_PREV(number) \
+	PCUT_JOIN(pcut_item_, PCUT_JOIN(PCUT_PREV_, number))
+
+#define PCUT_ADD_ITEM(number, itemkind, ...) \
+		static pcut_item_t PCUT_ITEM_NAME(number) = { \
+				.previous = &PCUT_ITEM_NAME_PREV(number), \
+				.next = NULL, \
+				.id = -1, \
+				.kind = itemkind, \
+				__VA_ARGS__ \
+		}; \
+
+#define PCUT_TEST_IMPL(testname, number) \
+		static void PCUT_JOIN(test_, testname)(void); \
+		PCUT_ADD_ITEM(number, PCUT_KIND_TEST, \
+				.test = { \
+					.name = #testname, \
+					.func = PCUT_JOIN(test_, testname) \
+				} \
+		) \
+		void PCUT_JOIN(test_, testname)(void)
+
+#define PCUT_TEST_SUITE_IMPL(suitename, number) \
+		PCUT_ADD_ITEM(number, PCUT_KIND_TESTSUITE, \
+				.suite = { \
+					.name = #suitename, \
+					.setup = NULL, \
+					.teardown = NULL \
+				} \
+		)
+
+#define PCUT_TEST_BEFORE_IMPL(number) \
+		static void PCUT_JOIN(setup_, number)(void); \
+		PCUT_ADD_ITEM(number, PCUT_KIND_SETUP, \
+				.setup.func = PCUT_JOIN(setup_, number) \
+		) \
+		void PCUT_JOIN(setup_, number)(void)
+
+#define PCUT_TEST_AFTER_IMPL(number) \
+		static void PCUT_JOIN(teardown_, number)(void); \
+		PCUT_ADD_ITEM(number, PCUT_KIND_TEARDOWN, \
+				.setup.func = PCUT_JOIN(teardown_, number) \
+		) \
+		void PCUT_JOIN(teardown_, number)(void)
+
+#define PCUT_EXPORT_IMPL(identifier, number) \
+	pcut_item_t pcut_exported_##identifier = { \
+		.previous = &PCUT_ITEM_NAME_PREV(number), \
+		.next = NULL, \
+		.kind = PCUT_KIND_SKIP \
+	}
+
+/*
+ * Trick with [] and & copied from
+ * http://bytes.com/topic/c/answers/553555-initializer-element-not-constant#post2159846
+ * because following does not work:
+ * extern int *a;
+ * int *b = a;
+ */
+#define PCUT_IMPORT_IMPL(identifier, number) \
+	extern pcut_item_t pcut_exported_##identifier; \
+	PCUT_ADD_ITEM(number, PCUT_KIND_NESTED, \
+		.nested.last = &pcut_exported_##identifier \
+	)
+
+#define PCUT_INIT_IMPL(first_number) \
+	static pcut_item_t PCUT_ITEM_NAME(__COUNTER__) = { \
+		.previous = NULL, \
+		.next = NULL, \
+		.id = -1, \
+		.kind = PCUT_KIND_SKIP \
+	}; \
+	PCUT_TEST_SUITE(Default);
+
+#define PCUT_MAIN_IMPL(last_number) \
+	static pcut_item_t pcut_item_last = { \
+		.previous = &PCUT_JOIN(pcut_item_, PCUT_JOIN(PCUT_PREV_, last_number)), \
+		.kind = PCUT_KIND_SKIP \
+	}; \
+	int main(int argc, char *argv[]) { \
+		return pcut_main(&pcut_item_last, argc, argv); \
+	}
+
+#ifdef PCUT_DEBUG_BUILD
+#define PCUT_DEBUG(msg, ...) \
+	printf("[PCUT]: Debug: " msg "\n", ##__VA_ARGS__)
+#else
+#define PCUT_DEBUG(msg, ...) (void)0
+#endif
+
+#endif
Index: uspace/lib/pcut/include/pcut/prevs.h
===================================================================
--- uspace/lib/pcut/include/pcut/prevs.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/include/pcut/prevs.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if !defined(PCUT_TEST_H_GUARD) && !defined(PCUT_INTERNAL)
+#error "You cannot include this file directly."
+#endif
+
+#ifndef PCUT_PREVS_H_GUARD
+#define PCUT_PREVS_H_GUARD
+
+#define PCUT_PREV_1 0
+#define PCUT_PREV_2 1
+#define PCUT_PREV_3 2
+#define PCUT_PREV_4 3
+#define PCUT_PREV_5 4
+#define PCUT_PREV_6 5
+#define PCUT_PREV_7 6
+#define PCUT_PREV_8 7
+#define PCUT_PREV_9 8
+#define PCUT_PREV_10 9
+#define PCUT_PREV_11 10
+#define PCUT_PREV_12 11
+#define PCUT_PREV_13 12
+#define PCUT_PREV_14 13
+#define PCUT_PREV_15 14
+#define PCUT_PREV_16 15
+#define PCUT_PREV_17 16
+#define PCUT_PREV_18 17
+#define PCUT_PREV_19 18
+#define PCUT_PREV_20 19
+#define PCUT_PREV_21 20
+#define PCUT_PREV_22 21
+#define PCUT_PREV_23 22
+#define PCUT_PREV_24 23
+#define PCUT_PREV_25 24
+#define PCUT_PREV_26 25
+#define PCUT_PREV_27 26
+#define PCUT_PREV_28 27
+#define PCUT_PREV_29 28
+#define PCUT_PREV_30 29
+#define PCUT_PREV_31 30
+#define PCUT_PREV_32 31
+#define PCUT_PREV_33 32
+#define PCUT_PREV_34 33
+#define PCUT_PREV_35 34
+#define PCUT_PREV_36 35
+#define PCUT_PREV_37 36
+#define PCUT_PREV_38 37
+#define PCUT_PREV_39 38
+#define PCUT_PREV_40 39
+#define PCUT_PREV_41 40
+#define PCUT_PREV_42 41
+#define PCUT_PREV_43 42
+#define PCUT_PREV_44 43
+#define PCUT_PREV_45 44
+#define PCUT_PREV_46 45
+#define PCUT_PREV_47 46
+#define PCUT_PREV_48 47
+#define PCUT_PREV_49 48
+#define PCUT_PREV_50 49
+#define PCUT_PREV_51 50
+#define PCUT_PREV_52 51
+#define PCUT_PREV_53 52
+#define PCUT_PREV_54 53
+#define PCUT_PREV_55 54
+#define PCUT_PREV_56 55
+#define PCUT_PREV_57 56
+#define PCUT_PREV_58 57
+#define PCUT_PREV_59 58
+#define PCUT_PREV_60 59
+#define PCUT_PREV_61 60
+#define PCUT_PREV_62 61
+#define PCUT_PREV_63 62
+#define PCUT_PREV_64 63
+#define PCUT_PREV_65 64
+#define PCUT_PREV_66 65
+#define PCUT_PREV_67 66
+#define PCUT_PREV_68 67
+#define PCUT_PREV_69 68
+#define PCUT_PREV_70 69
+#define PCUT_PREV_71 70
+#define PCUT_PREV_72 71
+#define PCUT_PREV_73 72
+#define PCUT_PREV_74 73
+#define PCUT_PREV_75 74
+#define PCUT_PREV_76 75
+#define PCUT_PREV_77 76
+#define PCUT_PREV_78 77
+#define PCUT_PREV_79 78
+#define PCUT_PREV_80 79
+#define PCUT_PREV_81 80
+#define PCUT_PREV_82 81
+#define PCUT_PREV_83 82
+#define PCUT_PREV_84 83
+#define PCUT_PREV_85 84
+#define PCUT_PREV_86 85
+#define PCUT_PREV_87 86
+#define PCUT_PREV_88 87
+#define PCUT_PREV_89 88
+#define PCUT_PREV_90 89
+#define PCUT_PREV_91 90
+#define PCUT_PREV_92 91
+#define PCUT_PREV_93 92
+#define PCUT_PREV_94 93
+#define PCUT_PREV_95 94
+#define PCUT_PREV_96 95
+#define PCUT_PREV_97 96
+#define PCUT_PREV_98 97
+#define PCUT_PREV_99 98
+#define PCUT_PREV_100 99
+#define PCUT_PREV_101 100
+#define PCUT_PREV_102 101
+#define PCUT_PREV_103 102
+#define PCUT_PREV_104 103
+#define PCUT_PREV_105 104
+#define PCUT_PREV_106 105
+#define PCUT_PREV_107 106
+#define PCUT_PREV_108 107
+#define PCUT_PREV_109 108
+#define PCUT_PREV_110 109
+#define PCUT_PREV_111 110
+#define PCUT_PREV_112 111
+#define PCUT_PREV_113 112
+#define PCUT_PREV_114 113
+#define PCUT_PREV_115 114
+#define PCUT_PREV_116 115
+#define PCUT_PREV_117 116
+#define PCUT_PREV_118 117
+#define PCUT_PREV_119 118
+#define PCUT_PREV_120 119
+#define PCUT_PREV_121 120
+#define PCUT_PREV_122 121
+#define PCUT_PREV_123 122
+#define PCUT_PREV_124 123
+#define PCUT_PREV_125 124
+#define PCUT_PREV_126 125
+#define PCUT_PREV_127 126
+#define PCUT_PREV_128 127
+#define PCUT_PREV_129 128
+#define PCUT_PREV_130 129
+#define PCUT_PREV_131 130
+#define PCUT_PREV_132 131
+#define PCUT_PREV_133 132
+#define PCUT_PREV_134 133
+#define PCUT_PREV_135 134
+#define PCUT_PREV_136 135
+#define PCUT_PREV_137 136
+#define PCUT_PREV_138 137
+#define PCUT_PREV_139 138
+#define PCUT_PREV_140 139
+#define PCUT_PREV_141 140
+#define PCUT_PREV_142 141
+#define PCUT_PREV_143 142
+#define PCUT_PREV_144 143
+#define PCUT_PREV_145 144
+#define PCUT_PREV_146 145
+#define PCUT_PREV_147 146
+#define PCUT_PREV_148 147
+#define PCUT_PREV_149 148
+#define PCUT_PREV_150 149
+#define PCUT_PREV_151 150
+#define PCUT_PREV_152 151
+#define PCUT_PREV_153 152
+#define PCUT_PREV_154 153
+#define PCUT_PREV_155 154
+#define PCUT_PREV_156 155
+#define PCUT_PREV_157 156
+#define PCUT_PREV_158 157
+#define PCUT_PREV_159 158
+#define PCUT_PREV_160 159
+#define PCUT_PREV_161 160
+#define PCUT_PREV_162 161
+#define PCUT_PREV_163 162
+#define PCUT_PREV_164 163
+#define PCUT_PREV_165 164
+#define PCUT_PREV_166 165
+#define PCUT_PREV_167 166
+#define PCUT_PREV_168 167
+#define PCUT_PREV_169 168
+#define PCUT_PREV_170 169
+#define PCUT_PREV_171 170
+#define PCUT_PREV_172 171
+#define PCUT_PREV_173 172
+#define PCUT_PREV_174 173
+#define PCUT_PREV_175 174
+#define PCUT_PREV_176 175
+#define PCUT_PREV_177 176
+#define PCUT_PREV_178 177
+#define PCUT_PREV_179 178
+#define PCUT_PREV_180 179
+#define PCUT_PREV_181 180
+#define PCUT_PREV_182 181
+#define PCUT_PREV_183 182
+#define PCUT_PREV_184 183
+#define PCUT_PREV_185 184
+#define PCUT_PREV_186 185
+#define PCUT_PREV_187 186
+#define PCUT_PREV_188 187
+#define PCUT_PREV_189 188
+#define PCUT_PREV_190 189
+#define PCUT_PREV_191 190
+#define PCUT_PREV_192 191
+#define PCUT_PREV_193 192
+#define PCUT_PREV_194 193
+#define PCUT_PREV_195 194
+#define PCUT_PREV_196 195
+#define PCUT_PREV_197 196
+#define PCUT_PREV_198 197
+#define PCUT_PREV_199 198
+#define PCUT_PREV_200 199
+#define PCUT_PREV_201 200
+#define PCUT_PREV_202 201
+#define PCUT_PREV_203 202
+#define PCUT_PREV_204 203
+#define PCUT_PREV_205 204
+#define PCUT_PREV_206 205
+#define PCUT_PREV_207 206
+#define PCUT_PREV_208 207
+#define PCUT_PREV_209 208
+#define PCUT_PREV_210 209
+#define PCUT_PREV_211 210
+#define PCUT_PREV_212 211
+#define PCUT_PREV_213 212
+#define PCUT_PREV_214 213
+#define PCUT_PREV_215 214
+#define PCUT_PREV_216 215
+#define PCUT_PREV_217 216
+#define PCUT_PREV_218 217
+#define PCUT_PREV_219 218
+#define PCUT_PREV_220 219
+#define PCUT_PREV_221 220
+#define PCUT_PREV_222 221
+#define PCUT_PREV_223 222
+#define PCUT_PREV_224 223
+#define PCUT_PREV_225 224
+#define PCUT_PREV_226 225
+#define PCUT_PREV_227 226
+#define PCUT_PREV_228 227
+#define PCUT_PREV_229 228
+#define PCUT_PREV_230 229
+#define PCUT_PREV_231 230
+#define PCUT_PREV_232 231
+#define PCUT_PREV_233 232
+#define PCUT_PREV_234 233
+#define PCUT_PREV_235 234
+#define PCUT_PREV_236 235
+#define PCUT_PREV_237 236
+#define PCUT_PREV_238 237
+#define PCUT_PREV_239 238
+#define PCUT_PREV_240 239
+#define PCUT_PREV_241 240
+#define PCUT_PREV_242 241
+#define PCUT_PREV_243 242
+#define PCUT_PREV_244 243
+#define PCUT_PREV_245 244
+#define PCUT_PREV_246 245
+#define PCUT_PREV_247 246
+#define PCUT_PREV_248 247
+#define PCUT_PREV_249 248
+#define PCUT_PREV_250 249
+#define PCUT_PREV_251 250
+#define PCUT_PREV_252 251
+#define PCUT_PREV_253 252
+#define PCUT_PREV_254 253
+#define PCUT_PREV_255 254
+#define PCUT_PREV_256 255
+#define PCUT_PREV_257 256
+#define PCUT_PREV_258 257
+#define PCUT_PREV_259 258
+#define PCUT_PREV_260 259
+#define PCUT_PREV_261 260
+#define PCUT_PREV_262 261
+#define PCUT_PREV_263 262
+#define PCUT_PREV_264 263
+#define PCUT_PREV_265 264
+#define PCUT_PREV_266 265
+#define PCUT_PREV_267 266
+#define PCUT_PREV_268 267
+#define PCUT_PREV_269 268
+#define PCUT_PREV_270 269
+#define PCUT_PREV_271 270
+#define PCUT_PREV_272 271
+#define PCUT_PREV_273 272
+#define PCUT_PREV_274 273
+#define PCUT_PREV_275 274
+#define PCUT_PREV_276 275
+#define PCUT_PREV_277 276
+#define PCUT_PREV_278 277
+#define PCUT_PREV_279 278
+#define PCUT_PREV_280 279
+#define PCUT_PREV_281 280
+#define PCUT_PREV_282 281
+#define PCUT_PREV_283 282
+#define PCUT_PREV_284 283
+#define PCUT_PREV_285 284
+#define PCUT_PREV_286 285
+#define PCUT_PREV_287 286
+#define PCUT_PREV_288 287
+#define PCUT_PREV_289 288
+#define PCUT_PREV_290 289
+#define PCUT_PREV_291 290
+#define PCUT_PREV_292 291
+#define PCUT_PREV_293 292
+#define PCUT_PREV_294 293
+#define PCUT_PREV_295 294
+#define PCUT_PREV_296 295
+#define PCUT_PREV_297 296
+#define PCUT_PREV_298 297
+#define PCUT_PREV_299 298
+#define PCUT_PREV_300 299
+
+#endif
+
Index: uspace/lib/pcut/include/pcut/test.h
===================================================================
--- uspace/lib/pcut/include/pcut/test.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/include/pcut/test.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * PCUT: Plain-C unit-testing mini-framework.
+ */
+#ifndef PCUT_TEST_H_GUARD
+#define PCUT_TEST_H_GUARD
+
+#include "impl.h"
+
+/** Generic assertion for types where == is defined.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_EQUALS(expected, actual) \
+		do {\
+			if (!((expected) == (actual))) { \
+				PCUT_ASSERTION_FAILED("Expected <"#expected "> but got <" #actual ">"); \
+			} \
+		} while (0)
+
+/** Asserts that given pointer is NULL.
+ *
+ * @param pointer The pointer to be tested.
+ */
+#define PCUT_ASSERT_NULL(pointer) \
+	do { \
+		void *pcut_ptr_eval = (pointer); \
+		if (pcut_ptr_eval != (NULL)) { \
+			PCUT_ASSERTION_FAILED("Expected <" #pointer "> to be NULL, " \
+				"instead it points to %p", pcut_ptr_eval); \
+		} \
+	} while (0)
+
+/** Asserts that given pointer is not NULL.
+ *
+ * @param pointer The pointer to be tested.
+ */
+#define PCUT_ASSERT_NOT_NULL(pointer) \
+	do { \
+		void *pcut_ptr_eval = (pointer); \
+		if (pcut_ptr_eval == (NULL)) { \
+			PCUT_ASSERTION_FAILED("Pointer <" #pointer "> ought not to be NULL"); \
+		} \
+	} while (0)
+
+
+/** Assertion for checking that two integers are equal.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_INT_EQUALS(expected, actual) \
+	do {\
+		long pcut_expected_eval = (expected); \
+		long pcut_actual_eval = (actual); \
+		if (pcut_expected_eval != pcut_actual_eval) { \
+			PCUT_ASSERTION_FAILED("Expected <%ld> but got <%ld> (%s != %s)", \
+				pcut_expected_eval, pcut_actual_eval, \
+				#expected, #actual); \
+		} \
+	} while (0)
+
+/** Assertion for checking that two doubles are close enough.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ * @param epsilon How much the actual value can differ from the expected one.
+ */
+#define PCUT_ASSERT_DOUBLE_EQUALS(expected, actual, epsilon) \
+	do {\
+		double pcut_expected_eval = (expected); \
+		double pcut_actual_eval = (actual); \
+		double pcut_epsilon_eval = (epsilon); \
+		double pcut_double_diff = pcut_expected_eval - pcut_actual_eval; \
+		if ((pcut_double_diff < -pcut_epsilon_eval) | (pcut_double_diff > pcut_epsilon_eval)) { \
+			PCUT_ASSERTION_FAILED("Expected <%lf+-%lf> but got <%lf> (%s != %s)", \
+				pcut_expected_eval, pcut_epsilon_eval, pcut_actual_eval, \
+				#expected, #actual); \
+		} \
+	} while (0)
+
+/** Assertion for checking that two strings (`const char *`) are equal.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_STR_EQUALS(expected, actual) \
+	do {\
+		const char *pcut_expected_eval = (expected); \
+		const char *pcut_actual_eval = (actual); \
+		if (!pcut_str_equals(pcut_expected_eval, pcut_actual_eval)) { \
+			PCUT_ASSERTION_FAILED("Expected <%s> but got <%s> (%s != %s)", \
+				pcut_expected_eval, pcut_actual_eval, \
+				#expected, #actual); \
+		} \
+	} while (0)
+
+
+/** Define a new test with given name.
+ *
+ * @param name A valid C identifier name (not quoted).
+ */
+#define PCUT_TEST(name) PCUT_TEST_IMPL(name, __COUNTER__)
+
+/** Define a new test suite with given name.
+ *
+ * All tests following this macro belong to the new suite
+ * (up to next occurence of PCUT_TEST_SUITE).
+ *
+ */
+#define PCUT_TEST_SUITE(name) PCUT_TEST_SUITE_IMPL(name, __COUNTER__)
+
+/** Define a set-up function for a test suite.
+ *
+ * There could be only a single set-up function for each suite.
+ */
+#define PCUT_TEST_BEFORE \
+	PCUT_TEST_BEFORE_IMPL(__COUNTER__)
+
+/** Define a tear-down function for a test suite.
+ *
+ * There could be only a single tear-down function for each suite.
+ */
+#define PCUT_TEST_AFTER \
+	PCUT_TEST_AFTER_IMPL(__COUNTER__)
+
+/** Export test cases from current file. */
+#define PCUT_EXPORT(identifier) \
+	PCUT_EXPORT_IMPL(identifier, __COUNTER__)
+
+/** Import test cases from a different file. */
+#define PCUT_IMPORT(identifier) \
+	PCUT_IMPORT_IMPL(identifier, __COUNTER__)
+
+/** Initialize the PCUT testing framework. */
+#define PCUT_INIT \
+	PCUT_INIT_IMPL(__COUNTER__)
+
+/** Insert code to run all the tests. */
+#define PCUT_MAIN() \
+	PCUT_MAIN_IMPL(__COUNTER__)
+
+#endif
Index: uspace/lib/pcut/pcut.mak
===================================================================
--- uspace/lib/pcut/pcut.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/pcut.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+-include base.mak
+
+all: $(PCUT_LIB)
+
+pcut-clean: check-clean platform-clean
+	$(RM) *.$(OBJ_EXT) src/*.$(OBJ_EXT) src/*/*.$(OBJ_EXT)
+
+%.o: %.c
+	$(CC) -c -o $@ $(PCUT_CFLAGS) $<
Index: uspace/lib/pcut/src/assert.c
===================================================================
--- uspace/lib/pcut/src/assert.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/assert.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file
+ * Formatting and processing of failed assertion messages.
+ *
+ * We are using static buffers to prevent any calls to malloc()/free()
+ * by the testing framework.
+ */
+
+#include "internal.h"
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+/** Maximum length of failed-assert message. */
+#define MAX_MESSAGE_LENGTH 256
+
+/** How many assertion messages we need to keep in memory at once. */
+#define MESSAGE_BUFFER_COUNT 2
+
+/** Assertion message buffers. */
+static char message_buffer[MESSAGE_BUFFER_COUNT][MAX_MESSAGE_LENGTH + 1];
+
+/** Currently active assertion buffer. */
+static int message_buffer_index = 0;
+
+/** Announce that assertion failed.
+ *
+ * @warning This function may not return.
+ *
+ * @param fmt printf-style formatting string.
+ *
+ */
+void pcut_failed_assertion_fmt(const char *fmt, ...) {
+	char *current_buffer = message_buffer[message_buffer_index];
+	message_buffer_index = (message_buffer_index + 1) % MESSAGE_BUFFER_COUNT;
+
+	va_list args;
+	va_start(args, fmt);
+	vsnprintf(current_buffer, MAX_MESSAGE_LENGTH, fmt, args);
+	va_end(args);
+
+	pcut_failed_assertion(current_buffer);
+}
Index: uspace/lib/pcut/src/internal.h
===================================================================
--- uspace/lib/pcut/src/internal.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/internal.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PCUT_INTERNAL_H_GUARD
+#define PCUT_INTERNAL_H_GUARD
+
+#include <pcut/test.h>
+#include <stdlib.h>
+
+/** Mark a variable as unused. */
+#define PCUT_UNUSED(x) ((void)x)
+
+/** Forking mode for test execution.
+ *
+ * In this mode, each test is run in a separate process.
+ * This ensures that even SIGSEGV does not stop the framework itself.
+ */
+#define PCUT_RUN_MODE_FORKING 1
+
+/** Single-process mode for test execution.
+ *
+ * This mode is used when new process is launched when in forking-mode or
+ * this mode can be used if we are sure that no test would fail
+ * fatally (that is causing an unexpected program exit).
+ */
+#define PCUT_RUN_MODE_SINGLE 2
+
+/** Test outcome: test passed. */
+#define TEST_OUTCOME_PASS 1
+
+/** Test outcome: test failed. */
+#define TEST_OUTCOME_FAIL 2
+
+/** Test outcome: test failed unexpectedly. */
+#define TEST_OUTCOME_ERROR 3
+
+extern int pcut_run_mode;
+
+
+pcut_item_t *pcut_fix_list_get_real_head(pcut_item_t *last);
+int pcut_count_tests(pcut_item_t *it);
+void pcut_print_items(pcut_item_t *first);
+
+pcut_item_t *pcut_get_real_next(pcut_item_t *item);
+pcut_item_t *pcut_get_real(pcut_item_t *item);
+const char* pcut_run_test(pcut_test_func_t function);
+const char* pcut_run_setup_teardown(pcut_setup_func_t function);
+void pcut_print_tests(pcut_item_t *first);
+int pcut_is_arg_with_number(const char *arg, const char *opt, int *value);
+
+void pcut_run_test_forking(const char *self_path, pcut_item_t *test);
+int pcut_run_test_forked(pcut_item_t *test);
+int pcut_run_test_single(pcut_item_t *test);
+
+extern pcut_item_t *pcut_current_test;
+extern pcut_item_t *pcut_current_suite;
+extern int pcut_running_test_now;
+extern int pcut_running_setup_now;
+
+void pcut_print_fail_message(const char *msg);
+
+typedef struct pcut_report_ops pcut_report_ops_t;
+/** Reporting callbacks structure. */
+struct pcut_report_ops {
+	/** Initialize the reporting, given all tests. */
+	void (*init)(pcut_item_t *);
+	/** Test suite just started. */
+	void (*suite_start)(pcut_item_t *);
+	/** Test suite completed. */
+	void (*suite_done)(pcut_item_t *);
+	/** Test is about to start. */
+	void (*test_start)(pcut_item_t *);
+	/** Test completed. */
+	void (*test_done)(pcut_item_t *, int, const char *, const char *,
+		const char *);
+	/** Finalize the reporting. */
+	void (*done)(void);
+};
+
+void pcut_report_register_handler(pcut_report_ops_t *ops);
+
+void pcut_report_init(pcut_item_t *all_items);
+void pcut_report_suite_start(pcut_item_t *suite);
+void pcut_report_suite_done(pcut_item_t *suite);
+void pcut_report_test_start(pcut_item_t *test);
+void pcut_report_test_done(pcut_item_t *test, int outcome,
+		const char *error_message, const char *teardown_error_message,
+		const char *extra_output);
+void pcut_report_test_done_unparsed(pcut_item_t *test, int outcome,
+		const char *unparsed_output, size_t unparsed_output_size);
+void pcut_report_done(void);
+
+
+int pcut_str_start_equals(const char *a, const char *b, int len);
+int pcut_str_size(const char *s);
+int pcut_str_to_int(const char *s);
+char *pcut_str_find_char(const char *haystack, const char needle);
+
+
+#endif
Index: uspace/lib/pcut/src/list.c
===================================================================
--- uspace/lib/pcut/src/list.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/list.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Helper functions for working with list of items.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include "internal.h"
+#include <pcut/test.h>
+
+
+/** Find next item with actual content.
+ *
+ * @param item Head of the list.
+ * @return First item with actual content or NULL on end of list.
+ */
+pcut_item_t *pcut_get_real_next(pcut_item_t *item) {
+	if (item == NULL) {
+		return NULL;
+	}
+
+	do {
+		item = item->next;
+	} while ((item != NULL) && (item->kind == PCUT_KIND_SKIP));
+
+
+	return item;
+}
+
+/** Retrieve the first item with actual content.
+ *
+ * Unlike pcut_get_real_next(), where we always advance after the
+ * first item, here the @p item itself could be returned.
+ *
+ * @param item Head of the list.
+ * @return First item with actual content or NULL on end of list.
+ */
+pcut_item_t *pcut_get_real(pcut_item_t *item) {
+	if (item == NULL) {
+		return NULL;
+	}
+
+	if (item->kind == PCUT_KIND_SKIP) {
+		return pcut_get_real_next(item);
+	} else {
+		return item;
+	}
+}
+
+
+/** In-line nested lists into the parent.
+ *
+ * @param nested Head of the nested list.
+ */
+static void inline_nested_lists(pcut_item_t *nested) {
+	if (nested->kind != PCUT_KIND_NESTED) {
+		return;
+	}
+
+	if (nested->nested.last == NULL) {
+		nested->kind = PCUT_KIND_SKIP;
+		return;
+	}
+
+	pcut_item_t *first = pcut_fix_list_get_real_head(nested->nested.last);
+	nested->nested.last->next = nested->next;
+	if (nested->next != NULL) {
+		nested->next->previous = nested->nested.last;
+	}
+	nested->next = first;
+	first->previous = nested;
+
+	nested->kind = PCUT_KIND_SKIP;
+}
+
+/** Assing unique ids to each item in the list.
+ *
+ * @param first List head.
+ */
+static void set_ids(pcut_item_t *first) {
+	assert(first != NULL);
+	int id = 1;
+	if (first->kind == PCUT_KIND_SKIP) {
+		first = pcut_get_real_next(first);
+	}
+	for (pcut_item_t *it = first; it != NULL; it = pcut_get_real_next(it)) {
+		it->id = id;
+		id++;
+	}
+}
+
+/** Convert the static single-linked list into a flat double-linked list.
+ *
+ * The conversion includes
+ * * adding forward links
+ * * flattening of any nested lists
+ * * assigning of unique ids
+ *
+ * @param last Tail of the list.
+ * @return Head of the fixed list.
+ */
+pcut_item_t *pcut_fix_list_get_real_head(pcut_item_t *last) {
+	last->next = NULL;
+
+	inline_nested_lists(last);
+
+	pcut_item_t *next = last;
+
+	pcut_item_t *it = last->previous;
+	while (it != NULL) {
+		it->next = next;
+		inline_nested_lists(it);
+		next = it;
+		it = it->previous;
+	}
+
+	set_ids(next);
+
+	return next;
+}
+
+/** Compute the number of all tests in a list.
+ *
+ * @param it Head of the list.
+ * @return Number of tests.
+ */
+int pcut_count_tests(pcut_item_t *it) {
+	int count = 0;
+	while (it != NULL) {
+		if (it->kind == PCUT_KIND_TEST) {
+			count++;
+		}
+		it = pcut_get_real_next(it);
+	}
+	return count;
+}
Index: uspace/lib/pcut/src/main.c
===================================================================
--- uspace/lib/pcut/src/main.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/main.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * The main control loop of the whole library.
+ */
+
+#include "internal.h"
+#include "report/report.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/** Current running mode. */
+int pcut_run_mode = PCUT_RUN_MODE_FORKING;
+
+
+/** Checks whether the argument is an option followed by a number.
+ *
+ * @param arg Argument from the user.
+ * @param opt Option, including the leading dashes.
+ * @param value Where to store the integer value.
+ * @return Whether @p arg is @p opt followed by a number.
+ */
+int pcut_is_arg_with_number(const char *arg, const char *opt, int *value) {
+	int opt_len = pcut_str_size(opt);
+	if (! pcut_str_start_equals(arg, opt, opt_len)) {
+		return 0;
+	}
+	int val = pcut_str_to_int(arg + opt_len);
+	*value = val;
+	return 1;
+}
+
+
+/** Find item by its id.
+ *
+ * @param first List to search.
+ * @param id Id to find.
+ * @return The item with given id.
+ * @retval NULL No item with such id exists in the list.
+ */
+static pcut_item_t *pcut_find_by_id(pcut_item_t *first, int id) {
+	pcut_item_t *it = pcut_get_real(first);
+	while (it != NULL) {
+		if (it->id == id) {
+			return it;
+		}
+		it = pcut_get_real_next(it);
+	}
+	return NULL;
+}
+
+/** Run the whole test suite.
+ *
+ * @param suite Suite to run.
+ * @param last Pointer to first item after this suite is stored here.
+ * @param prog_path Path to the current binary (used in forked mode).
+ */
+static void run_suite(pcut_item_t *suite, pcut_item_t **last, const char *prog_path) {
+	pcut_item_t *it = pcut_get_real_next(suite);
+	if ((it == NULL) || (it->kind == PCUT_KIND_TESTSUITE)) {
+		goto leave_no_print;
+	}
+
+	int is_first_test = 1;
+	int total_count = 0;
+
+	for (; it != NULL; it = pcut_get_real_next(it)) {
+		if (it->kind == PCUT_KIND_TESTSUITE) {
+			goto leave_ok;
+		}
+		if (it->kind != PCUT_KIND_TEST) {
+			continue;
+		}
+
+		if (is_first_test) {
+			pcut_report_suite_start(suite);
+			is_first_test = 0;
+		}
+
+		if (pcut_run_mode == PCUT_RUN_MODE_FORKING) {
+			pcut_run_test_forking(prog_path, it);
+		} else {
+			pcut_run_test_single(it);
+		}
+		total_count++;
+	}
+
+leave_ok:
+	if (total_count > 0) {
+		pcut_report_suite_done(suite);
+	}
+
+leave_no_print:
+	if (last != NULL) {
+		*last = it;
+	}
+}
+
+/** Add direct pointers to set-up/tear-down functions to a suites.
+ *
+ * At start-up, set-up and tear-down functions are scattered in the
+ * list as siblings of suites and tests.
+ * This puts them into the structure describing the suite itself.
+ *
+ * @param first First item of the list.
+ */
+static void set_setup_teardown_callbacks(pcut_item_t *first) {
+	pcut_item_t *active_suite = NULL;
+	for (pcut_item_t *it = first; it != NULL; it = pcut_get_real_next(it)) {
+		if (it->kind == PCUT_KIND_TESTSUITE) {
+			active_suite = it;
+		} else if (it->kind == PCUT_KIND_SETUP) {
+			if (active_suite != NULL) {
+				active_suite->suite.setup = it->setup.func;
+			}
+			it->kind = PCUT_KIND_SKIP;
+		} else if (it->kind == PCUT_KIND_TEARDOWN) {
+			if (active_suite != NULL) {
+				active_suite->suite.teardown = it->setup.func;
+			}
+			it->kind = PCUT_KIND_SKIP;
+		} else {
+			/* Not interesting right now. */
+		}
+	}
+}
+
+/** The main function of PCUT.
+ *
+ * This function is expected to be called as the only function in
+ * normal main().
+ *
+ * @param last Pointer to the last item defined by PCUT_TEST macros.
+ * @param argc Original argc of the program.
+ * @param argv Original argv of the program.
+ * @return Program exit code.
+ */
+int pcut_main(pcut_item_t *last, int argc, char *argv[]) {
+	pcut_item_t *items = pcut_fix_list_get_real_head(last);
+
+	int run_only_suite = -1;
+	int run_only_test = -1;
+
+	pcut_report_register_handler(&pcut_report_tap);
+
+	if (argc > 1) {
+		int i;
+		for (i = 1; i < argc; i++) {
+			pcut_is_arg_with_number(argv[i], "-s", &run_only_suite);
+			pcut_is_arg_with_number(argv[i], "-t", &run_only_test);
+			if (pcut_str_equals(argv[i], "-l")) {
+				pcut_print_tests(items);
+				return 0;
+			}
+			if (pcut_str_equals(argv[i], "-x")) {
+				pcut_report_register_handler(&pcut_report_xml);
+			}
+#ifndef PCUT_NO_LONG_JUMP
+			if (pcut_str_equals(argv[i], "-u")) {
+				pcut_run_mode = PCUT_RUN_MODE_SINGLE;
+			}
+#endif
+		}
+	}
+
+	setvbuf(stdout, NULL, _IONBF, 0);
+	set_setup_teardown_callbacks(items);
+
+	PCUT_DEBUG("run_only_suite = %d   run_only_test = %d", run_only_suite, run_only_test);
+
+	if ((run_only_suite >= 0) && (run_only_test >= 0)) {
+		printf("Specify either -s or -t!\n");
+		return 1;
+	}
+
+	if (run_only_suite > 0) {
+		pcut_item_t *suite = pcut_find_by_id(items, run_only_suite);
+		if (suite == NULL) {
+			printf("Suite not found, aborting!\n");
+			return 2;
+		}
+		if (suite->kind != PCUT_KIND_TESTSUITE) {
+			printf("Invalid suite id!\n");
+			return 3;
+		}
+
+		run_suite(suite, NULL, argv[0]);
+		return 0;
+	}
+
+	if (run_only_test > 0) {
+		pcut_item_t *test = pcut_find_by_id(items, run_only_test);
+		if (test == NULL) {
+			printf("Test not found, aborting!\n");
+			return 2;
+		}
+		if (test->kind != PCUT_KIND_TEST) {
+			printf("Invalid test id!\n");
+			return 3;
+		}
+
+		int rc;
+		if (pcut_run_mode == PCUT_RUN_MODE_SINGLE) {
+			rc = pcut_run_test_single(test);
+		} else {
+			rc = pcut_run_test_forked(test);
+		}
+
+		return rc;
+	}
+
+	/* Otherwise, run the whole thing. */
+	pcut_report_init(items);
+
+	pcut_item_t *it = items;
+	while (it != NULL) {
+		if (it->kind == PCUT_KIND_TESTSUITE) {
+			pcut_item_t *tmp;
+			run_suite(it, &tmp, argv[0]);
+			it = tmp;
+		} else {
+			it = pcut_get_real_next(it);
+		}
+	}
+
+	pcut_report_done();
+
+	return 0;
+}
Index: uspace/lib/pcut/src/os/generic.c
===================================================================
--- uspace/lib/pcut/src/os/generic.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/os/generic.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Platform-dependent test execution function when system() is available.
+ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include "../internal.h"
+
+/** Maximum command-line length. */
+#define PCUT_COMMAND_LINE_BUFFER_SIZE 256
+
+/** Maximum length of a temporary file name. */
+#define PCUT_TEMP_FILENAME_BUFFER_SIZE 128
+
+/** Maximum size of stdout we are able to capture. */
+#define OUTPUT_BUFFER_SIZE 8192
+
+/* Format the command to launch a test according to OS we are running on. */
+
+#if defined(__WIN64) || defined(__WIN32)
+#include <process.h>
+
+#define FORMAT_COMMAND(buffer, buffer_size, self_path, test_id, temp_file) \
+	snprintf(buffer, buffer_size, "\"\"%s\" -t%d >%s\"", self_path, test_id, temp_file)
+#define FORMAT_TEMP_FILENAME(buffer, buffer_size) \
+	snprintf(buffer, buffer_size, "pcut_%d.tmp", _getpid())
+
+#elif defined(__unix)
+#include <unistd.h>
+
+#define FORMAT_COMMAND(buffer, buffer_size, self_path, test_id, temp_file) \
+	snprintf(buffer, buffer_size, "%s -t%d &>%s", self_path, test_id, temp_file)
+#define FORMAT_TEMP_FILENAME(buffer, buffer_size) \
+	snprintf(buffer, buffer_size, "pcut_%d.tmp", getpid())
+
+#else
+#error "Unknown operating system."
+#endif
+
+/** Buffer for assertion and other error messages. */
+static char error_message_buffer[OUTPUT_BUFFER_SIZE];
+
+/** Buffer for stdout from the test. */
+static char extra_output_buffer[OUTPUT_BUFFER_SIZE];
+
+/** Prepare for a new test. */
+static void before_test_start(pcut_item_t *test) {
+	pcut_report_test_start(test);
+
+	memset(error_message_buffer, 0, OUTPUT_BUFFER_SIZE);
+	memset(extra_output_buffer, 0, OUTPUT_BUFFER_SIZE);
+}
+
+/** Convert program exit code to test outcome.
+ *
+ * @param status Return value from the system() function.
+ * @return Test outcome code.
+ */
+static int convert_wait_status_to_outcome(int status) {
+	if (status < 0) {
+		return TEST_OUTCOME_ERROR;
+	} else if (status == 0) {
+		return TEST_OUTCOME_PASS;
+	} else {
+		return TEST_OUTCOME_FAIL;
+	}
+}
+
+/** Run the test as a new process and report the result.
+ *
+ * @param self_path Path to itself, that is to current binary.
+ * @param test Test to be run.
+ */
+void pcut_run_test_forking(const char *self_path, pcut_item_t *test) {
+	before_test_start(test);
+
+	char tempfile_name[PCUT_TEMP_FILENAME_BUFFER_SIZE];
+	FORMAT_TEMP_FILENAME(tempfile_name, PCUT_TEMP_FILENAME_BUFFER_SIZE - 1);
+
+	char command[PCUT_COMMAND_LINE_BUFFER_SIZE];
+	FORMAT_COMMAND(command, PCUT_COMMAND_LINE_BUFFER_SIZE - 1,
+		self_path, (test)->id, tempfile_name);
+
+	int rc = system(command);
+	rc = convert_wait_status_to_outcome(rc);
+
+	FILE *tempfile = fopen(tempfile_name, "rb");
+	if (tempfile == NULL) {
+		pcut_report_test_done(test, TEST_OUTCOME_ERROR, "Failed to open temporary file.", NULL, NULL);
+		return;
+	}
+
+	fread(extra_output_buffer, 1, OUTPUT_BUFFER_SIZE, tempfile);
+	fclose(tempfile);
+	remove(tempfile_name);
+
+	pcut_report_test_done_unparsed(test, rc, extra_output_buffer, OUTPUT_BUFFER_SIZE);
+}
+
Index: uspace/lib/pcut/src/os/helenos.c
===================================================================
--- uspace/lib/pcut/src/os/helenos.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/os/helenos.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Implementation of platform-dependent functions for HelenOS.
+ */
+
+#include <stdlib.h>
+#include <str.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdio.h>
+#include <task.h>
+#include <fcntl.h>
+#include "../internal.h"
+
+
+/* String functions. */
+
+int pcut_str_equals(const char *a, const char *b) {
+	return str_cmp(a, b) == 0;
+}
+
+
+int pcut_str_start_equals(const char *a, const char *b, int len) {
+	return str_lcmp(a, b, len) == 0;
+}
+
+int pcut_str_size(const char *s) {
+	return str_size(s);
+}
+
+int pcut_str_to_int(const char *s) {
+	int result = strtol(s, NULL, 10);
+	return result;
+}
+
+char *pcut_str_find_char(const char *haystack, const char needle) {
+	return str_chr(haystack, needle);
+}
+
+
+/* Forking-mode related functions. */
+
+/** Maximum width of a test number. */
+#define MAX_TEST_NUMBER_WIDTH 24
+
+/** Maximum length of a temporary file name. */
+#define PCUT_TEMP_FILENAME_BUFFER_SIZE 128
+
+/** Maximum command-line length. */
+#define MAX_COMMAND_LINE_LENGTH 1024
+
+/** Maximum size of stdout we are able to capture. */
+#define OUTPUT_BUFFER_SIZE 8192
+
+/** Buffer for assertion and other error messages. */
+static char error_message_buffer[OUTPUT_BUFFER_SIZE];
+
+/** Buffer for stdout from the test. */
+static char extra_output_buffer[OUTPUT_BUFFER_SIZE];
+
+/** Prepare for a new test. */
+static void before_test_start(pcut_item_t *test) {
+	pcut_report_test_start(test);
+
+	memset(error_message_buffer, 0, OUTPUT_BUFFER_SIZE);
+	memset(extra_output_buffer, 0, OUTPUT_BUFFER_SIZE);
+}
+
+/** Run the test as a new task and report the result.
+ *
+ * @param self_path Path to itself, that is to current binary.
+ * @param test Test to be run.
+ */
+void pcut_run_test_forking(const char *self_path, pcut_item_t *test) {
+	before_test_start(test);
+
+	char tempfile_name[PCUT_TEMP_FILENAME_BUFFER_SIZE];
+	snprintf(tempfile_name, PCUT_TEMP_FILENAME_BUFFER_SIZE - 1, "pcut_%lld.tmp", (unsigned long long) task_get_id());
+	int tempfile = open(tempfile_name, O_CREAT | O_RDWR);
+	if (tempfile < 0) {
+		pcut_report_test_done(test, TEST_OUTCOME_ERROR, "Failed to create temporary file.", NULL, NULL);
+		return;
+	}
+
+	char test_number_argument[MAX_TEST_NUMBER_WIDTH];
+	snprintf(test_number_argument, MAX_TEST_NUMBER_WIDTH, "-t%d", test->id);
+
+	int *files[4];
+	int fd_stdin = fileno(stdin);
+	files[0] = &fd_stdin;
+	files[1] = &tempfile;
+	files[2] = &tempfile;
+	files[3] = NULL;
+
+	const char *const arguments[3] = {
+		self_path,
+		test_number_argument,
+		NULL
+	};
+
+	int status = TEST_OUTCOME_PASS;
+
+	task_id_t task_id;
+	int rc = task_spawnvf(&task_id, self_path, arguments, files);
+	if (rc != EOK) {
+		status = TEST_OUTCOME_ERROR;
+		goto leave_close_tempfile;
+	}
+
+	task_exit_t task_exit;
+	int task_retval;
+	rc = task_wait(task_id, &task_exit, &task_retval);
+	if (rc != EOK) {
+		status = TEST_OUTCOME_ERROR;
+		goto leave_close_tempfile;
+	}
+	if (task_exit == TASK_EXIT_UNEXPECTED) {
+		status = TEST_OUTCOME_ERROR;
+	} else {
+		status = task_retval == 0 ? TEST_OUTCOME_PASS : TEST_OUTCOME_FAIL;
+	}
+
+	read_all(tempfile, extra_output_buffer, OUTPUT_BUFFER_SIZE);
+
+leave_close_tempfile:
+	close(tempfile);
+	unlink(tempfile_name);
+
+	pcut_report_test_done_unparsed(test, status, extra_output_buffer, OUTPUT_BUFFER_SIZE);
+}
Index: uspace/lib/pcut/src/os/stdc.c
===================================================================
--- uspace/lib/pcut/src/os/stdc.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/os/stdc.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * String operation functions for systems with a standard C library.
+ */
+
+#include <string.h>
+#include "../internal.h"
+
+int pcut_str_equals(const char *a, const char *b) {
+	return strcmp(a, b) == 0;
+}
+
+int pcut_str_start_equals(const char *a, const char *b, int len) {
+	return strncmp(a, b, len) == 0;
+}
+
+int pcut_str_size(const char *s) {
+	return strlen(s);
+}
+
+int pcut_str_to_int(const char *s) {
+	return atoi(s);
+}
+
+char *pcut_str_find_char(const char *haystack, const char needle) {
+	return strchr(haystack, needle);
+}
Index: uspace/lib/pcut/src/os/unix.c
===================================================================
--- uspace/lib/pcut/src/os/unix.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/os/unix.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Unix-specific functions for test execution via the fork() system call.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <string.h>
+#include "../internal.h"
+
+/** Maximum size of stdout we are able to capture. */
+#define OUTPUT_BUFFER_SIZE 8192
+
+/** Buffer for assertion and other error messages. */
+static char error_message_buffer[OUTPUT_BUFFER_SIZE];
+
+/** Buffer for stdout from the test. */
+static char extra_output_buffer[OUTPUT_BUFFER_SIZE];
+
+/** Prepare for a new test. */
+static void before_test_start(pcut_item_t *test) {
+	pcut_report_test_start(test);
+
+	memset(error_message_buffer, 0, OUTPUT_BUFFER_SIZE);
+	memset(extra_output_buffer, 0, OUTPUT_BUFFER_SIZE);
+}
+
+/** Read full buffer from given file descriptor.
+ *
+ * This function exists to overcome the possibility that read() may
+ * not fill the full length of the provided buffer even when EOF is
+ * not reached.
+ *
+ * @param fd Opened file descriptor.
+ * @param buffer Buffer to store data into.
+ * @param buffer_size Size of the @p buffer in bytes.
+ * @return Number of actually read bytes.
+ */
+static size_t read_all(int fd, char *buffer, size_t buffer_size) {
+	ssize_t actually_read;
+	char *buffer_start = buffer;
+	do {
+		actually_read = read(fd, buffer, buffer_size);
+		if (actually_read > 0) {
+			buffer += actually_read;
+			buffer_size -= actually_read;
+			if (buffer_size == 0) {
+				break;
+			}
+		}
+	} while (actually_read > 0);
+	if (buffer_start != buffer) {
+		if (*(buffer - 1) == 10) {
+			*(buffer - 1) = 0;
+			buffer--;
+		}
+	}
+	return buffer - buffer_start;
+}
+
+/** Convert program exit code to test outcome.
+ *
+ * @param status Status value from the wait() function.
+ * @return Test outcome code.
+ */
+static int convert_wait_status_to_outcome(int status) {
+	if (WIFEXITED(status)) {
+		if (WEXITSTATUS(status) != 0) {
+			return TEST_OUTCOME_FAIL;
+		} else {
+			return TEST_OUTCOME_PASS;
+		}
+	}
+
+	if (WIFSIGNALED(status)) {
+		return TEST_OUTCOME_ERROR;
+	}
+
+	return status;
+}
+
+/** Run the test in a forked environment and report the result.
+ *
+ * @param self_path Ignored.
+ * @param test Test to be run.
+ */
+void pcut_run_test_forking(const char *self_path, pcut_item_t *test) {
+	PCUT_UNUSED(self_path);
+
+	before_test_start(test);
+
+	int link_stdout[2], link_stderr[2];
+	pid_t pid;
+
+	int rc = pipe(link_stdout);
+	if (rc == -1) {
+		snprintf(error_message_buffer, OUTPUT_BUFFER_SIZE - 1,
+				"pipe() failed: %s.", strerror(rc));
+		pcut_report_test_done(test, TEST_OUTCOME_ERROR, error_message_buffer, NULL, NULL);
+		return;
+	}
+	rc = pipe(link_stderr);
+	if (rc == -1) {
+		snprintf(error_message_buffer, OUTPUT_BUFFER_SIZE - 1,
+				"pipe() failed: %s.", strerror(rc));
+		pcut_report_test_done(test, TEST_OUTCOME_ERROR, error_message_buffer, NULL, NULL);
+		return;
+	}
+
+	pid = fork();
+	if (pid == (pid_t)-1) {
+		snprintf(error_message_buffer, OUTPUT_BUFFER_SIZE - 1,
+			"fork() failed: %s.", strerror(rc));
+		rc = TEST_OUTCOME_ERROR;
+		goto leave_close_pipes;
+	}
+
+	if (pid == 0) {
+		/* We are the child. */
+		dup2(link_stdout[1], STDOUT_FILENO);
+		close(link_stdout[0]);
+		dup2(link_stderr[1], STDERR_FILENO);
+		close(link_stderr[0]);
+
+		rc = pcut_run_test_forked(test);
+
+		exit(rc);
+	}
+
+	close(link_stdout[1]);
+	close(link_stderr[1]);
+
+	size_t stderr_size = read_all(link_stderr[0], extra_output_buffer, OUTPUT_BUFFER_SIZE - 1);
+	read_all(link_stdout[0], extra_output_buffer, OUTPUT_BUFFER_SIZE - 1 - stderr_size);
+
+	int status;
+	wait(&status);
+
+	rc = convert_wait_status_to_outcome(status);
+
+	goto leave_close_parent_pipe;
+
+leave_close_pipes:
+	close(link_stdout[1]);
+	close(link_stderr[1]);
+leave_close_parent_pipe:
+	close(link_stdout[0]);
+	close(link_stderr[0]);
+
+	pcut_report_test_done_unparsed(test, rc, extra_output_buffer, OUTPUT_BUFFER_SIZE);
+}
Index: uspace/lib/pcut/src/print.c
===================================================================
--- uspace/lib/pcut/src/print.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/print.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Helper functions for debugging prints.
+ */
+
+#include <pcut/test.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "internal.h"
+
+/** Print all items in the given list.
+ *
+ * @param first First item to be printed.
+ */
+void pcut_print_items(pcut_item_t *first) {
+	pcut_item_t *it = first;
+	printf("====>\n");
+	while (it != NULL) {
+		switch (it->kind) {
+		case PCUT_KIND_TEST:
+			printf("TEST %s (%p)\n", it->test.name, it->test.func);
+			break;
+		case PCUT_KIND_TESTSUITE:
+			printf("SUITE %s\n", it->suite.name);
+			break;
+		case PCUT_KIND_SKIP:
+			break;
+		case PCUT_KIND_NESTED:
+			printf("NESTED ...\n");
+			break;
+		default:
+			printf("UNKNOWN (%d)\n", it->kind);
+			break;
+		}
+		it = it->next;
+	}
+	printf("----\n");
+}
+
+/** Print valid items in the list.
+ *
+ * @param first First item to be printed.
+ */
+void pcut_print_tests(pcut_item_t *first) {
+	for (pcut_item_t *it = pcut_get_real(first); it != NULL; it = pcut_get_real_next(it)) {
+		switch (it->kind) {
+		case PCUT_KIND_TESTSUITE:
+			printf("  Suite `%s' [%d]\n", it->suite.name, it->id);
+			break;
+		case PCUT_KIND_TEST:
+			printf("    Test `%s' [%d]\n", it->test.name, it->id);
+			break;
+		default:
+			assert(0 && "unreachable case in item-kind switch");
+			break;
+		}
+	}
+}
Index: uspace/lib/pcut/src/report/report.c
===================================================================
--- uspace/lib/pcut/src/report/report.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/report/report.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Common functions for test results reporting.
+ */
+
+#include "../internal.h"
+#ifndef __helenos__
+#include <string.h>
+#endif
+#include <stdio.h>
+
+/** Currently used report ops. */
+static pcut_report_ops_t *report_ops = NULL;
+
+/** Call a report function if it is available.
+ *
+ * @param op Operation to be called on the pcut_report_ops_t.
+ */
+#define REPORT_CALL(op, ...) \
+	if ((report_ops != NULL) && (report_ops->op != NULL)) report_ops->op(__VA_ARGS__)
+
+/** Print error message.
+ *
+ * NULL or empty message is silently ignored.
+ *
+ * The message is printed with a special 3-zero-byte prefix to be later
+ * parsed when reporting the results from a different process.
+ *
+ * @param msg The message to be printed.
+ */
+void pcut_print_fail_message(const char *msg) {
+	if (msg == NULL) {
+		return;
+	}
+	if (pcut_str_size(msg) == 0) {
+		return;
+	}
+
+	printf("%c%c%c%s\n%c", 0, 0, 0, msg, 0);
+}
+
+/** Size of buffer for storing error messages or extra test output. */
+#define BUFFER_SIZE 4096
+
+/** Buffer for stdout from the test. */
+static char buffer_for_extra_output[BUFFER_SIZE];
+
+/** Buffer for assertion and other error messages. */
+static char buffer_for_error_messages[BUFFER_SIZE];
+
+/** Parse output of a single test.
+ *
+ * @param full_output Full unparsed output.
+ * @param full_output_size Size of @p full_output in bytes.
+ * @param stdio_buffer Where to store normal output from the test.
+ * @param stdio_buffer_size Size of @p stdio_buffer in bytes.
+ * @param error_buffer Where to store error messages from the test.
+ * @param error_buffer_size Size of @p error_buffer in bytes.
+ */
+static void parse_command_output(const char *full_output, size_t full_output_size,
+		char *stdio_buffer, size_t stdio_buffer_size,
+		char *error_buffer, size_t error_buffer_size) {
+	memset(stdio_buffer, 0, stdio_buffer_size);
+	memset(error_buffer, 0, error_buffer_size);
+
+	/* Ensure that we do not read past the full_output. */
+	if (full_output[full_output_size - 1] != 0) {
+		// FIXME: can this happen?
+		return;
+	}
+
+	while (1) {
+		/* First of all, count number of zero bytes before the text. */
+		size_t cont_zeros_count = 0;
+		while (full_output[0] == 0) {
+			cont_zeros_count++;
+			full_output++;
+			full_output_size--;
+			if (full_output_size == 0) {
+				return;
+			}
+		}
+
+		/* Determine the length of the text after the zeros. */
+		size_t message_length = pcut_str_size(full_output);
+
+		if (cont_zeros_count < 2) {
+			/* Okay, standard I/O. */
+			if (message_length > stdio_buffer_size) {
+				// TODO: handle gracefully
+				return;
+			}
+			memcpy(stdio_buffer, full_output, message_length);
+			stdio_buffer += message_length;
+			stdio_buffer_size -= message_length;
+		} else {
+			/* Error message. */
+			if (message_length > error_buffer_size) {
+				// TODO: handle gracefully
+				return;
+			}
+			memcpy(error_buffer, full_output, message_length);
+			error_buffer += message_length;
+			error_buffer_size -= message_length;
+		}
+
+		full_output += message_length + 1;
+		full_output_size -= message_length + 1;
+	}
+}
+
+/** Use given set of functions for error reporting.
+ *
+ * @param ops Functions to use.
+ */
+void pcut_report_register_handler(pcut_report_ops_t *ops) {
+	report_ops = ops;
+}
+
+/** Initialize the report.
+ *
+ * @param all_items List of all tests that could be run.
+ */
+void pcut_report_init(pcut_item_t *all_items) {
+	REPORT_CALL(init, all_items);
+}
+
+/** Report that a test suite was started.
+ *
+ * @param suite Suite that was just started.
+ */
+void pcut_report_suite_start(pcut_item_t *suite) {
+	REPORT_CALL(suite_start, suite);
+}
+
+/** Report that a test suite was completed.
+ *
+ * @param suite Suite that just completed.
+ */
+void pcut_report_suite_done(pcut_item_t *suite) {
+	REPORT_CALL(suite_done, suite);
+}
+
+/** Report that a test is about to start.
+ *
+ * @param test Test to be run just about now.
+ */
+void pcut_report_test_start(pcut_item_t *test) {
+	REPORT_CALL(test_start, test);
+}
+
+/** Report that a test was completed.
+ *
+ * @param test Test that just finished.
+ * @param outcome Outcome of the test.
+ * @param error_message Buffer with error message.
+ * @param teardown_error_message Buffer with error message from a tear-down function.
+ * @param extra_output Extra output from the test (stdout).
+ */
+void pcut_report_test_done(pcut_item_t *test, int outcome,
+		const char *error_message, const char *teardown_error_message,
+		const char *extra_output) {
+	REPORT_CALL(test_done, test, outcome, error_message, teardown_error_message,
+			extra_output);
+}
+
+/** Report that a test was completed with unparsed test output.
+ *
+ * @param test Test that just finished
+ * @param outcome Outcome of the test.
+ * @param unparsed_output Buffer with all the output from the test.
+ * @param unparsed_output_size Size of @p unparsed_output in bytes.
+ */
+void pcut_report_test_done_unparsed(pcut_item_t *test, int outcome,
+		const char *unparsed_output, size_t unparsed_output_size) {
+
+	parse_command_output(unparsed_output, unparsed_output_size,
+			buffer_for_extra_output, BUFFER_SIZE,
+			buffer_for_error_messages, BUFFER_SIZE);
+
+	pcut_report_test_done(test, outcome, buffer_for_error_messages, NULL, buffer_for_extra_output);
+}
+
+/** Close the report.
+ *
+ */
+void pcut_report_done() {
+	REPORT_CALL(done);
+}
+
Index: uspace/lib/pcut/src/report/report.h
===================================================================
--- uspace/lib/pcut/src/report/report.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/report/report.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Test results reporting.
+ */
+
+#ifndef PCUT_REPORT_H_GUARD
+#define PCUT_REPORT_H_GUARD
+
+#include "../internal.h"
+
+/** Reporting functions for the test-anything-protocol. */
+extern pcut_report_ops_t pcut_report_tap;
+
+/** Reporting functions for XML report output. */
+extern pcut_report_ops_t pcut_report_xml;
+
+#endif
Index: uspace/lib/pcut/src/report/tap.c
===================================================================
--- uspace/lib/pcut/src/report/tap.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/report/tap.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Test-anything-protocol reporting routines.
+ */
+
+#include "../internal.h"
+#include "report.h"
+#ifndef __helenos__
+#include <string.h>
+#endif
+#include <stdio.h>
+
+/** Counter of all run tests. */
+static int test_counter;
+
+/** Counter for tests in a current suite. */
+static int tests_in_suite;
+
+/** Counter of failed tests in current suite. */
+static int failed_tests_in_suite;
+
+/** Initialize the tap output. */
+static void tap_init(pcut_item_t *all_items) {
+	int tests_total = pcut_count_tests(all_items);
+	test_counter = 0;
+
+	printf("1..%d\n", tests_total);
+}
+
+/** Report that a suite was started. */
+static void tap_suite_start(pcut_item_t *suite) {
+	tests_in_suite = 0;
+	failed_tests_in_suite = 0;
+
+	printf("#> Starting suite %s.\n", suite->suite.name);
+}
+
+/** Report that a suite was completed. */
+static void tap_suite_done(pcut_item_t *suite) {
+	printf("#> Finished suite %s (failed %d of %d).\n",
+			suite->suite.name, failed_tests_in_suite, tests_in_suite);
+}
+
+/** Report that a test was started.
+ *
+ * We do nothing - all handling is done after the test completes.
+ *
+ * @param test Test that is started.
+ */
+static void tap_test_start(pcut_item_t *test) {
+	PCUT_UNUSED(test);
+
+	tests_in_suite++;
+	test_counter++;
+}
+
+/** Print the buffer, prefix new line with a given string.
+ *
+ * @param message Message to print.
+ * @param prefix Prefix for each new line, such as comment character.
+ */
+static void print_by_lines(const char *message, const char *prefix) {
+	if ((message == NULL) || (message[0] == 0)) {
+		return;
+	}
+	char *next_line_start = pcut_str_find_char(message, '\n');
+	while (next_line_start != NULL) {
+		next_line_start[0] = 0;
+		printf("%s%s\n", prefix, message);
+		message = next_line_start + 1;
+		next_line_start = pcut_str_find_char(message, '\n');
+	}
+	if (message[0] != 0) {
+		printf("%s%s\n", prefix, message);
+	}
+}
+
+/** Report a completed test. */
+static void tap_test_done(pcut_item_t *test, int outcome,
+		const char *error_message, const char *teardown_error_message,
+		const char *extra_output) {
+	const char *test_name = test->test.name;
+
+	if (outcome != TEST_OUTCOME_PASS) {
+		failed_tests_in_suite++;
+	}
+
+	const char *status_str = NULL;
+	const char *fail_error_str = NULL;
+	switch (outcome) {
+	case TEST_OUTCOME_PASS:
+		status_str = "ok";
+		fail_error_str = "";
+		break;
+	case TEST_OUTCOME_FAIL:
+		status_str = "not ok";
+		fail_error_str = " failed";
+		break;
+	case TEST_OUTCOME_ERROR:
+		status_str = "not ok";
+		fail_error_str = " aborted";
+		break;
+	default:
+		/* Shall not get here. */
+		break;
+	}
+	printf("%s %d %s%s\n", status_str, test_counter, test_name, fail_error_str);
+
+	print_by_lines(error_message, "# error: ");
+	print_by_lines(teardown_error_message, "# error: ");
+
+	print_by_lines(extra_output, "# stdio: ");
+}
+
+/** Report testing done. */
+static void tap_done() {
+}
+
+
+pcut_report_ops_t pcut_report_tap = {
+	.init = tap_init,
+	.done = tap_done,
+	.suite_start = tap_suite_start,
+	.suite_done = tap_suite_done,
+	.test_start = tap_test_start,
+	.test_done = tap_test_done
+};
Index: uspace/lib/pcut/src/report/xml.c
===================================================================
--- uspace/lib/pcut/src/report/xml.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/report/xml.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Reporting routines for XML output (non-standard).
+ */
+
+#include "../internal.h"
+#include "report.h"
+#ifndef __helenos__
+#include <string.h>
+#endif
+#include <stdio.h>
+
+/** Counter of all run tests. */
+static int test_counter;
+
+/** Counter for tests in a current suite. */
+static int tests_in_suite;
+
+/** Counter of failed tests in current suite. */
+static int failed_tests_in_suite;
+
+/** Initialize the XML output. */
+static void xml_init(pcut_item_t *all_items) {
+	printf("<?xml version=\"1.0\"?>\n");
+
+	int tests_total = pcut_count_tests(all_items);
+	test_counter = 0;
+
+	printf("<report tests-total=\"%d\">\n", tests_total);
+}
+
+/** Report that a suite was started. */
+static void xml_suite_start(pcut_item_t *suite) {
+	tests_in_suite = 0;
+	failed_tests_in_suite = 0;
+
+	printf("\t<suite name=\"%s\">\n", suite->suite.name);
+}
+
+/** Report that a suite was completed. */
+static void xml_suite_done(pcut_item_t *suite) {
+	printf("\t</suite><!-- %s: %d / %d -->\n", suite->suite.name,
+		failed_tests_in_suite, tests_in_suite);
+}
+
+/** Report that a test was started.
+ *
+ * We do nothing - all handling is done after the test completes.
+ *
+ * @param test Test that is started.
+ */
+static void xml_test_start(pcut_item_t *test) {
+	PCUT_UNUSED(test);
+
+	tests_in_suite++;
+	test_counter++;
+}
+
+/** Print the buffer as a CDATA into given element.
+ *
+ * @param message Message to print.
+ * @param element_name Wrapping XML element name.
+ */
+static void print_by_lines(const char *message, const char *element_name) {
+	if ((message == NULL) || (message[0] == 0)) {
+		return;
+	}
+
+	printf("\t\t\t<%s><![CDATA[", element_name);
+
+	char *next_line_start = pcut_str_find_char(message, '\n');
+	while (next_line_start != NULL) {
+		next_line_start[0] = 0;
+		printf("%s\n", message);
+		message = next_line_start + 1;
+		next_line_start = pcut_str_find_char(message, '\n');
+	}
+	if (message[0] != 0) {
+		printf("%s\n", message);
+	}
+
+	printf("]]></%s>\n", element_name);
+}
+
+/** Report a completed test. */
+static void xml_test_done(pcut_item_t *test, int outcome,
+		const char *error_message, const char *teardown_error_message,
+		const char *extra_output) {
+	const char *test_name = test->test.name;
+
+	if (outcome != TEST_OUTCOME_PASS) {
+		failed_tests_in_suite++;
+	}
+
+	const char *status_str = NULL;
+	switch (outcome) {
+	case TEST_OUTCOME_PASS:
+		status_str = "pass";
+		break;
+	case TEST_OUTCOME_FAIL:
+		status_str = "fail";
+		break;
+	case TEST_OUTCOME_ERROR:
+		status_str = "error";
+		break;
+	default:
+		/* Shall not get here. */
+		break;
+	}
+
+	printf("\t\t<testcase name=\"%s\" status=\"%s\">\n", test_name,
+		status_str);
+
+	print_by_lines(error_message, "error-message");
+	print_by_lines(teardown_error_message, "error-message");
+
+	print_by_lines(extra_output, "standard-output");
+
+	printf("\t\t</testcase><!-- %s -->\n", test_name);
+}
+
+/** Report testing done. */
+static void xml_done() {
+	printf("</report>\n");
+}
+
+
+pcut_report_ops_t pcut_report_xml = {
+	.init = xml_init,
+	.done = xml_done,
+	.suite_start = xml_suite_start,
+	.suite_done = xml_suite_done,
+	.test_start = xml_test_start,
+	.test_done = xml_test_done
+};
Index: uspace/lib/pcut/src/run.c
===================================================================
--- uspace/lib/pcut/src/run.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/src/run.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * Test execution routines.
+ */
+
+#include "internal.h"
+#ifndef PCUT_NO_LONG_JUMP
+#include <setjmp.h>
+#endif
+
+#ifndef PCUT_NO_LONG_JUMP
+/** Long-jump buffer. */
+static jmp_buf start_test_jump;
+#endif
+
+/** Whether to run a tear-down function on a failure.
+ *
+ * Used to determine whether we are already in a tear-down context.
+ */
+static int execute_teardown_on_failure;
+
+/** Whether to report test result at all.
+ *
+ * Used to determine whether we are the forked or the parent process.
+ */
+static int report_test_result;
+
+/** Whether to print test error.
+ *
+ * Used to determine whether we are the forked or the parent process.
+ */
+static int print_test_error;
+
+/** Whether leaving a test means a process exit. */
+static int leave_means_exit;
+
+/** Pointer to currently running test. */
+static pcut_item_t *current_test = NULL;
+
+/** Pointer to current test suite. */
+static pcut_item_t *current_suite = NULL;
+
+/** A NULL-like suite. */
+static pcut_item_t default_suite = {
+	.kind = PCUT_KIND_TESTSUITE,
+	.id = -1,
+	.previous = NULL,
+	.next = NULL,
+	.suite = {
+		.name = "Default",
+		.setup = NULL,
+		.teardown = NULL
+	}
+};
+
+/** Find the suite given test belongs to.
+ *
+ * @param it The test.
+ * @return Always a valid test suite item.
+ */
+static pcut_item_t *pcut_find_parent_suite(pcut_item_t *it) {
+	while (it != NULL) {
+		if (it->kind == PCUT_KIND_TESTSUITE) {
+			return it;
+		}
+		it = it->previous;
+	}
+	return &default_suite;
+}
+
+/** Run a set-up (tear-down) function.
+ *
+ * @param func Function to run (can be NULL).
+ */
+static void run_setup_teardown(pcut_setup_func_t func) {
+	if (func != NULL) {
+		func();
+	}
+}
+
+/** Terminate current test with given outcome.
+ *
+ * @warning This function may execute a long jump or terminate
+ * current process.
+ *
+ * @param outcome Outcome of the current test.
+ */
+static void leave_test(int outcome) {
+	if (leave_means_exit) {
+		exit(outcome);
+	}
+
+#ifndef PCUT_NO_LONG_JUMP
+	longjmp(start_test_jump, 1);
+#endif
+}
+
+/** Process a failed assertion.
+ *
+ * @warning This function calls leave_test() and typically will not
+ * return.
+ *
+ * @param message Message describing the failure.
+ */
+void pcut_failed_assertion(const char *message) {
+	static const char *prev_message = NULL;
+	/*
+	 * The assertion failed. We need to abort the current test,
+	 * inform the user and perform some clean-up. That could
+	 * include running the tear-down routine.
+	 */
+	if (print_test_error) {
+		pcut_print_fail_message(message);
+	}
+
+	if (execute_teardown_on_failure) {
+		execute_teardown_on_failure = 0;
+		prev_message = message;
+		run_setup_teardown(current_suite->suite.teardown);
+
+		/* Tear-down was okay. */
+		if (report_test_result) {
+			pcut_report_test_done(current_test, TEST_OUTCOME_FAIL,
+				message, NULL, NULL);
+		}
+	} else {
+		if (report_test_result) {
+			pcut_report_test_done(current_test, TEST_OUTCOME_FAIL,
+				prev_message, message, NULL);
+		}
+	}
+
+	prev_message = NULL;
+
+	leave_test(TEST_OUTCOME_FAIL); /* No return. */
+}
+
+/** Run a test.
+ *
+ * @param test Test to execute.
+ * @return Error status (zero means success).
+ */
+static int run_test(pcut_item_t *test) {
+	/*
+	 * Set here as the returning point in case of test failure.
+	 * If we get here, it means something failed during the
+	 * test execution.
+	 */
+#ifndef PCUT_NO_LONG_JUMP
+	int test_finished = setjmp(start_test_jump);
+	if (test_finished) {
+		return 1;
+	}
+#endif
+
+	if (report_test_result) {
+		pcut_report_test_start(test);
+	}
+
+	current_suite = pcut_find_parent_suite(test);
+	current_test = test;
+
+	/*
+	 * If anything goes wrong, execute the tear-down function
+	 * as well.
+	 */
+	execute_teardown_on_failure = 1;
+
+	/*
+	 * Run the set-up function.
+	 */
+	run_setup_teardown(current_suite->suite.setup);
+
+	/*
+	 * The setup function was performed, it is time to run
+	 * the actual test.
+	 */
+	test->test.func();
+
+	/*
+	 * Finally, run the tear-down function. We need to clear
+	 * the flag to prevent endless loop.
+	 */
+	execute_teardown_on_failure = 0;
+	run_setup_teardown(current_suite->suite.teardown);
+
+	/*
+	 * If we got here, it means everything went well with
+	 * this test.
+	 */
+	if (report_test_result) {
+		pcut_report_test_done(current_test, TEST_OUTCOME_PASS,
+			NULL, NULL, NULL);
+	}
+
+	return 0;
+}
+
+/** Run a test in a forked mode.
+ *
+ * Forked mode means that the caller of the test is already a new
+ * process running this test only.
+ *
+ * @param test Test to execute.
+ * @return Error status (zero means success).
+ */
+int pcut_run_test_forked(pcut_item_t *test) {
+	report_test_result = 0;
+	print_test_error = 1;
+	leave_means_exit = 1;
+
+	int rc = run_test(test);
+
+	current_test = NULL;
+	current_suite = NULL;
+
+	return rc;
+}
+
+/** Run a test in a single mode.
+ *
+ * Single mode means that the test is called in the context of the
+ * parent process, that is no new process is forked.
+ *
+ * @param test Test to execute.
+ * @return Error status (zero means success).
+ */
+int pcut_run_test_single(pcut_item_t *test) {
+	report_test_result = 1;
+	print_test_error = 0;
+	leave_means_exit = 0;
+
+	int rc = run_test(test);
+
+	current_test = NULL;
+	current_suite = NULL;
+
+	return rc;
+}
+
Index: uspace/lib/pcut/tests/alloc.c
===================================================================
--- uspace/lib/pcut/tests/alloc.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/alloc.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+PCUT_INIT
+
+static char *buffer = NULL;
+#define BUFFER_SIZE 512
+
+PCUT_TEST_SUITE(suite_with_setup_and_teardown)
+
+PCUT_TEST_BEFORE {
+	buffer = malloc(BUFFER_SIZE);
+	PCUT_ASSERT_NOT_NULL(buffer);
+}
+
+PCUT_TEST_AFTER {
+	free(buffer);
+	buffer = NULL;
+}
+
+PCUT_TEST(snprintf) {
+	snprintf(buffer, BUFFER_SIZE - 1, "%d-%s", 56, "abcd");
+	PCUT_ASSERT_STR_EQUALS("56-abcd", buffer);
+}
+
+PCUT_TEST_SUITE(another_without_setup)
+
+PCUT_TEST(whatever) {
+	PCUT_ASSERT_NULL(buffer);
+}
+
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/alloc.expected
===================================================================
--- uspace/lib/pcut/tests/alloc.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/alloc.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,7 @@
+1..2
+#> Starting suite suite_with_setup_and_teardown.
+ok 1 snprintf
+#> Finished suite suite_with_setup_and_teardown (failed 0 of 1).
+#> Starting suite another_without_setup.
+ok 2 whatever
+#> Finished suite another_without_setup (failed 0 of 1).
Index: uspace/lib/pcut/tests/asserts.c
===================================================================
--- uspace/lib/pcut/tests/asserts.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/asserts.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST(int_equals) {
+	PCUT_ASSERT_INT_EQUALS(1, 1);
+	PCUT_ASSERT_INT_EQUALS(1, 0);
+}
+
+PCUT_TEST(double_equals) {
+	PCUT_ASSERT_DOUBLE_EQUALS(1., 1., 0.001);
+	PCUT_ASSERT_DOUBLE_EQUALS(1., 0.5, 0.4);
+}
+
+PCUT_TEST(str_equals) {
+	PCUT_ASSERT_STR_EQUALS("xyz", "xyz");
+	PCUT_ASSERT_STR_EQUALS("abc", "xyz");
+}
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/asserts.expected
===================================================================
--- uspace/lib/pcut/tests/asserts.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/asserts.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,9 @@
+1..3
+#> Starting suite Default.
+not ok 1 int_equals failed
+# error: asserts.c:36: Expected <1> but got <0> (1 != 0)
+not ok 2 double_equals failed
+# error: asserts.c:41: Expected <1.000000+-0.400000> but got <0.500000> (1. != 0.5)
+not ok 3 str_equals failed
+# error: asserts.c:46: Expected <abc> but got <xyz> ("abc" != "xyz")
+#> Finished suite Default (failed 3 of 3).
Index: uspace/lib/pcut/tests/manytests.c
===================================================================
--- uspace/lib/pcut/tests/manytests.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/manytests.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+
+/*
+ * Just test how it will look like if a huge number of tests would
+ * be present in the suite.
+ */
+
+PCUT_INIT
+
+PCUT_TEST(my_test_001) { }
+PCUT_TEST(my_test_002) { }
+PCUT_TEST(my_test_003) { }
+PCUT_TEST(my_test_004) { }
+PCUT_TEST(my_test_005) { }
+PCUT_TEST(my_test_006) { }
+PCUT_TEST(my_test_007) { }
+PCUT_TEST(my_test_008) { }
+PCUT_TEST(my_test_009) { }
+PCUT_TEST(my_test_010) { }
+PCUT_TEST(my_test_011) { }
+PCUT_TEST(my_test_012) { }
+PCUT_TEST(my_test_013) { }
+PCUT_TEST(my_test_014) { }
+PCUT_TEST(my_test_015) { }
+PCUT_TEST(my_test_016) { }
+PCUT_TEST(my_test_017) { }
+PCUT_TEST(my_test_018) { }
+PCUT_TEST(my_test_019) { }
+PCUT_TEST(my_test_020) { }
+PCUT_TEST(my_test_021) { }
+PCUT_TEST(my_test_022) { }
+PCUT_TEST(my_test_023) { }
+PCUT_TEST(my_test_024) { }
+PCUT_TEST(my_test_025) { }
+PCUT_TEST(my_test_026) { }
+PCUT_TEST(my_test_027) { }
+PCUT_TEST(my_test_028) { }
+PCUT_TEST(my_test_029) { }
+PCUT_TEST(my_test_030) { }
+PCUT_TEST(my_test_031) { }
+PCUT_TEST(my_test_032) { }
+PCUT_TEST(my_test_033) { }
+PCUT_TEST(my_test_034) { }
+PCUT_TEST(my_test_035) { }
+PCUT_TEST(my_test_036) { }
+PCUT_TEST(my_test_037) { }
+PCUT_TEST(my_test_038) { }
+PCUT_TEST(my_test_039) { }
+PCUT_TEST(my_test_040) { }
+PCUT_TEST(my_test_041) { }
+PCUT_TEST(my_test_042) { }
+PCUT_TEST(my_test_043) { }
+PCUT_TEST(my_test_044) { }
+PCUT_TEST(my_test_045) { }
+PCUT_TEST(my_test_046) { }
+PCUT_TEST(my_test_047) { }
+PCUT_TEST(my_test_048) { }
+PCUT_TEST(my_test_049) { }
+PCUT_TEST(my_test_050) { }
+PCUT_TEST(my_test_051) { }
+PCUT_TEST(my_test_052) { }
+PCUT_TEST(my_test_053) { }
+PCUT_TEST(my_test_054) { }
+PCUT_TEST(my_test_055) { }
+PCUT_TEST(my_test_056) { }
+PCUT_TEST(my_test_057) { }
+PCUT_TEST(my_test_058) { }
+PCUT_TEST(my_test_059) { }
+PCUT_TEST(my_test_060) { }
+PCUT_TEST(my_test_061) { }
+PCUT_TEST(my_test_062) { }
+PCUT_TEST(my_test_063) { }
+PCUT_TEST(my_test_064) { }
+PCUT_TEST(my_test_065) { }
+PCUT_TEST(my_test_066) { }
+PCUT_TEST(my_test_067) { }
+PCUT_TEST(my_test_068) { }
+PCUT_TEST(my_test_069) { }
+PCUT_TEST(my_test_070) { }
+PCUT_TEST(my_test_071) { }
+PCUT_TEST(my_test_072) { }
+PCUT_TEST(my_test_073) { }
+PCUT_TEST(my_test_074) { }
+PCUT_TEST(my_test_075) { }
+PCUT_TEST(my_test_076) { }
+PCUT_TEST(my_test_077) { }
+PCUT_TEST(my_test_078) { }
+PCUT_TEST(my_test_079) { }
+PCUT_TEST(my_test_080) { }
+
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/manytests.expected
===================================================================
--- uspace/lib/pcut/tests/manytests.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/manytests.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,83 @@
+1..80
+#> Starting suite Default.
+ok 1 my_test_001
+ok 2 my_test_002
+ok 3 my_test_003
+ok 4 my_test_004
+ok 5 my_test_005
+ok 6 my_test_006
+ok 7 my_test_007
+ok 8 my_test_008
+ok 9 my_test_009
+ok 10 my_test_010
+ok 11 my_test_011
+ok 12 my_test_012
+ok 13 my_test_013
+ok 14 my_test_014
+ok 15 my_test_015
+ok 16 my_test_016
+ok 17 my_test_017
+ok 18 my_test_018
+ok 19 my_test_019
+ok 20 my_test_020
+ok 21 my_test_021
+ok 22 my_test_022
+ok 23 my_test_023
+ok 24 my_test_024
+ok 25 my_test_025
+ok 26 my_test_026
+ok 27 my_test_027
+ok 28 my_test_028
+ok 29 my_test_029
+ok 30 my_test_030
+ok 31 my_test_031
+ok 32 my_test_032
+ok 33 my_test_033
+ok 34 my_test_034
+ok 35 my_test_035
+ok 36 my_test_036
+ok 37 my_test_037
+ok 38 my_test_038
+ok 39 my_test_039
+ok 40 my_test_040
+ok 41 my_test_041
+ok 42 my_test_042
+ok 43 my_test_043
+ok 44 my_test_044
+ok 45 my_test_045
+ok 46 my_test_046
+ok 47 my_test_047
+ok 48 my_test_048
+ok 49 my_test_049
+ok 50 my_test_050
+ok 51 my_test_051
+ok 52 my_test_052
+ok 53 my_test_053
+ok 54 my_test_054
+ok 55 my_test_055
+ok 56 my_test_056
+ok 57 my_test_057
+ok 58 my_test_058
+ok 59 my_test_059
+ok 60 my_test_060
+ok 61 my_test_061
+ok 62 my_test_062
+ok 63 my_test_063
+ok 64 my_test_064
+ok 65 my_test_065
+ok 66 my_test_066
+ok 67 my_test_067
+ok 68 my_test_068
+ok 69 my_test_069
+ok 70 my_test_070
+ok 71 my_test_071
+ok 72 my_test_072
+ok 73 my_test_073
+ok 74 my_test_074
+ok 75 my_test_075
+ok 76 my_test_076
+ok 77 my_test_077
+ok 78 my_test_078
+ok 79 my_test_079
+ok 80 my_test_080
+#> Finished suite Default (failed 0 of 80).
Index: uspace/lib/pcut/tests/multisuite.expected
===================================================================
--- uspace/lib/pcut/tests/multisuite.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/multisuite.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,12 @@
+1..4
+#> Starting suite intpow.
+not ok 1 zero_exponent failed
+# error: suite1.c:37: Expected <1> but got <0> (1 != intpow(2, 0))
+not ok 2 one_exponent failed
+# error: suite1.c:41: Expected <2> but got <0> (2 != intpow(2, 1))
+#> Finished suite intpow (failed 2 of 2).
+#> Starting suite intmin.
+not ok 3 test_min failed
+# error: suite2.c:38: Expected <5> but got <654> (5 != intmin(654, 5))
+ok 4 test_same_numbers
+#> Finished suite intmin (failed 1 of 2).
Index: uspace/lib/pcut/tests/null.c
===================================================================
--- uspace/lib/pcut/tests/null.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/null.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST(access_null_pointer) {
+	int a = 5;
+	int *p = &a;
+	PCUT_ASSERT_INT_EQUALS(5, *p);
+	p = NULL;
+	PCUT_ASSERT_INT_EQUALS(5, *p);
+}
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/null.expected
===================================================================
--- uspace/lib/pcut/tests/null.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/null.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,4 @@
+1..1
+#> Starting suite Default.
+not ok 1 access_null_pointer aborted
+#> Finished suite Default (failed 1 of 1).
Index: uspace/lib/pcut/tests/nullteardown.c
===================================================================
--- uspace/lib/pcut/tests/nullteardown.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/nullteardown.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST_AFTER {
+	int a = 5;
+	int *p = &a;
+	PCUT_ASSERT_INT_EQUALS(5, *p);
+	p = NULL;
+	PCUT_ASSERT_INT_EQUALS(5, *p);
+}
+
+PCUT_TEST(print_and_fail) {
+	printf("Tear-down will cause null pointer access...\n");
+	PCUT_ASSERT_NOT_NULL(NULL);
+}
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/nullteardown.expected
===================================================================
--- uspace/lib/pcut/tests/nullteardown.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/nullteardown.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,6 @@
+1..1
+#> Starting suite Default.
+not ok 1 print_and_fail aborted
+# error: nullteardown.c:45: Pointer <NULL> ought not to be NULL
+# stdio: Tear-down will cause null pointer access...
+#> Finished suite Default (failed 1 of 1).
Index: uspace/lib/pcut/tests/printing.c
===================================================================
--- uspace/lib/pcut/tests/printing.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/printing.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+#include <stdio.h>
+
+PCUT_INIT
+
+PCUT_TEST(print_to_stdout) {
+	printf("Printed from a test to stdout!\n");
+}
+
+PCUT_TEST(print_to_stderr) {
+	fprintf(stderr, "Printed from a test to stderr!\n");
+}
+
+PCUT_TEST(print_to_stdout_and_fail) {
+	printf("Printed from a test to stdout!\n");
+	PCUT_ASSERT_NOT_NULL(0);
+}
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/printing.expected
===================================================================
--- uspace/lib/pcut/tests/printing.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/printing.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,10 @@
+1..3
+#> Starting suite Default.
+ok 1 print_to_stdout
+# stdio: Printed from a test to stdout!
+ok 2 print_to_stderr
+# stdio: Printed from a test to stderr!
+not ok 3 print_to_stdout_and_fail failed
+# error: printing.c:45: Pointer <0> ought not to be NULL
+# stdio: Printed from a test to stdout!
+#> Finished suite Default (failed 1 of 3).
Index: uspace/lib/pcut/tests/simple.c
===================================================================
--- uspace/lib/pcut/tests/simple.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/simple.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST(zero_exponent) {
+	PCUT_ASSERT_INT_EQUALS(1, intpow(2, 0));
+}
+
+PCUT_TEST(one_exponent) {
+	PCUT_ASSERT_INT_EQUALS(2, intpow(2, 1));
+	PCUT_ASSERT_INT_EQUALS(39, intpow(39, 1));
+}
+
+PCUT_TEST(same_strings) {
+	const char *p = "xyz";
+	PCUT_ASSERT_STR_EQUALS("xyz", p);
+	PCUT_ASSERT_STR_EQUALS("abc", "XXXabd" + 3);
+}
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/simple.expected
===================================================================
--- uspace/lib/pcut/tests/simple.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/simple.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,9 @@
+1..3
+#> Starting suite Default.
+not ok 1 zero_exponent failed
+# error: simple.c:35: Expected <1> but got <0> (1 != intpow(2, 0))
+not ok 2 one_exponent failed
+# error: simple.c:39: Expected <2> but got <0> (2 != intpow(2, 1))
+not ok 3 same_strings failed
+# error: simple.c:46: Expected <abc> but got <abd> ("abc" != "XXXabd" + 3)
+#> Finished suite Default (failed 3 of 3).
Index: uspace/lib/pcut/tests/suite1.c
===================================================================
--- uspace/lib/pcut/tests/suite1.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/suite1.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(intpow);
+
+PCUT_TEST(zero_exponent) {
+	PCUT_ASSERT_INT_EQUALS(1, intpow(2, 0));
+}
+
+PCUT_TEST(one_exponent) {
+	PCUT_ASSERT_INT_EQUALS(2, intpow(2, 1));
+	PCUT_ASSERT_INT_EQUALS(39, intpow(39, 1));
+}
+
+PCUT_EXPORT(intpow_suite);
Index: uspace/lib/pcut/tests/suite2.c
===================================================================
--- uspace/lib/pcut/tests/suite2.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/suite2.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(intmin);
+
+PCUT_TEST(test_min) {
+	PCUT_ASSERT_INT_EQUALS(5, intmin(5, 654));
+	PCUT_ASSERT_INT_EQUALS(5, intmin(654, 5));
+
+	PCUT_ASSERT_INT_EQUALS(-17, intmin(-17, -2));
+}
+
+PCUT_TEST(test_same_numbers) {
+	PCUT_ASSERT_INT_EQUALS(5, intmin(5, 5));
+	PCUT_ASSERT_INT_EQUALS(719, intmin(719, 719));
+	PCUT_ASSERT_INT_EQUALS(-4589, intmin(-4589, 4589));
+}
+
+PCUT_EXPORT(intmin_suite);
Index: uspace/lib/pcut/tests/suite_all.c
===================================================================
--- uspace/lib/pcut/tests/suite_all.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/suite_all.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+
+PCUT_INIT
+
+PCUT_IMPORT(intpow_suite);
+PCUT_IMPORT(intmin_suite);
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/suites.c
===================================================================
--- uspace/lib/pcut/tests/suites.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/suites.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+PCUT_TEST_SUITE(intpow);
+
+PCUT_TEST(zero_exponent) {
+	PCUT_ASSERT_INT_EQUALS(1, intpow(2, 0));
+}
+
+PCUT_TEST(one_exponent) {
+	PCUT_ASSERT_INT_EQUALS(2, intpow(2, 1));
+	PCUT_ASSERT_INT_EQUALS(39, intpow(39, 1));
+}
+
+PCUT_TEST_SUITE(intmin);
+
+PCUT_TEST(test_min) {
+	PCUT_ASSERT_INT_EQUALS(5, intmin(5, 654));
+	PCUT_ASSERT_INT_EQUALS(5, intmin(654, 5));
+
+	PCUT_ASSERT_INT_EQUALS(-17, intmin(-17, -2));
+}
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/suites.expected
===================================================================
--- uspace/lib/pcut/tests/suites.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/suites.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,11 @@
+1..3
+#> Starting suite intpow.
+not ok 1 zero_exponent failed
+# error: suites.c:37: Expected <1> but got <0> (1 != intpow(2, 0))
+not ok 2 one_exponent failed
+# error: suites.c:41: Expected <2> but got <0> (2 != intpow(2, 1))
+#> Finished suite intpow (failed 2 of 2).
+#> Starting suite intmin.
+not ok 3 test_min failed
+# error: suites.c:49: Expected <5> but got <654> (5 != intmin(654, 5))
+#> Finished suite intmin (failed 1 of 1).
Index: uspace/lib/pcut/tests/teardown.c
===================================================================
--- uspace/lib/pcut/tests/teardown.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/teardown.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <pcut/test.h>
+#include "tested.h"
+
+PCUT_INIT
+
+
+
+PCUT_TEST_SUITE(with_teardown);
+
+PCUT_TEST_AFTER {
+	printf("This is teardown-function.\n");
+}
+
+PCUT_TEST(empty) {
+}
+
+PCUT_TEST(failing) {
+	PCUT_ASSERT_INT_EQUALS(10, intmin(1, 2));
+}
+
+
+
+PCUT_TEST_SUITE(with_failing_teardown)
+
+PCUT_TEST_AFTER {
+	printf("This is failing teardown-function.\n");
+	PCUT_ASSERT_INT_EQUALS(42, intmin(10, 20));
+}
+
+PCUT_TEST(empty2) {
+}
+
+PCUT_TEST(printing2) {
+	printf("Printed before test failure.\n");
+	PCUT_ASSERT_INT_EQUALS(0, intmin(-17, -19));
+}
+
+PCUT_TEST(failing2) {
+	PCUT_ASSERT_INT_EQUALS(12, intmin(3, 5));
+}
+
+
+PCUT_MAIN()
Index: uspace/lib/pcut/tests/teardown.expected
===================================================================
--- uspace/lib/pcut/tests/teardown.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/teardown.expected	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,22 @@
+1..5
+#> Starting suite with_teardown.
+ok 1 empty
+# stdio: This is teardown-function.
+not ok 2 failing failed
+# error: teardown.c:47: Expected <10> but got <1> (10 != intmin(1, 2))
+# stdio: This is teardown-function.
+#> Finished suite with_teardown (failed 1 of 2).
+#> Starting suite with_failing_teardown.
+not ok 3 empty2 failed
+# error: teardown.c:56: Expected <42> but got <10> (42 != intmin(10, 20))
+# stdio: This is failing teardown-function.
+not ok 4 printing2 failed
+# error: teardown.c:64: Expected <0> but got <-17> (0 != intmin(-17, -19))
+# error: teardown.c:56: Expected <42> but got <10> (42 != intmin(10, 20))
+# stdio: Printed before test failure.
+# stdio: This is failing teardown-function.
+not ok 5 failing2 failed
+# error: teardown.c:68: Expected <12> but got <3> (12 != intmin(3, 5))
+# error: teardown.c:56: Expected <42> but got <10> (42 != intmin(10, 20))
+# stdio: This is failing teardown-function.
+#> Finished suite with_failing_teardown (failed 3 of 3).
Index: uspace/lib/pcut/tests/tested.c
===================================================================
--- uspace/lib/pcut/tests/tested.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/tested.c	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tested.h"
+
+#define UNUSED(a) ((void)a)
+
+long intpow(int base, int exp) {
+	UNUSED(base); UNUSED(exp);
+	return 0;
+}
+
+int intmin(int a, int b) {
+	UNUSED(b);
+	return a;
+}
Index: uspace/lib/pcut/tests/tested.h
===================================================================
--- uspace/lib/pcut/tests/tested.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/tested.h	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012-2013 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TESTED_H
+#define TESTED_H
+
+long intpow(int base, int exp);
+
+int intmin(int a, int b);
+
+#endif
Index: uspace/lib/pcut/tests/tests.mak
===================================================================
--- uspace/lib/pcut/tests/tests.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/tests/tests.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+TEST_DEPS = $(TEST_BASE)tested.o $(PCUT_LIB)
+
+TEST_APPS = \
+	$(TEST_BASE)alloc.$(EXE_EXT) \
+	$(TEST_BASE)asserts.$(EXE_EXT) \
+	$(TEST_BASE)manytests.$(EXE_EXT) \
+	$(TEST_BASE)multisuite.$(EXE_EXT) \
+	$(TEST_BASE)null.$(EXE_EXT) \
+	$(TEST_BASE)nullteardown.$(EXE_EXT) \
+	$(TEST_BASE)printing.$(EXE_EXT) \
+	$(TEST_BASE)simple.$(EXE_EXT) \
+	$(TEST_BASE)suites.$(EXE_EXT) \
+	$(TEST_BASE)teardown.$(EXE_EXT)
+
+check-build: $(TEST_APPS)
+
+.PRECIOUS: $(TEST_BASE)tested.o
+
+check-clean:
+	rm -f $(TEST_BASE)*.o $(TEST_BASE)*.$(EXE_EXT) $(TEST_BASE)*.got
+
+$(TEST_BASE)%.$(EXE_EXT): $(TEST_DEPS)
+	$(CC) -o $@ $^ $(TEST_LDFLAGS)
+
+$(TEST_BASE)alloc.$(EXE_EXT): $(TEST_BASE)alloc.o
+$(TEST_BASE)asserts.$(EXE_EXT): $(TEST_BASE)asserts.o
+$(TEST_BASE)manytests.$(EXE_EXT): $(TEST_BASE)manytests.o
+$(TEST_BASE)multisuite.$(EXE_EXT): $(TEST_BASE)suite_all.o $(TEST_BASE)suite1.o $(TEST_BASE)suite2.o
+$(TEST_BASE)null.$(EXE_EXT): $(TEST_BASE)null.o
+$(TEST_BASE)nullteardown.$(EXE_EXT): $(TEST_BASE)nullteardown.o
+$(TEST_BASE)printing.$(EXE_EXT): $(TEST_BASE)printing.o
+$(TEST_BASE)simple.$(EXE_EXT): $(TEST_BASE)simple.o
+$(TEST_BASE)suites.$(EXE_EXT): $(TEST_BASE)suites.o
+$(TEST_BASE)teardown.$(EXE_EXT): $(TEST_BASE)teardown.o
+
+$(TEST_BASE)%.o: $(TEST_BASE)%.c
+	$(CC) -c -o $@ $(TEST_CFLAGS) $<
Index: uspace/lib/pcut/unix.mak
===================================================================
--- uspace/lib/pcut/unix.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/unix.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+PCUT_TARGET_SOURCES = src/os/stdc.c src/os/unix.c
+OBJ_EXT = o
+PCUT_LIB = libpcut.a
+
+# Installation paths
+PREFIX = /usr/local
+LIBDIR = $(PREFIX)/lib
+INCLUDEDIR = $(PREFIX)/include
+
+-include pcut.mak
+
+PCUT_OBJECTS := $(addsuffix .o,$(basename $(PCUT_SOURCES)))
+
+# Take care of dependencies
+DEPEND = Makefile.depend
+-include $(DEPEND)
+$(DEPEND):
+	makedepend -f - -Iinclude -- $(PCUT_SOURCES) >$@ 2>/dev/null
+
+
+#
+# Add the check target for running all the tests
+#
+TEST_BASE = tests/
+EXE_EXT = run
+TEST_CFLAGS = $(PCUT_CFLAGS)
+TEST_LDFLAGS = -L. -lpcut
+-include tests/tests.mak
+TEST_APPS_BASENAMES := $(basename $(TEST_APPS))
+DIFF = diff
+DIFFFLAGS = -du1
+
+check: libpcut.a check-build
+	@for i in $(TEST_APPS_BASENAMES); do \
+		echo -n ./$$i; \
+		./$$i.$(EXE_EXT) | sed 's:$(TEST_BASE)::g' >$$i.got; \
+		if cmp -s $$i.got $$i.expected; then \
+			echo " ok."; \
+		else \
+			echo " failed:"; \
+			$(DIFF) $(DIFFFLAGS) $$i.expected $$i.got; \
+		fi; \
+	done
+
+#
+# Clean-up
+#
+platform-clean:
+	rm -f libpcut.a $(DEPEND)
+
+#
+# Actual build rules
+#
+$(PCUT_LIB): $(PCUT_OBJECTS)
+	$(AR) rc $@ $(PCUT_OBJECTS)
+	$(RANLIB) $@
+
+%.o: $(DEPEND)
+
+#
+# Installation
+#
+install: $(PCUT_LIB)
+	install -d -m 755 $(DESTDIR)$(LIBDIR)
+	install -d -m 755 $(DESTDIR)$(INCLUDEDIR)/pcut
+	install -m 644 $(PCUT_LIB) $(DESTDIR)$(LIBDIR)/$(PCUT_LIB)
+	install -m 644 include/pcut/*.h $(DESTDIR)$(INCLUDEDIR)/pcut/
Index: uspace/lib/pcut/update-from-master.sh
===================================================================
--- uspace/lib/pcut/update-from-master.sh	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/update-from-master.sh	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2014 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+run_echo() {
+	echo "[exec]:" "$@"
+	"$@"
+}
+
+RUN=run_echo
+
+
+# Because of the very first command we issue that deletes about everything
+if ! [ "$1" == "really-overwrite" ]; then
+	echo "Wrong argument, see sources!"
+	exit 1
+fi
+
+$RUN find -not -name update-from-master.sh -delete
+$RUN wget https://github.com/vhotspur/pcut/archive/master.zip -O pcut-master.zip
+$RUN unzip -u pcut-master.zip
+$RUN mv -f pcut-master/* .
+$RUN rm -rf pcut-master pcut-master.zip
+
+cat >Makefile <<'EOF_MAKEFILE'
+#
+# This file was generated by call to update-from-master.sh
+#
+
+USPACE_PREFIX = ../..
+
+include helenos.mak
+
+include $(USPACE_PREFIX)/Makefile.common
+
+EOF_MAKEFILE
Index: uspace/lib/pcut/windows.mak
===================================================================
--- uspace/lib/pcut/windows.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
+++ uspace/lib/pcut/windows.mak	(revision 01579ad1020d073a91a73278666eb1fa947e04f5)
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+PCUT_TARGET_SOURCES = src/os/stdc.c src/os/generic.c
+OBJ_EXT = obj
+PCUT_LIB = pcut.lib
+
+-include pcut.mak
+
+#
+# Add the check target for running all the tests
+#
+TEST_BASE = tests/
+EXE_EXT = exe
+TEST_CFLAGS = $(PCUT_CFLAGS)
+TEST_LDFLAGS = -L. -lpcut
+-include tests/tests.mak
+
+#
+# Clean-up
+#
+platform-clean:
+
+#
+# Actual build rules
+#
+$(PCUT_LIB): $(PCUT_OBJECTS)
+
