libgrapheme

unicode string library
git clone git://git.suckless.org/libgrapheme
Log | Files | Refs | README | LICENSE

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 
     12 int
     13 run_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 
     44 int
     45 run_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 
     63 int
     64 unit_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;
     78 err:
     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 
     86 int
     87 unit_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;
    102 err:
    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 }