73 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
	
		
			1.6 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/perl
 | 
						|
#
 | 
						|
#  Generate Expansion Table of Compatibility Ligatures
 | 
						|
#  (c) 2003 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
 | 
						|
#
 | 
						|
 | 
						|
use strict;
 | 
						|
use warnings;
 | 
						|
 | 
						|
print STDERR "Reading ligature list\n";
 | 
						|
open(L, "misc/u-ligatures") || die "lig file open";
 | 
						|
my %ligs = ();
 | 
						|
while (<L>) {
 | 
						|
	chomp;
 | 
						|
	$ligs{$_} = 1;
 | 
						|
}
 | 
						|
close L;
 | 
						|
 | 
						|
print STDERR "Reading decompositions\n";
 | 
						|
open(I, "unidata/UnicodeData.txt") || die "Unable to open UniCode data file";
 | 
						|
my %decs = ();
 | 
						|
while (<I>) {
 | 
						|
	chomp;
 | 
						|
	(/^$/ || /^#/) && next;
 | 
						|
	my ($code,$name,$cat,$comb,$bidir,$decomp,$d0,$d1,$n0,$mirr,$cmt1,$cmt2,$upper,$lower,$title) = split /;/;
 | 
						|
	$code =~ /^....$/ || next;
 | 
						|
	if (my ($d) = ($decomp =~ /^<compat> (.*)/)) {
 | 
						|
		$decs{$code} = $d;
 | 
						|
	}
 | 
						|
}
 | 
						|
close I;
 | 
						|
 | 
						|
sub expand($) {
 | 
						|
	my ($c) = @_;
 | 
						|
	if (defined $decs{$c}) {
 | 
						|
		return join (" ", map { expand($_) } split(/\s+/, $decs{$c}));
 | 
						|
	} else {
 | 
						|
		return $c;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
print STDERR "Searching for a perfect hash function\n";
 | 
						|
my $n = keys %ligs;
 | 
						|
my $div = $n-1;
 | 
						|
DIV: while (++$div) {
 | 
						|
	#print STDERR "Trying $div... ";
 | 
						|
	my @c = ();
 | 
						|
	foreach my $l (keys %ligs) {
 | 
						|
		my $i = (hex $l) % $div;
 | 
						|
		if (defined $c[$i]) {
 | 
						|
			#print STDERR "collision\n";
 | 
						|
			next DIV;
 | 
						|
		}
 | 
						|
		$c[$i] = 1;
 | 
						|
	}
 | 
						|
	#print STDERR "FOUND\n";
 | 
						|
	last;
 | 
						|
}
 | 
						|
 | 
						|
print STDERR "Filling hash table with $div entries for $n ligatures\n";
 | 
						|
my @ht = map { "NULL" } 1..$div;
 | 
						|
foreach my $l (keys %ligs) {
 | 
						|
	my $i = (hex $l) % $div;
 | 
						|
	my $w = join(", ", map { "0x$_" } split(/ /, expand($l)));
 | 
						|
	$ht[$i] = "/* $l */ (const u16 []) { $w, 0 }";
 | 
						|
}
 | 
						|
 | 
						|
print "#define LIG_HASH_SIZE $div\n\n";
 | 
						|
print "static const u16 *_U_lig_hash[] = {\n";
 | 
						|
for (my $i=0; $i<$div; $i++) {
 | 
						|
	print "\t", $ht[$i], ",\n";
 | 
						|
}
 | 
						|
print "};\n";
 |