aboutsummaryrefslogtreecommitdiff
path: root/vendor/librune/test/gbrk.c
blob: ad32fdd349d3b9fcb1a0f3551cc0f708e06bae6b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#define _POSIX_C_SOURCE 200809L
#include <err.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

#include <gbrk.h>
#include <rune.h>
#include <utf8.h>

#define die(...) err(EXIT_FAILURE, __VA_ARGS__)

static void test(char *);

int
main(int argc, char **argv)
{
	char *line = NULL;
	size_t n;
	ssize_t nr;
	FILE *fp;

	setlocale(LC_ALL, "");

	if (argc != 2) {
		fprintf(stderr, "%s: file\n", *argv);
		exit(EXIT_FAILURE);
	}

	if (!(fp = fopen(argv[1], "r")))
		die("fopen");

	while ((nr = getline(&line, &n, fp)) > 0) {
		line[nr - 1] = 0;
		test(line);
	}

	if (nr == -1 && ferror(fp))
		die("getline");

	fclose(fp);
	free(line);
	return EXIT_SUCCESS;
}

void
test(char *raw)
{
	int n;
	rune ch;
	char8_t *p, *buf;
	const char8_t *s;
	size_t bufsiz = 4096;
	struct grapheme graph;

	if (!(buf = malloc(bufsiz)))
		die("malloc");

	p = buf;
	while (sscanf(raw, "%" SCNxRUNE "%n", &ch, &n)) {
		rune sep;
		p += rtou8(p, ch, bufsiz - (p - buf));
		raw += n;
		raw += u8tor(&sep, (char8_t *)raw);
		if (!sep)
			break;
	}
	*p = 0;

	s = buf;
	while (u8gnext(&graph, &s, &bufsiz) && *graph.p) {
		rune ch;
		const char8_t *p;

		while (u8next(&ch, &graph.p, &graph.len) && ch) {
			printf("%04" PRIXRUNE "%s", ch, graph.len > 0 ? "×" : "");
			p = graph.p;
		}
		if (bufsiz && *p)
			fputs("÷", stdout);
	}

	putchar('\n');
	free(buf);
}