Simple Directmedia Layer
at main 10 kB view raw
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/* 38 Simple DirectMedia Layer 39 Copyright (C) 1997-2024 Sam Lantinga <slouken\@libsdl.org> 40 41 This software is provided 'as-is', without any express or implied 42 warranty. In no event will the authors be held liable for any damages 43 arising from the use of this software. 44 45 Permission is granted to anyone to use this software for any purpose, 46 including commercial applications, and to alter it and redistribute it 47 freely, subject to the following restrictions: 48 49 1. The origin of this software must not be misrepresented; you must not 50 claim that you wrote the original software. If you use this software 51 in a product, an acknowledgment in the product documentation would be 52 appreciated but is not required. 53 2. Altered source versions must be plainly marked as such, and must not be 54 misrepresented as being the original software. 55 3. 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{ 80 Uint32 from; 81 Uint32 to0; 82} CaseFoldMapping1_32; 83 84typedef struct CaseFoldMapping1_16 85{ 86 Uint16 from; 87 Uint16 to0; 88} CaseFoldMapping1_16; 89 90typedef struct CaseFoldMapping2_16 91{ 92 Uint16 from; 93 Uint16 to0; 94 Uint16 to1; 95} CaseFoldMapping2_16; 96 97typedef struct CaseFoldMapping3_16 98{ 99 Uint16 from; 100 Uint16 to0; 101 Uint16 to1; 102 Uint16 to2; 103} CaseFoldMapping3_16; 104 105typedef struct CaseFoldHashBucket1_16 106{ 107 const CaseFoldMapping1_16 *list; 108 const Uint8 count; 109} CaseFoldHashBucket1_16; 110 111typedef struct CaseFoldHashBucket1_32 112{ 113 const CaseFoldMapping1_32 *list; 114 const Uint8 count; 115} CaseFoldHashBucket1_32; 116 117typedef struct CaseFoldHashBucket2_16 118{ 119 const CaseFoldMapping2_16 *list; 120 const Uint8 count; 121} CaseFoldHashBucket2_16; 122 123typedef struct CaseFoldHashBucket3_16 124{ 125 const CaseFoldMapping3_16 *list; 126 const 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>) { 155 chomp; 156 # strip comments from textfile... 157 s/\#.*\Z//; 158 159 # strip whitespace... 160 s/\A\s+//; 161 s/\s+\Z//; 162 163 next if not /\A([a-fA-F0-9]+)\;\s*(.)\;\s*(.+)\;/; 164 my ($code, $status, $mapping) = ($1, $2, $3); 165 166 my $hexxed = hex($code); 167 #print("// code '$code' status '$status' mapping '$mapping'\n"); 168 169 if (($status eq 'C') or ($status eq 'F')) { 170 my ($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)//; 174 die("mapping space too small for '$code'\n") if ($mapping ne ''); 175 die("problem parsing mapping for '$code'\n") if (not defined($map1)); 176 177 if ($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. 181 die("Uhoh, a codepoint > 0xFFFF that folds to multiple codepoints! Fixme.") if defined($map2); 182 my $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)) { 187 my $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)) { 192 my $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 { 197 my $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//; 208 my $str = $foldPairs1_16[$i]; 209 next if $str eq ''; 210 my $num = '000' . $i; 211 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 212 my $sym = "case_fold1_16_${num}"; 213 print("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//; 218 my $str = $foldPairs1_32[$i]; 219 next if $str eq ''; 220 my $num = '000' . $i; 221 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 222 my $sym = "case_fold1_32_${num}"; 223 print("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//; 228 my $str = $foldPairs2_16[$i]; 229 next if $str eq ''; 230 my $num = '000' . $i; 231 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 232 my $sym = "case_fold2_16_${num}"; 233 print("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//; 238 my $str = $foldPairs3_16[$i]; 239 next if $str eq ''; 240 my $num = '000' . $i; 241 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 242 my $sym = "case_fold3_16_${num}"; 243 print("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++) { 249 my $str = $foldPairs1_16[$i]; 250 if ($str eq '') { 251 print(" { NULL, 0 },\n"); 252 } else { 253 my $num = '000' . $i; 254 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 255 my $sym = "case_fold1_16_${num}"; 256 print(" { $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++) { 266 my $str = $foldPairs1_32[$i]; 267 if ($str eq '') { 268 print(" { NULL, 0 },\n"); 269 } else { 270 my $num = '000' . $i; 271 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 272 my $sym = "case_fold1_32_${num}"; 273 print(" { $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++) { 283 my $str = $foldPairs2_16[$i]; 284 if ($str eq '') { 285 print(" { NULL, 0 },\n"); 286 } else { 287 my $num = '000' . $i; 288 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 289 my $sym = "case_fold2_16_${num}"; 290 print(" { $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++) { 299 my $str = $foldPairs3_16[$i]; 300 if ($str eq '') { 301 print(" { NULL, 0 },\n"); 302 } else { 303 my $num = '000' . $i; 304 $num =~ s/\A.*?(\d\d\d)\Z/$1/; 305 my $sym = "case_fold3_16_${num}"; 306 print(" { $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