SDL
321 строка · 9.7 Кб
1#!/usr/bin/perl -w
2
3# Simple DirectMedia Layer
4# Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
5#
6# This software is provided 'as-is', without any express or implied
7# warranty. In no event will the authors be held liable for any damages
8# arising from the use of this software.
9#
10# Permission is granted to anyone to use this software for any purpose,
11# including commercial applications, and to alter it and redistribute it
12# freely, subject to the following restrictions:
13#
14# 1. The origin of this software must not be misrepresented; you must not
15# claim that you wrote the original software. If you use this software
16# in a product, an acknowledgment in the product documentation would be
17# appreciated but is not required.
18# 2. Altered source versions must be plainly marked as such, and must not be
19# misrepresented as being the original software.
20# 3. This notice may not be removed or altered from any source distribution.
21
22# This script was originally written by Ryan C. Gordon for PhysicsFS
23# ( https://icculus.org/physfs/ ), under the zlib license: the same license
24# that SDL itself uses).
25
26use warnings;
27use strict;
28
29my $HASHBUCKETS1_16 = 256;
30my $HASHBUCKETS1_32 = 16;
31my $HASHBUCKETS2_16 = 16;
32my $HASHBUCKETS3_16 = 4;
33
34my $mem_used = 0;
35
36print <<__EOF__;
37/*
38Simple DirectMedia Layer
39Copyright (C) 1997-2024 Sam Lantinga <slouken\@libsdl.org>
40
41This software is provided 'as-is', without any express or implied
42warranty. In no event will the authors be held liable for any damages
43arising from the use of this software.
44
45Permission is granted to anyone to use this software for any purpose,
46including commercial applications, and to alter it and redistribute it
47freely, subject to the following restrictions:
48
491. The origin of this software must not be misrepresented; you must not
50claim that you wrote the original software. If you use this software
51in a product, an acknowledgment in the product documentation would be
52appreciated but is not required.
532. Altered source versions must be plainly marked as such, and must not be
54misrepresented as being the original software.
553. This notice may not be removed or altered from any source distribution.
56*/
57
58/*
59* This data was generated by SDL/build-scripts/makecasefoldhashtable.pl
60*
61* Do not manually edit this file!
62*/
63
64#ifndef SDL_casefolding_h_
65#define SDL_casefolding_h_
66
67/* We build three simple hashmaps here: one that maps Unicode codepoints to
68a one, two, or three lowercase codepoints. To retrieve this info: look at
69case_fold_hashX, where X is 1, 2, or 3. Most foldable codepoints fold to one,
70a few dozen fold to two, and a handful fold to three. If the codepoint isn't
71in any of these hashes, it doesn't fold (no separate upper and lowercase).
72
73Almost all these codepoints fit into 16 bits, so we hash them as such to save
74memory. If a codepoint is > 0xFFFF, we have separate hashes for them,
75since there are (currently) only about 120 of them and (currently) all of them
76map to a single lowercase codepoint. */
77
78typedef struct CaseFoldMapping1_32
79{
80Uint32 from;
81Uint32 to0;
82} CaseFoldMapping1_32;
83
84typedef struct CaseFoldMapping1_16
85{
86Uint16 from;
87Uint16 to0;
88} CaseFoldMapping1_16;
89
90typedef struct CaseFoldMapping2_16
91{
92Uint16 from;
93Uint16 to0;
94Uint16 to1;
95} CaseFoldMapping2_16;
96
97typedef struct CaseFoldMapping3_16
98{
99Uint16 from;
100Uint16 to0;
101Uint16 to1;
102Uint16 to2;
103} CaseFoldMapping3_16;
104
105typedef struct CaseFoldHashBucket1_16
106{
107const CaseFoldMapping1_16 *list;
108const Uint8 count;
109} CaseFoldHashBucket1_16;
110
111typedef struct CaseFoldHashBucket1_32
112{
113const CaseFoldMapping1_32 *list;
114const Uint8 count;
115} CaseFoldHashBucket1_32;
116
117typedef struct CaseFoldHashBucket2_16
118{
119const CaseFoldMapping2_16 *list;
120const Uint8 count;
121} CaseFoldHashBucket2_16;
122
123typedef struct CaseFoldHashBucket3_16
124{
125const CaseFoldMapping3_16 *list;
126const Uint8 count;
127} CaseFoldHashBucket3_16;
128
129__EOF__
130
131
132my @foldPairs1_16;
133my @foldPairs2_16;
134my @foldPairs3_16;
135my @foldPairs1_32;
136
137for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) {
138$foldPairs1_16[$i] = '';
139}
140
141for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) {
142$foldPairs1_32[$i] = '';
143}
144
145for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) {
146$foldPairs2_16[$i] = '';
147}
148
149for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) {
150$foldPairs3_16[$i] = '';
151}
152
153open(FH,'<','casefolding.txt') or die("failed to open casefolding.txt: $!\n");
154while (<FH>) {
155chomp;
156# strip comments from textfile...
157s/\#.*\Z//;
158
159# strip whitespace...
160s/\A\s+//;
161s/\s+\Z//;
162
163next if not /\A([a-fA-F0-9]+)\;\s*(.)\;\s*(.+)\;/;
164my ($code, $status, $mapping) = ($1, $2, $3);
165
166my $hexxed = hex($code);
167#print("// code '$code' status '$status' mapping '$mapping'\n");
168
169if (($status eq 'C') or ($status eq 'F')) {
170my ($map1, $map2, $map3) = (undef, undef, undef);
171$map1 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
172$map2 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
173$map3 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
174die("mapping space too small for '$code'\n") if ($mapping ne '');
175die("problem parsing mapping for '$code'\n") if (not defined($map1));
176
177if ($hexxed < 128) {
178# Just ignore these, we'll handle the low-ASCII ones ourselves.
179} elsif ($hexxed > 0xFFFF) {
180# We just need to add the 32-bit 2 and/or 3 codepoint maps if this die()'s here.
181die("Uhoh, a codepoint > 0xFFFF that folds to multiple codepoints! Fixme.") if defined($map2);
182my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS1_32-1));
183#print("// hexxed '$hexxed' hashed1 '$hashed'\n");
184$foldPairs1_32[$hashed] .= " { 0x$code, 0x$map1 },\n";
185$mem_used += 8;
186} elsif (not defined($map2)) {
187my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS1_16-1));
188#print("// hexxed '$hexxed' hashed1 '$hashed'\n");
189$foldPairs1_16[$hashed] .= " { 0x$code, 0x$map1 },\n";
190$mem_used += 4;
191} elsif (not defined($map3)) {
192my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS2_16-1));
193#print("// hexxed '$hexxed' hashed2 '$hashed'\n");
194$foldPairs2_16[$hashed] .= " { 0x$code, 0x$map1, 0x$map2 },\n";
195$mem_used += 6;
196} else {
197my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS3_16-1));
198#print("// hexxed '$hexxed' hashed3 '$hashed'\n");
199$foldPairs3_16[$hashed] .= " { 0x$code, 0x$map1, 0x$map2, 0x$map3 },\n";
200$mem_used += 8;
201}
202}
203}
204close(FH);
205
206for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) {
207$foldPairs1_16[$i] =~ s/,\n\Z//;
208my $str = $foldPairs1_16[$i];
209next if $str eq '';
210my $num = '000' . $i;
211$num =~ s/\A.*?(\d\d\d)\Z/$1/;
212my $sym = "case_fold1_16_${num}";
213print("static const CaseFoldMapping1_16 ${sym}[] = {\n$str\n};\n\n");
214}
215
216for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) {
217$foldPairs1_32[$i] =~ s/,\n\Z//;
218my $str = $foldPairs1_32[$i];
219next if $str eq '';
220my $num = '000' . $i;
221$num =~ s/\A.*?(\d\d\d)\Z/$1/;
222my $sym = "case_fold1_32_${num}";
223print("static const CaseFoldMapping1_32 ${sym}[] = {\n$str\n};\n\n");
224}
225
226for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) {
227$foldPairs2_16[$i] =~ s/,\n\Z//;
228my $str = $foldPairs2_16[$i];
229next if $str eq '';
230my $num = '000' . $i;
231$num =~ s/\A.*?(\d\d\d)\Z/$1/;
232my $sym = "case_fold2_16_${num}";
233print("static const CaseFoldMapping2_16 ${sym}[] = {\n$str\n};\n\n");
234}
235
236for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) {
237$foldPairs3_16[$i] =~ s/,\n\Z//;
238my $str = $foldPairs3_16[$i];
239next if $str eq '';
240my $num = '000' . $i;
241$num =~ s/\A.*?(\d\d\d)\Z/$1/;
242my $sym = "case_fold3_16_${num}";
243print("static const CaseFoldMapping3_16 ${sym}[] = {\n$str\n};\n\n");
244}
245
246print("static const CaseFoldHashBucket1_16 case_fold_hash1_16[] = {\n");
247
248for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) {
249my $str = $foldPairs1_16[$i];
250if ($str eq '') {
251print(" { NULL, 0 },\n");
252} else {
253my $num = '000' . $i;
254$num =~ s/\A.*?(\d\d\d)\Z/$1/;
255my $sym = "case_fold1_16_${num}";
256print(" { $sym, SDL_arraysize($sym) },\n");
257}
258$mem_used += 12;
259}
260print("};\n\n");
261
262
263print("static const CaseFoldHashBucket1_32 case_fold_hash1_32[] = {\n");
264
265for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) {
266my $str = $foldPairs1_32[$i];
267if ($str eq '') {
268print(" { NULL, 0 },\n");
269} else {
270my $num = '000' . $i;
271$num =~ s/\A.*?(\d\d\d)\Z/$1/;
272my $sym = "case_fold1_32_${num}";
273print(" { $sym, SDL_arraysize($sym) },\n");
274}
275$mem_used += 12;
276}
277print("};\n\n");
278
279
280print("static const CaseFoldHashBucket2_16 case_fold_hash2_16[] = {\n");
281
282for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) {
283my $str = $foldPairs2_16[$i];
284if ($str eq '') {
285print(" { NULL, 0 },\n");
286} else {
287my $num = '000' . $i;
288$num =~ s/\A.*?(\d\d\d)\Z/$1/;
289my $sym = "case_fold2_16_${num}";
290print(" { $sym, SDL_arraysize($sym) },\n");
291}
292$mem_used += 12;
293}
294print("};\n\n");
295
296print("static const CaseFoldHashBucket3_16 case_fold_hash3_16[] = {\n");
297
298for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) {
299my $str = $foldPairs3_16[$i];
300if ($str eq '') {
301print(" { NULL, 0 },\n");
302} else {
303my $num = '000' . $i;
304$num =~ s/\A.*?(\d\d\d)\Z/$1/;
305my $sym = "case_fold3_16_${num}";
306print(" { $sym, SDL_arraysize($sym) },\n");
307}
308$mem_used += 12;
309}
310print("};\n\n");
311
312print <<__EOF__;
313#endif /* SDL_casefolding_h_ */
314
315__EOF__
316
317print STDERR "Memory required for case-folding hashtable: $mem_used bytes\n";
318
319exit 0;
320
321# end of makecashfoldhashtable.pl ...
322
323