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);
}
|