]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/locale/tools/convert_map.pl
Update nvi to 2.2.0
[FreeBSD/FreeBSD.git] / tools / tools / locale / tools / convert_map.pl
1 #! /usr/local/bin/perl
2 #
3 # $FreeBSD$
4 #
5 # This file and its contents are supplied under the terms of the
6 # Common Development and Distribution License ("CDDL"), version 1.0.
7 # You may only use this file in accordance with the terms of version
8 # 1.0 of the CDDL.
9 #
10 # A full copy of the text of the CDDL should have accompanied this
11 # source.  A copy is of the CDDL is also available via the Internet
12 # at http://www.illumos.org/license/CDDL.
13 #
14
15 #
16 # Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
17 # Copyright 2015 John Marino <draco@marino.st>
18 #
19
20 # This converts MAPPING files to localedef character maps
21 # suitable for use with the UTF-8 derived localedef data.
22
23 sub ucs_to_utf8
24 {
25     my $ucs = shift;
26     my $utf8;
27
28     if ($ucs <= 0x7f) {
29         $utf8 = sprintf("\\x%02X", $ucs).$utf8;
30     } elsif ($ucs <= 0x7ff) {
31         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
32         $ucs >>= 6;
33         $utf8 = sprintf("\\x%02X", $ucs | 0xc0).$utf8;
34
35     } elsif ($ucs <= 0xffff) {
36         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
37         $ucs >>= 6;
38         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
39         $ucs >>= 6;
40         $utf8 = sprintf("\\x%02X", $ucs | 0xe0).$utf8;
41
42     } elsif ($ucs <= 0x1fffff) {
43         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
44         $ucs >>= 6;
45         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
46         $ucs >>= 6;
47         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
48         $ucs >>= 6;
49         $utf8 = sprintf("\\x%02X", $ucs | 0xf0).$utf8;
50
51     } elsif ($ucs <= 0x03ffffff) {
52         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
53         $ucs >>= 6;
54         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
55         $ucs >>= 6;
56         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
57         $ucs >>= 6;
58         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
59         $ucs >>= 6;
60         $utf8 = sprintf("\\x%02X", $ucs | 0xf8).$utf8;
61
62     } else {
63         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
64         $ucs >>= 6;
65         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
66         $ucs >>= 6;
67         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
68         $ucs >>= 6;
69         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
70         $ucs >>= 6;
71         $utf8 = sprintf("\\x%02X", ($ucs & 0x3f) | 0x80).$utf8;
72         $ucs >>= 6;
73         $utf8 = sprintf("\\x%02X", $ucs | 0xf8).$utf8;
74     }
75
76     return ($utf8);
77 }
78
79 my %unames;
80 my %uvalues;
81
82 #
83 # This is not a general purpose Character Map parser, but its good enough
84 # for the stock one supplied with CLDR.
85 #
86 sub load_utf8_cm
87 {
88     my $file = shift;
89
90     open(UTF8, "$file") || die "$!: open: $file";
91
92     while (<UTF8>) {
93         next if (/^#/);
94         next if (/^\s*$/);
95         next if (/^\s*CHARMAP\s*$/);
96         next if (/^\s*END\s*CHARMAP\s*$/);
97         chomp;
98         @words = split /\s+/;
99         $name = $words[0];
100         $utf8val = $words[1];
101
102         if (defined($unames{$utf8val})) {
103             $unames{$utf8val} .= "\n" .$name;
104         } else {
105             $unames{$utf8val} = $name;
106         }
107         $uvalues{$name} = $utf8val;
108     }
109     close(UTF8);
110 }
111
112 my %map;
113
114 sub load_map
115 {
116     my $file = shift;
117
118     open(MAP, "$file") || die "open";
119
120     while (<MAP>) {
121         next if (/^#/);
122         next if (/^\s*$/);
123         next if (/^0x..\+0x../);
124         next if (/^0x[0-9A-F]{4}\t0x[0-9A-F]{4} 0x[0-9A-F]{4}/);
125         next if (/^0x[0-9A-F]{2}\s+#/);
126         next if (/# ... NO MAPPING .../);
127         chomp;
128         @words = split /\s+/;
129         $utf8 = $words[1];
130         $utf8 =~ s/^\\x[0]*//;
131         $utf8 = ucs_to_utf8(hex($utf8));
132         $val = $words[0];
133         if (defined ($map{$val})) {
134             $map{$val} .= " ".$utf8;
135         } else {
136             $map{$val} = $utf8;
137         }
138     }
139 }
140
141 sub mb_str
142 {
143     my $val = shift;
144     my $str = "";
145     $val = hex($val);
146
147     if ($val == 0) {
148         return ("\\x00");
149     }
150     while ($val) {
151         $str = sprintf("\\x%02x", $val & 0xff).$str;
152         $val >>= 8;
153     }
154     return ($str);
155 }
156
157 $mf = shift(@ARGV);
158 $codeset = shift(@ARGV);
159 my $max_mb;
160
161 my $etcdir = (exists $ENV{'ETCDIR'}) ? $ENV{'ETCDIR'} : "etc";
162 load_utf8_cm("${etcdir}/final-maps/map.UTF-8");
163 load_map($mf);
164
165
166    if ($codeset eq "SJIS")      { $max_mb = 2 }
167 elsif ($codeset eq "eucCN")     { $max_mb = 2 }
168 elsif ($codeset eq "eucJP")     { $max_mb = 3 }
169 elsif ($codeset eq "eucKR")     { $max_mb = 2 }
170 elsif ($codeset eq "GBK")       { $max_mb = 2 }
171 elsif ($codeset eq "GB2312")    { $max_mb = 2 }
172 elsif ($codeset eq "Big5")      { $max_mb = 2 }
173 else { $max_mb = 1 };
174 print("<code_set_name> \"$codeset\"\n");
175 print("<mb_cur_min> 1\n");
176 print("<mb_cur_max> $max_mb\n");
177
178 print("CHARMAP\n");
179 foreach $val (sort (keys (%map))) {
180     #$utf8 = $map{$val};
181     foreach $utf8 (split / /, $map{$val}) {
182         $ref = $unames{$utf8};
183         foreach $name (sort (split /\n/, $ref)) {
184             print "$name";
185             my $nt = int((64 - length($name) + 7) / 8);
186             while ($nt) {
187                 print "\t";
188                 $nt--;
189             }
190             print mb_str($val)."\n";
191         }
192     }
193 }
194 print "END CHARMAP\n";