This source file includes following definitions.
- is_using_utf8
- using_simple_locale
- init_localeinfo
- case_folded_counterparts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include <localeinfo.h>
25
26 #include <verify.h>
27
28 #include <limits.h>
29 #include <locale.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <wctype.h>
33
34
35 verify (MB_LEN_MAX <= SCHAR_MAX);
36
37
38
39 static bool
40 is_using_utf8 (void)
41 {
42 wchar_t wc;
43 mbstate_t mbs = {0};
44 return mbrtowc (&wc, "\xc4\x80", 2, &mbs) == 2 && wc == 0x100;
45 }
46
47
48
49
50
51 static bool
52 using_simple_locale (bool multibyte)
53 {
54
55
56
57
58 enum { native_c_charset =
59 ('\b' == 8 && '\t' == 9 && '\n' == 10 && '\v' == 11 && '\f' == 12
60 && '\r' == 13 && ' ' == 32 && '!' == 33 && '"' == 34 && '#' == 35
61 && '%' == 37 && '&' == 38 && '\'' == 39 && '(' == 40 && ')' == 41
62 && '*' == 42 && '+' == 43 && ',' == 44 && '-' == 45 && '.' == 46
63 && '/' == 47 && '0' == 48 && '9' == 57 && ':' == 58 && ';' == 59
64 && '<' == 60 && '=' == 61 && '>' == 62 && '?' == 63 && 'A' == 65
65 && 'Z' == 90 && '[' == 91 && '\\' == 92 && ']' == 93 && '^' == 94
66 && '_' == 95 && 'a' == 97 && 'z' == 122 && '{' == 123 && '|' == 124
67 && '}' == 125 && '~' == 126)
68 };
69
70 if (!native_c_charset || multibyte)
71 return false;
72
73
74
75
76
77
78
79 for (int i = 0; i < UCHAR_MAX; i++)
80 if (0 <= strcoll (((char []) {i, 0}), ((char []) {i + 1, 0})))
81 return false;
82
83 return true;
84 }
85
86
87
88 void
89 init_localeinfo (struct localeinfo *localeinfo)
90 {
91 localeinfo->multibyte = MB_CUR_MAX > 1;
92 localeinfo->simple = using_simple_locale (localeinfo->multibyte);
93 localeinfo->using_utf8 = is_using_utf8 ();
94
95 for (int i = CHAR_MIN; i <= CHAR_MAX; i++)
96 {
97 char c = i;
98 unsigned char uc = i;
99 mbstate_t s = {0};
100 wchar_t wc;
101 size_t len = mbrtowc (&wc, &c, 1, &s);
102 localeinfo->sbclen[uc] = len <= 1 ? 1 : - (int) - len;
103 localeinfo->sbctowc[uc] = len <= 1 ? wc : WEOF;
104 }
105 }
106
107
108
109
110
111
112 static short const lonesome_lower[] =
113 {
114 0x00B5, 0x0131, 0x017F, 0x01C5, 0x01C8, 0x01CB, 0x01F2, 0x0345,
115 0x03C2, 0x03D0, 0x03D1, 0x03D5, 0x03D6, 0x03F0, 0x03F1,
116
117
118
119 0x03F2,
120
121 0x03F5, 0x1E9B, 0x1FBE,
122 };
123
124
125
126 verify (1 + 1 + sizeof lonesome_lower / sizeof *lonesome_lower
127 <= CASE_FOLDED_BUFSIZE);
128
129
130
131
132
133 int
134 case_folded_counterparts (wint_t c, wchar_t folded[CASE_FOLDED_BUFSIZE])
135 {
136 int i;
137 int n = 0;
138 wint_t uc = towupper (c);
139 wint_t lc = towlower (uc);
140 if (uc != c)
141 folded[n++] = uc;
142 if (lc != uc && lc != c && towupper (lc) == uc)
143 folded[n++] = lc;
144 for (i = 0; i < sizeof lonesome_lower / sizeof *lonesome_lower; i++)
145 {
146 wint_t li = lonesome_lower[i];
147 if (li != lc && li != uc && li != c && towupper (li) == uc)
148 folded[n++] = li;
149 }
150 return n;
151 }