Include libcharset into both the Timber and Halibut checkouts.
[sgt/charset] / sbcsgen.pl
1 #!/usr/bin/env perl -w
2
3 # This script generates sbcsdat.c (the data for all the SBCSes) from its
4 # source form sbcs.dat.
5
6 $infile = "sbcs.dat";
7 $infile = shift @ARGV if defined $ARGV[0];
8 $outfile = "sbcsdat.c";
9 $outfile = shift @ARGV if defined $ARGV[0];
10
11 open FOO, $infile;
12 open BAR, ">$outfile";
13 select BAR;
14
15 print "/*\n";
16 print " * sbcsdat.c - data definitions for single-byte character sets.\n";
17 print " *\n";
18 print " * Generated by sbcsgen.pl from sbcs.dat.\n";
19 print " * You should edit those files rather than editing this one.\n";
20 print " */\n";
21 print "\n";
22 print "#ifndef ENUM_CHARSETS\n";
23 print "\n";
24 print "#include \"charset.h\"\n";
25 print "#include \"internal.h\"\n";
26 print "\n";
27
28 my $charsetname = undef;
29 my @vals = ();
30
31 my @charsetnames = ();
32 my @sortpriority = ();
33
34 while (<FOO>) {
35 chomp;
36 if (/^charset (.*)$/) {
37 $charsetname = $1;
38 @vals = ();
39 @sortpriority = map { 0 } 0..255;
40 } elsif (/^sortpriority ([^-]*)-([^-]*) (.*)$/) {
41 for ($i = hex $1; $i <= hex $2; $i++) {
42 $sortpriority[$i] += $3;
43 }
44 } elsif (/^[0-9a-fA-FX]/) {
45 push @vals, map { $_ eq "XXXX" ? -1 : hex $_ } split / +/, $_;
46 if (scalar @vals > 256) {
47 die "$infile:$.: charset $charsetname has more than 256 values\n";
48 } elsif (scalar @vals == 256) {
49 &outcharset($charsetname, \@vals, \@sortpriority);
50 push @charsetnames, $charsetname;
51 $charsetname = undef;
52 @vals = ();
53 @sortpriority = map { 0 } 0..255;
54 }
55 }
56 }
57
58 print "#else /* ENUM_CHARSETS */\n";
59 print "\n";
60
61 foreach $i (@charsetnames) {
62 print "ENUM_CHARSET($i)\n";
63 }
64
65 print "\n";
66 print "#endif /* ENUM_CHARSETS */\n";
67
68 sub outcharset($$$) {
69 my ($name, $vals, $sortpriority) = @_;
70 my ($prefix, $i, @sorted);
71
72 print "static const sbcs_data data_$name = {\n";
73 print " {\n";
74 $prefix = " ";
75 @sorted = ();
76 for ($i = 0; $i < 256; $i++) {
77 if ($vals->[$i] < 0) {
78 printf "%sERROR ", $prefix;
79 } else {
80 printf "%s0x%04x", $prefix, $vals->[$i];
81 die "ooh? $i\n" unless defined $sortpriority->[$i];
82 push @sorted, [$i, $vals->[$i], 0+$sortpriority->[$i]];
83 }
84 if ($i % 8 == 7) {
85 $prefix = ",\n ";
86 } else {
87 $prefix = ", ";
88 }
89 }
90 print "\n },\n {\n";
91 @sorted = sort { $a->[1] == $b->[1] ?
92 $b->[2] <=> $a->[2] :
93 $a->[1] <=> $b->[1] } @sorted;
94 $prefix = " ";
95 $uval = -1;
96 for ($i = $j = 0; $i < scalar @sorted; $i++) {
97 next if ($uval == $sorted[$i]->[1]); # low-priority alternative
98 $uval = $sorted[$i]->[1];
99 printf "%s0x%02x", $prefix, $sorted[$i]->[0];
100 if ($j % 8 == 7) {
101 $prefix = ",\n ";
102 } else {
103 $prefix = ", ";
104 }
105 $j++;
106 }
107 printf "\n },\n %d\n", $j;
108 print "};\n";
109 print "const charset_spec charset_$name = {\n" .
110 " $name, read_sbcs, write_sbcs, &data_$name\n};\n\n";
111 }