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