Index: uspace/app/df/df.c
===================================================================
--- uspace/app/df/df.c	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/app/df/df.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -70,5 +70,5 @@
 
 	/* Parse command-line options */
-	while ((optres = getopt(argc, argv, ":ubh")) != -1) {
+	while ((optres = getopt(argc, argv, "ubh")) != -1) {
 		switch (optres) {
 		case 'h':
@@ -78,10 +78,4 @@
 		case 'b':
 			display_blocks = true;
-			break;
-
-		case ':':
-			fprintf(stderr, "Option -%c requires an operand\n",
-			    optopt);
-			errflg++;
 			break;
 
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/lib/c/Makefile	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -190,20 +190,27 @@
 TEST_SOURCES = \
 	test/adt/circ_buf.c \
+	test/adt/odict.c \
+	test/cap.c \
 	test/casting.c \
+	test/double_to_str.c \
 	test/fibril/timer.c \
+	test/getopt.c \
+	test/gsort.c \
+	test/ieee_double.c \
+	test/imath.c \
+	test/inttypes.c \
+	test/io/table.c \
 	test/main.c \
 	test/mem.c \
-	test/inttypes.c \
-	test/io/table.c \
-	test/stdio/scanf.c \
-	test/odict.c \
 	test/perf.c \
 	test/perm.c \
 	test/qsort.c \
 	test/sprintf.c \
+	test/stdio/scanf.c \
 	test/stdio.c \
 	test/stdlib.c \
 	test/str.c \
-	test/string.c
+	test/string.c \
+	test/uuid.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/c/generic/gsort.c
===================================================================
--- uspace/lib/c/generic/gsort.c	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/lib/c/generic/gsort.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -33,8 +33,7 @@
 /**
  * @file
- * @brief Sorting functions.
+ * @brief Gnome Sort.
  *
- * This files contains functions implementing several sorting
- * algorithms (e.g. quick sort and gnome sort).
+ * This file contains an implementation of gnome sort
  *
  */
Index: uspace/lib/c/generic/imath.c
===================================================================
--- uspace/lib/c/generic/imath.c	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/lib/c/generic/imath.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -50,5 +50,5 @@
 errno_t ipow10_u64(unsigned exp, uint64_t *res)
 {
-	unsigned a;
+	uint64_t a;
 	uint64_t r;
 
Index: uspace/lib/c/generic/uuid.c
===================================================================
--- uspace/lib/c/generic/uuid.c	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/lib/c/generic/uuid.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -39,4 +39,5 @@
 #include <stddef.h>
 #include <str.h>
+#include <stdio.h>
 
 /** Generate UUID.
@@ -67,5 +68,4 @@
 	uuid->b[8] = (uuid->b[8] & 0x3f) | 0x80;
 
-	return EOK;
 error:
 	rndgen_destroy(rndgen);
@@ -139,5 +139,5 @@
 
 	rc = str_uint64_t(str + 24, &eptr, 16, false, &node);
-	if (rc != EOK || eptr != str + 36 || *eptr != '\0')
+	if (rc != EOK || eptr != str + 36)
 		return EINVAL;
 
@@ -176,7 +176,22 @@
  * @return EOK on success, ENOMEM if out of memory
  */
-errno_t uuid_format(uuid_t *uuid, char **rstr)
+errno_t uuid_format(uuid_t *uuid, char **rstr, bool uppercase)
 {
-	return ENOTSUP;
+	size_t size = 37;
+	char *str = malloc(sizeof(char) * size);
+	if (str == NULL)
+		return ENOMEM;
+
+	const char *format = "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x";
+	if (uppercase)
+		format = "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X";
+
+	int ret = snprintf(str, size, format, uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], uuid->b[15]);
+
+	if (ret != 36)
+		return EINVAL;
+
+	*rstr = str;
+	return EOK;
 }
 
Index: uspace/lib/c/include/uuid.h
===================================================================
--- uspace/lib/c/include/uuid.h	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/lib/c/include/uuid.h	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -38,4 +38,5 @@
 #include <stdint.h>
 #include <types/uuid.h>
+#include <stdbool.h>
 
 extern errno_t uuid_generate(uuid_t *);
@@ -43,5 +44,5 @@
 extern void uuid_decode(uint8_t *, uuid_t *);
 extern errno_t uuid_parse(const char *, uuid_t *, const char **);
-extern errno_t uuid_format(uuid_t *, char **);
+extern errno_t uuid_format(uuid_t *, char **, bool);
 
 #endif
Index: uspace/lib/c/test/adt/odict.c
===================================================================
--- uspace/lib/c/test/adt/odict.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/adt/odict.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2016 Jiri Svoboda
+ * 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 <adt/odict.h>
+#include <pcut/pcut.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Test entry */
+typedef struct {
+	odlink_t odict;
+	int key;
+} test_entry_t;
+
+enum {
+	/** Length of test number sequences */
+	test_seq_len = 100
+};
+
+/** Test get key function.
+ *
+ * @param odlink Ordered dictionary link
+ * @return Pointer to key
+ */
+static void *test_getkey(odlink_t *odlink)
+{
+	return &odict_get_instance(odlink, test_entry_t, odict)->key;
+}
+
+/** Test compare function.
+ *
+ * @param a First key
+ * @param b Second key
+ * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
+ */
+static int test_cmp(void *a, void *b)
+{
+	int *ia = (int *)a;
+	int *ib = (int *)b;
+
+	return *ia - *ib;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(odict);
+
+/** Increasing sequence test.
+ *
+ * Test initialization, emptiness, insertion of increasing sequence and walking.
+ */
+PCUT_TEST(incr_seq)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = i;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_next(c, &odict);
+		++i;
+	}
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	i = test_seq_len;
+	c = odict_last(&odict);
+	while (c != NULL) {
+		--i;
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_prev(c, &odict);
+	}
+
+	PCUT_ASSERT_INT_EQUALS(0, i);
+}
+
+/** Decreasing sequence test.
+ *
+ * Test initialization, emptiness, insertion of decreasing sequence and walking.
+ */
+PCUT_TEST(decr_seq)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = test_seq_len - i - 1;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_next(c, &odict);
+		++i;
+	}
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	i = test_seq_len;
+	c = odict_last(&odict);
+	while (c != NULL) {
+		--i;
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_prev(c, &odict);
+	}
+
+	PCUT_ASSERT_INT_EQUALS(0, i);
+}
+
+/** Increasing sequence insertion and removal test.
+ *
+ * Test sequential insertion of increasing sequence and sequential removal.
+ */
+PCUT_TEST(incr_seq_ins_rem)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = i;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+
+		odict_remove(c);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+
+		c = odict_first(&odict);
+		++i;
+	}
+
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+}
+
+/** Generate pseudorandom sequence. */
+static int seq_next(int cur)
+{
+	return (cur * 1951) % 1000000;
+}
+
+/** Test 4.
+ *
+ * Test inserting a pseudorandom sequence and then extracting it again.
+ */
+PCUT_TEST(prseq_ins_extract)
+{
+	odict_t odict;
+	test_entry_t *e, *ep;
+	odlink_t *c, *d;
+	int prev;
+	int i;
+	int v;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	v = 1;
+	ep = NULL;
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = v;
+		odict_insert(&e->odict, &odict, &ep->odict);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+		v = seq_next(v);
+		ep = e;
+	}
+
+	/* Verify that entries are in ascending order */
+	c = odict_first(&odict);
+	prev = -1;
+	i = 0;
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_EQUALS(true, e->key > prev);
+
+		prev = e->key;
+		c = odict_next(c, &odict);
+		++i;
+	}
+
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	/* Try extracting the sequence */
+	v = 1;
+	for (i = 0; i < test_seq_len; i++) {
+		c = odict_find_eq(&odict, (void *)&v, NULL);
+		PCUT_ASSERT_NOT_NULL(c);
+
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(v, e->key);
+
+		d = odict_find_eq_last(&odict, (void *)&v, NULL);
+		PCUT_ASSERT_NOT_NULL(d);
+
+		e = odict_get_instance(d, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(v, e->key);
+
+		odict_remove(c);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+
+		v = seq_next(v);
+	}
+}
+
+PCUT_EXPORT(odict);
Index: uspace/lib/c/test/cap.c
===================================================================
--- uspace/lib/c/test/cap.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/cap.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <cap.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(cap);
+
+PCUT_TEST(cap_format)
+{
+	int block_size = 4;
+	size_t block[] = {
+		0,
+		1,
+		2,
+		10,
+	};
+
+	int input_size = 5;
+	size_t input[] = {
+		0,
+		10,
+		100,
+		1000,
+		1000000,
+		1000000000,
+	};
+
+	const char *out[] = {
+		"0 B",
+		"0 B",
+		"0 B",
+		"0 B",
+
+		"0 B",
+		"10 B",
+		"20 B",
+		"100 B",
+
+		"0 B",
+		"100 B",
+		"200 B",
+		"1.000 kB",
+
+		"0 B",
+		"1.000 kB",
+		"2.000 kB",
+		"10.00 kB",
+
+		"0 B",
+		"1.000 MB",
+		"2.000 MB",
+		"10.00 MB",
+
+		"0 B",
+		"1.000 GB",
+		"2.000 GB",
+		"10.00 GB",
+	};
+
+	cap_spec_t cap;
+	char *str;
+	errno_t rc;
+
+	int x, i;
+	for (i = 0; i < input_size; i++) {
+		for (x = 0; x < block_size; x++) {
+			cap_from_blocks(input[i], block[x], &cap);
+			cap_simplify(&cap);
+
+			rc = cap_format(&cap, &str);
+
+			PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+			PCUT_ASSERT_STR_EQUALS(out[x + (block_size * i)], str);
+			free(str);
+
+			cap_from_blocks(block[x], input[i], &cap);
+			cap_simplify(&cap);
+
+			rc = cap_format(&cap, &str);
+
+			PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+			PCUT_ASSERT_STR_EQUALS(out[x + (block_size * i)], str);
+			free(str);
+		}
+	}
+}
+
+PCUT_TEST(cap_format_rounding)
+{
+	int input_size = 8;
+	uint64_t input[] = {
+		555,
+		5555,
+		55555,
+		555555555,
+		5555555555,
+		555999999,
+		5999999,
+		999999
+	};
+
+	const char *out[] = {
+		"555 B",
+		"5.555 kB",
+		"55.56 kB",
+		"555.6 MB",
+		"5.556 GB",
+		"556.0 MB",
+		"6.000 MB",
+		"1.000 MB",
+	};
+
+	cap_spec_t cap;
+	char *str;
+	errno_t rc;
+
+	int i;
+	for (i = 0; i < input_size; i++) {
+		cap_from_blocks(input[i], 1, &cap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &str);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_STR_EQUALS(out[i], str);
+		free(str);
+
+		cap_from_blocks(1, input[i], &cap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &str);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_STR_EQUALS(out[i], str);
+		free(str);
+	}
+}
+
+PCUT_TEST(cap_parse)
+{
+	int input_size = 4;
+	const char *input[] = {
+		"0 B",
+		"100 B",
+		"1 kB",
+		"1.555 kB",
+	};
+
+	int out_cunit[] = {
+		cu_byte,
+		cu_byte,
+		cu_kbyte,
+		cu_kbyte,
+	};
+
+	int out_dp[] = {
+		0,
+		0,
+		0,
+		3,
+	};
+
+	int out_m[] = {
+		0,
+		100,
+		1,
+		1555,
+	};
+
+	cap_spec_t cap;
+	errno_t rc;
+	int i;
+
+	for (i = 0; i < input_size; i++) {
+		rc = cap_parse(input[i], &cap);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_cunit[i], cap.cunit);
+		PCUT_ASSERT_INT_EQUALS(out_dp[i], cap.dp);
+		PCUT_ASSERT_INT_EQUALS(out_m[i], cap.m);
+	}
+}
+
+PCUT_TEST(cap_to_blocks)
+{
+	int input_size = 0;
+	int input_m[] = {
+		0,
+		1,
+		1000,
+		5555,
+		7777,
+	};
+
+	int input_dp[] = {
+		0,
+		0,
+		3,
+		3,
+		2,
+	};
+
+	int block[] = {
+		1,
+		1,
+		1,
+		2,
+		3,
+	};
+
+	int out_nom[] = {
+		0,
+		1000,
+		1000,
+		2778,
+		25923,
+	};
+
+	int out_min[] = {
+		0,
+		1000,
+		1000,
+		2777,
+		25923,
+	};
+
+	int out_max[] = {
+		0,
+		1000,
+		1000,
+		2778,
+		25924,
+	};
+
+	cap_spec_t cap;
+	errno_t rc;
+	int i;
+	uint64_t ret;
+
+	for (i = 0; i < input_size; i++) {
+		cap.m = input_m[i];
+		cap.dp = input_dp[i];
+		cap.cunit = cu_kbyte;
+
+		rc = cap_to_blocks(&cap, cv_nom, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_nom[i], ret);
+
+		rc = cap_to_blocks(&cap, cv_min, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_min[i], ret);
+
+		rc = cap_to_blocks(&cap, cv_max, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_max[i], ret);
+	}
+}
+
+PCUT_EXPORT(cap);
Index: uspace/lib/c/test/double_to_str.c
===================================================================
--- uspace/lib/c/test/double_to_str.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/double_to_str.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <ieee_double.h>
+#include <double_to_str.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(double_to_str);
+
+PCUT_TEST(double_to_short_str_pos_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(0.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_short_str_neg_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-0.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_short_str_pos_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_short_str_neg_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-1.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_short_str_small)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.1);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(2, ret);
+	PCUT_ASSERT_INT_EQUALS(-1, dec);
+	PCUT_ASSERT_STR_EQUALS("11", buf);
+}
+
+PCUT_TEST(double_to_short_str_large)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1234.56789);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(9, ret);
+	PCUT_ASSERT_INT_EQUALS(-5, dec);
+	PCUT_ASSERT_STR_EQUALS("123456789", buf);
+}
+
+PCUT_TEST(double_to_short_str_mill)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1000000.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(6, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(0.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_pos_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1000", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_neg_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-1.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1000", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_small)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.1);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1100", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_large)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1234.56789);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(7, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1234567", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_nodecimals)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.999);
+	int ret = double_to_fixed_str(d, -1, 0, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_EXPORT(double_to_str);
Index: uspace/lib/c/test/getopt.c
===================================================================
--- uspace/lib/c/test/getopt.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/getopt.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <getopt.h>
+#include <stdio.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(getopt);
+
+PCUT_TEST(getopt_param_flag)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"-p",
+		"param",
+	};
+
+	const char *options = "fp:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_concat_flags)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-fda",
+	};
+
+	const char *options = "afd";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('d', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('a', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_concat_flag_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"-fp",
+		"param"
+	};
+
+	const char *options = "fp:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_missing_param1)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = "p:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_missing_param2)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = ":p:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(':', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_illegal_option)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = "a";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+
+	options = ":a";
+	optreset = 1;
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_flag_with_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"param",
+		"-d"
+	};
+
+	const char *options = "fd";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	/* getopt() would print a error message but thx to opterror=0 it doesnt */
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('d', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_case_sensitive)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"-F",
+		"-f"
+	};
+
+	const char *options = "fF";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('F', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_optional_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"-p",
+		"param"
+	};
+
+	const char *options = "f::p::";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_NULL(optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_special_option)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"--",
+		"-p"
+	};
+
+	const char *options = "fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_gnu_plus)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"break",
+		"-p"
+	};
+
+	const char *options = "+fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_gnu_minus)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"break",
+		"-p"
+	};
+
+	const char *options = "-fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("break", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_flag_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag",
+		"--parameter",
+		"param"
+	};
+
+	const char *options = "fp:";
+
+	const struct option long_options[] = {
+		{ "flag", no_argument, NULL, 'f' },
+		{ "parameter", required_argument, NULL, 'p' },
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_alt_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag=\"param param\"",
+		"--parameter=param",
+	};
+
+	const char *options = "f:p:";
+
+	const struct option long_options[] = {
+		{ "flag", required_argument, NULL, 'f' },
+		{ "parameter", required_argument, NULL, 'p' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_STR_EQUALS("\"param param\"", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_optional_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag=param",
+		"--parameter",
+	};
+
+	const char *options = "f::p::";
+
+	const struct option long_options[] = {
+		{ "flag", optional_argument, NULL, 'f' },
+		{ "parameter", optional_argument, NULL, 'p' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_NULL(optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_illegal_option)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--param",
+		"param",
+	};
+
+	const char *options = "f::";
+
+	const struct option long_options[] = {
+		{ "cflag", required_argument, NULL, 'c' },
+		{ "flag", required_argument, NULL, 'f' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_INT_EQUALS(0, optopt);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_ambiguous_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag",
+		"param",
+	};
+
+	const char *options = "f::";
+
+	const struct option long_options[] = {
+		{ "flag1", optional_argument, NULL, 'f' },
+		{ "flag2", required_argument, NULL, 'f' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_INT_EQUALS(0, optopt);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_EXPORT(getopt);
Index: uspace/lib/c/test/gsort.c
===================================================================
--- uspace/lib/c/test/gsort.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/gsort.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <gsort.h>
+
+static int cmp_func(void *a, void *b, void *param)
+{
+	int ia = *(int *)a;
+	int ib = *(int *)b;
+
+	if (ia == ib)
+		return 0;
+
+	return ia < ib ? -1 : 1;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(gsort);
+
+/* sort ascending */
+PCUT_TEST(gsort_asc)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = i;
+	}
+
+	bool ret = gsort(data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	for (int i = 0; i < size; i++) {
+		PCUT_ASSERT_INT_EQUALS(i, data[i]);
+	}
+}
+
+/* sort ascending including double entries of the same number */
+PCUT_TEST(gsort_asc_complex)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = (i * 13) % 9;
+	}
+
+	data[0] = 2;
+	data[1] = 0;
+	data[2] = 4;
+	data[3] = 1;
+
+	bool ret = gsort(data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	int prev = data[0];
+	for (int i = 1; i < size; i++) {
+		PCUT_ASSERT_TRUE(prev <= data[i]);
+		prev = data[i];
+	}
+}
+
+/* sort descanding */
+PCUT_TEST(gsort_desc)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = size - i;
+	}
+
+	bool ret = gsort(&data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	for (int i = 0; i < size; i++) {
+		PCUT_ASSERT_INT_EQUALS(i + 1, data[i]);
+	}
+}
+
+PCUT_EXPORT(gsort);
Index: uspace/lib/c/test/ieee_double.c
===================================================================
--- uspace/lib/c/test/ieee_double.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/ieee_double.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <ieee_double.h>
+
+union {
+	uint64_t integer;
+	double floating;
+} ieee_double_bits;
+
+const int EXP_BIAS = 1023;
+const int EXP_BIAS_UNDERFLOWED = 1075;
+const int SIGN_SHIFT = 52;
+const uint64_t HIDDEN_BIT = 1ULL << SIGN_SHIFT;
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(ieee_double);
+
+PCUT_TEST(extract_ieee_sizeof_double)
+{
+	PCUT_ASSERT_INT_EQUALS(8, sizeof(double));
+}
+
+PCUT_TEST(extract_ieee_double_pos_infinity)
+{
+	ieee_double_bits.integer = 0x7FF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_TRUE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_neg_infinity)
+{
+	ieee_double_bits.integer = 0xFFF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_TRUE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_nan)
+{
+	ieee_double_bits.integer = 0xFFFFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_TRUE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_pos_zero)
+{
+	ieee_double_bits.integer = 0x0000000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+}
+
+PCUT_TEST(extract_ieee_double_neg_zero)
+{
+	ieee_double_bits.integer = 0x8000000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_one)
+{
+	ieee_double_bits.integer = 0x3FF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_TRUE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(EXP_BIAS - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_one)
+{
+	ieee_double_bits.integer = 0xBFF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_TRUE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(EXP_BIAS - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_pos_smallest)
+{
+	ieee_double_bits.integer = 0x0000000000000001ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(1, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_neg_smallest)
+{
+	ieee_double_bits.integer = 0x8000000000000001ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(1, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_pos_largest)
+{
+	ieee_double_bits.integer = 0x000FFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_neg_largest)
+{
+	ieee_double_bits.integer = 0x800FFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_smallest)
+{
+	ieee_double_bits.integer = 0x0010000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_smallest)
+{
+	ieee_double_bits.integer = 0x8010000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_largest)
+{
+	ieee_double_bits.integer = 0x7FEFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL + HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0x7FEULL - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_largest)
+{
+	ieee_double_bits.integer = 0xFFEFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL + HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0x7FEULL - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_EXPORT(ieee_double);
Index: uspace/lib/c/test/imath.c
===================================================================
--- uspace/lib/c/test/imath.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/imath.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <imath.h>
+
+static uint64_t MAX_NUM = 10000000000000000000U;
+static unsigned MAX_EXP = 19;
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(imath);
+
+PCUT_TEST(ipow10_u64_zero)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(0, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(1, result);
+}
+
+PCUT_TEST(ipow10_u64_one)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(1, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(10, result);
+}
+
+PCUT_TEST(ipow10_u64_max)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(MAX_EXP, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(MAX_NUM, result);
+}
+
+PCUT_TEST(ipow10_u64_too_large)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(MAX_EXP + 1, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(ERANGE, ret);
+}
+
+PCUT_TEST(ilog10_u64_zero)
+{
+	unsigned ret = ilog10_u64(0);
+	PCUT_ASSERT_INT_EQUALS(0, ret);
+}
+
+PCUT_TEST(ilog10_u64_one)
+{
+	unsigned ret = ilog10_u64(1);
+	PCUT_ASSERT_INT_EQUALS(0, ret);
+}
+
+PCUT_TEST(ilog10_u64_max)
+{
+	unsigned ret = ilog10_u64(MAX_NUM);
+	PCUT_ASSERT_INT_EQUALS(MAX_EXP, ret);
+}
+
+PCUT_EXPORT(imath);
Index: uspace/lib/c/test/main.c
===================================================================
--- uspace/lib/c/test/main.c	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ uspace/lib/c/test/main.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -32,7 +32,13 @@
 PCUT_INIT;
 
+PCUT_IMPORT(cap);
 PCUT_IMPORT(casting);
 PCUT_IMPORT(circ_buf);
+PCUT_IMPORT(double_to_str);
 PCUT_IMPORT(fibril_timer);
+PCUT_IMPORT(getopt);
+PCUT_IMPORT(gsort);
+PCUT_IMPORT(ieee_double);
+PCUT_IMPORT(imath);
 PCUT_IMPORT(inttypes);
 PCUT_IMPORT(mem);
@@ -48,4 +54,5 @@
 PCUT_IMPORT(string);
 PCUT_IMPORT(table);
+PCUT_IMPORT(uuid);
 
 PCUT_MAIN();
Index: pace/lib/c/test/odict.c
===================================================================
--- uspace/lib/c/test/odict.c	(revision 098e16a542a995bd6a49397ae5c774a6dc91a3d1)
+++ 	(revision )
@@ -1,278 +1,0 @@
-/*
- * Copyright (c) 2016 Jiri Svoboda
- * 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 <adt/odict.h>
-#include <pcut/pcut.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/** Test entry */
-typedef struct {
-	odlink_t odict;
-	int key;
-} test_entry_t;
-
-enum {
-	/** Length of test number sequences */
-	test_seq_len = 100
-};
-
-/** Test get key function.
- *
- * @param odlink Ordered dictionary link
- * @return Pointer to key
- */
-static void *test_getkey(odlink_t *odlink)
-{
-	return &odict_get_instance(odlink, test_entry_t, odict)->key;
-}
-
-/** Test compare function.
- *
- * @param a First key
- * @param b Second key
- * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
- */
-static int test_cmp(void *a, void *b)
-{
-	int *ia = (int *)a;
-	int *ib = (int *)b;
-
-	return *ia - *ib;
-}
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(odict);
-
-/** Increasing sequence test.
- *
- * Test initialization, emptiness, insertion of increasing sequence and walking.
- */
-PCUT_TEST(incr_seq)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = i;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_next(c, &odict);
-		++i;
-	}
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	i = test_seq_len;
-	c = odict_last(&odict);
-	while (c != NULL) {
-		--i;
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_prev(c, &odict);
-	}
-
-	PCUT_ASSERT_INT_EQUALS(0, i);
-}
-
-/** Decreasing sequence test.
- *
- * Test initialization, emptiness, insertion of decreasing sequence and walking.
- */
-PCUT_TEST(decr_seq)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = test_seq_len - i - 1;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_next(c, &odict);
-		++i;
-	}
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	i = test_seq_len;
-	c = odict_last(&odict);
-	while (c != NULL) {
-		--i;
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_prev(c, &odict);
-	}
-
-	PCUT_ASSERT_INT_EQUALS(0, i);
-}
-
-/** Increasing sequence insertion and removal test.
- *
- * Test sequential insertion of increasing sequence and sequential removal.
- */
-PCUT_TEST(incr_seq_ins_rem)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = i;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-
-		odict_remove(c);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-
-		c = odict_first(&odict);
-		++i;
-	}
-
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-}
-
-/** Generate pseudorandom sequence. */
-static int seq_next(int cur)
-{
-	return (cur * 1951) % 1000000;
-}
-
-/** Test 4.
- *
- * Test inserting a pseudorandom sequence and then extracting it again.
- */
-PCUT_TEST(prseq_ins_extract)
-{
-	odict_t odict;
-	test_entry_t *e, *ep;
-	odlink_t *c, *d;
-	int prev;
-	int i;
-	int v;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	v = 1;
-	ep = NULL;
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = v;
-		odict_insert(&e->odict, &odict, &ep->odict);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-		v = seq_next(v);
-		ep = e;
-	}
-
-	/* Verify that entries are in ascending order */
-	c = odict_first(&odict);
-	prev = -1;
-	i = 0;
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_EQUALS(true, e->key > prev);
-
-		prev = e->key;
-		c = odict_next(c, &odict);
-		++i;
-	}
-
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	/* Try extracting the sequence */
-	v = 1;
-	for (i = 0; i < test_seq_len; i++) {
-		c = odict_find_eq(&odict, (void *)&v, NULL);
-		PCUT_ASSERT_NOT_NULL(c);
-
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(v, e->key);
-
-		d = odict_find_eq_last(&odict, (void *)&v, NULL);
-		PCUT_ASSERT_NOT_NULL(d);
-
-		e = odict_get_instance(d, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(v, e->key);
-
-		odict_remove(c);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-
-		v = seq_next(v);
-	}
-}
-
-PCUT_EXPORT(odict);
Index: uspace/lib/c/test/uuid.c
===================================================================
--- uspace/lib/c/test/uuid.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
+++ uspace/lib/c/test/uuid.c	(revision bc417660cbc159aeca9329f4da387c9038dc80bc)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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/pcut.h>
+#include <uuid.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <str.h>
+#include <ctype.h>
+
+static size_t MAX_SUB_TESTS = 10;
+static size_t uuids_len = 6;
+static const char *uuids[] = {
+	/* uppercase */
+	"F81163AE-299A-4DA2-BED1-0E096C59F3AB",
+	"4A0CE2A3-FD1C-4951-972E-AAA13A703078",
+	"69C7DB62-8309-4C58-831B-8C4E4161E8AC",
+
+	/* lower case*/
+	"c511bf24-70cb-422e-933b-2a74ab699a56",
+	"7b1abd05-456f-4661-ab62-917685069343",
+	"5b00f76b-4a16-4dce-a1fc-b78c60324d89"
+};
+
+static bool uuid_valid(uuid_t uuid)
+{
+	if (!(uuid.b[6] & 0x40)) {
+		return false;
+	}
+
+	int f = (uuid.b[8] & 0x80) || (uuid.b[8] & 0x90);
+	f = f || (uuid.b[8] & 0xA0) || (uuid.b[8] & 0xB0);
+	if (!f) {
+		return false;
+	}
+
+	return true;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(uuid);
+
+PCUT_TEST(uuid_generate)
+{
+	uuid_t uuid;
+	size_t i;
+
+	for (i = 0; i < MAX_SUB_TESTS; i++) {
+		errno_t ret = uuid_generate(&uuid);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	}
+}
+
+PCUT_TEST(uuid_parse)
+{
+	uuid_t uuid;
+	errno_t ret;
+
+	for (size_t i = 0; i < uuids_len; i++) {
+		ret = uuid_parse(uuids[i], &uuid, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	}
+}
+
+PCUT_TEST(uuid_parse_in_text)
+{
+	uuid_t uuid;
+	errno_t ret;
+	const char *endptr;
+	const char *uuid_in_text = "7b1abd05-456f-4661-ab62-917685069343hello world!";
+
+	ret = uuid_parse(uuid_in_text, &uuid, &endptr);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	PCUT_ASSERT_STR_EQUALS("hello world!", endptr);
+}
+
+PCUT_TEST(uuid_format_generated)
+{
+	uuid_t uuid;
+	size_t i;
+	char *rstr;
+
+	for (i = 0; i < MAX_SUB_TESTS; i++) {
+		errno_t ret = uuid_generate(&uuid);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+
+		ret = uuid_format(&uuid, &rstr, true);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_INT_EQUALS('\0', rstr[37]);
+		PCUT_ASSERT_INT_EQUALS(36, str_length(rstr));
+		PCUT_ASSERT_INT_EQUALS('4', rstr[14]);
+
+		int f = rstr[19] == '8' || rstr[19] == '9';
+		f = f || toupper(rstr[19]) == 'A' || toupper(rstr[19]) == 'B';
+		PCUT_ASSERT_TRUE(f);
+
+		free(rstr);
+	}
+}
+
+PCUT_TEST(uuid_format_parsed)
+{
+	uuid_t uuid;
+	char *rstr;
+	errno_t ret;
+
+	for (size_t i = 0; i < uuids_len; i++) {
+		ret = uuid_parse(uuids[i], &uuid, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+
+		ret = uuid_format(&uuid, &rstr, true);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_INT_EQUALS('\0', rstr[37]);
+		PCUT_ASSERT_INT_EQUALS(36, str_length(rstr));
+		PCUT_ASSERT_INT_EQUALS(0, str_casecmp(uuids[i], rstr));
+
+		free(rstr);
+	}
+}
+
+PCUT_EXPORT(uuid);
