aboutsummaryrefslogtreecommitdiff
path: root/lib/unicode/prop/uprop_get_lc.c
blob: 84d82407700c0da1ed1bb6d70ad5b1f5f76ce223 (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
#include "macros.h"
#include "unicode/prop.h"

struct rview
uprop_get_lc(rune ch, struct lcctx ctx)
{
	constexpr rune COMB_GRAVE = 0x300;
	constexpr rune COMB_ACUTE = 0x301;
	constexpr rune COMB_TILDE = 0x303;
	constexpr rune COMB_DOT_ABOVE = 0x307;
	static thread_local rune hack[3];

	if (ch == U'Σ') {
		hack[0] = ctx.final_sigma ? U'ς' : U'σ';
		return (struct rview){hack, 1};
	}
	if (ch == U'İ') {
		hack[0] = 'i';
		hack[1] = COMB_DOT_ABOVE;
		return (struct rview){hack, ctx.az_or_tr ? 1 : 2};
	}

	if (ctx.lt) {
		if (ctx.more_above) {
			switch (ch) {
			case 'I':
				hack[0] = 'i';
				hack[1] = COMB_DOT_ABOVE;
				return (struct rview){hack, 2};
			case 'J':
				hack[0] = 'j';
				hack[1] = COMB_DOT_ABOVE;
				return (struct rview){hack, 2};
			case U'Į':
				hack[0] = U'į';
				hack[1] = COMB_DOT_ABOVE;
				return (struct rview){hack, 2};
			}
		}

		switch (ch) {
		case U'Ì':
		case U'Í':
		case U'Ĩ':
			hack[0] = 'i';
			hack[1] = COMB_DOT_ABOVE;

			/* TODO: Use ternary when GCC stops being bad */
			if (ch == U'Ì')
				hack[2] = COMB_GRAVE;
			else if (ch == U'Í')
				hack[2] = COMB_ACUTE;
			else
				hack[2] = COMB_TILDE;

			return (struct rview){hack, 3};
		}
	}

	if (ctx.az_or_tr) {
		if (ch == COMB_DOT_ABOVE && ctx.after_I)
			return (struct rview){};
		if (ch == 'I' && !ctx.before_dot) {
			hack[0] = U'ı';
			return (struct rview){hack, 1};
		}
	}

	hack[0] = uprop_get_slc(ch);
	return (struct rview){hack, 1};
}