libgrapheme

Freestanding C library for unicode string handling
git clone https://git.sinitax.com/suckless/libgrapheme
Log | Files | Refs | README | LICENSE | sfeed.txt

util.c (3049B)


      1/* See LICENSE file for copyright and license details. */
      2#include <stdbool.h>
      3#include <stddef.h>
      4#include <stdint.h>
      5#include <stdio.h>
      6#include <string.h>
      7
      8#include "../gen/types.h"
      9#include "../grapheme.h"
     10#include "util.h"
     11
     12int
     13run_break_tests(size_t (*next_break)(const uint_least32_t *, size_t),
     14                const struct break_test *test, size_t testlen,
     15                const char *argv0)
     16{
     17	size_t i, j, off, res, failed;
     18
     19	/* character break test */
     20	for (i = 0, failed = 0; i < testlen; i++) {
     21		for (j = 0, off = 0; off < test[i].cplen; off += res) {
     22			res = next_break(test[i].cp + off, test[i].cplen - off);
     23
     24			/* check if our resulting offset matches */
     25			if (j == test[i].lenlen || res != test[i].len[j++]) {
     26				fprintf(stderr,
     27				        "%s: Failed conformance test %zu "
     28				        "\"%s\".\n",
     29				        argv0, i, test[i].descr);
     30				fprintf(stderr,
     31				        "J=%zu: EXPECTED len %zu, got %zu\n",
     32				        j - 1, test[i].len[j - 1], res);
     33				failed++;
     34				break;
     35			}
     36		}
     37	}
     38	printf("%s: %zu/%zu conformance tests passed.\n", argv0,
     39	       testlen - failed, testlen);
     40
     41	return (failed > 0) ? 1 : 0;
     42}
     43
     44int
     45run_unit_tests(int (*unit_test_callback)(const void *, size_t, const char *,
     46                                         const char *),
     47               const void *test, size_t testlen, const char *name,
     48               const char *argv0)
     49{
     50	size_t i, failed;
     51
     52	for (i = 0, failed = 0; i < testlen; i++) {
     53		failed +=
     54			(unit_test_callback(test, i, name, argv0) == 0) ? 0 : 1;
     55	}
     56
     57	printf("%s: %s: %zu/%zu unit tests passed.\n", argv0, name,
     58	       testlen - failed, testlen);
     59
     60	return (failed > 0) ? 1 : 0;
     61}
     62
     63int
     64unit_test_callback_next_break(const struct unit_test_next_break *t, size_t off,
     65                              size_t (*next_break)(const uint_least32_t *,
     66                                                   size_t),
     67                              const char *name, const char *argv0)
     68{
     69	const struct unit_test_next_break *test = t + off;
     70
     71	size_t ret = next_break(test->input.src, test->input.srclen);
     72
     73	if (ret != test->output.ret) {
     74		goto err;
     75	}
     76
     77	return 0;
     78err:
     79	fprintf(stderr,
     80	        "%s: %s: Failed unit test %zu \"%s\" "
     81	        "(returned %zu instead of %zu).\n",
     82	        argv0, name, off, test->description, ret, test->output.ret);
     83	return 1;
     84}
     85
     86int
     87unit_test_callback_next_break_utf8(const struct unit_test_next_break_utf8 *t,
     88                                   size_t off,
     89                                   size_t (*next_break_utf8)(const char *,
     90                                                             size_t),
     91                                   const char *name, const char *argv0)
     92{
     93	const struct unit_test_next_break_utf8 *test = t + off;
     94
     95	size_t ret = next_break_utf8(test->input.src, test->input.srclen);
     96
     97	if (ret != test->output.ret) {
     98		goto err;
     99	}
    100
    101	return 0;
    102err:
    103	fprintf(stderr,
    104	        "%s: %s: Failed unit test %zu \"%s\" "
    105	        "(returned %zu instead of %zu).\n",
    106	        argv0, name, off, test->description, ret, test->output.ret);
    107	return 1;
    108}