1*b1cdbd2cSJim Jagielski#!/usr/bin/perl 2*b1cdbd2cSJim Jagielski#************************************************************** 3*b1cdbd2cSJim Jagielski# 4*b1cdbd2cSJim Jagielski# Licensed to the Apache Software Foundation (ASF) under one 5*b1cdbd2cSJim Jagielski# or more contributor license agreements. See the NOTICE file 6*b1cdbd2cSJim Jagielski# distributed with this work for additional information 7*b1cdbd2cSJim Jagielski# regarding copyright ownership. The ASF licenses this file 8*b1cdbd2cSJim Jagielski# to you under the Apache License, Version 2.0 (the 9*b1cdbd2cSJim Jagielski# "License"); you may not use this file except in compliance 10*b1cdbd2cSJim Jagielski# with the License. You may obtain a copy of the License at 11*b1cdbd2cSJim Jagielski# 12*b1cdbd2cSJim Jagielski# http://www.apache.org/licenses/LICENSE-2.0 13*b1cdbd2cSJim Jagielski# 14*b1cdbd2cSJim Jagielski# Unless required by applicable law or agreed to in writing, 15*b1cdbd2cSJim Jagielski# software distributed under the License is distributed on an 16*b1cdbd2cSJim Jagielski# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17*b1cdbd2cSJim Jagielski# KIND, either express or implied. See the License for the 18*b1cdbd2cSJim Jagielski# specific language governing permissions and limitations 19*b1cdbd2cSJim Jagielski# under the License. 20*b1cdbd2cSJim Jagielski# 21*b1cdbd2cSJim Jagielski#************************************************************** 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski 25*b1cdbd2cSJim Jagielski# The following files must be available in a ./input subdir: 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski# <http://oss.software.ibm.com/cvs/icu/~checkout~/charset/data/xml/ 28*b1cdbd2cSJim Jagielski# gb-18030-2000.xml?rev=1.4&content-type=text/plain>: 29*b1cdbd2cSJim Jagielski# "modified version="3" date="2001-02-21"" 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski$id = "Gb180302000"; 32*b1cdbd2cSJim Jagielski 33*b1cdbd2cSJim Jagielskisub printUtf32 34*b1cdbd2cSJim Jagielski{ 35*b1cdbd2cSJim Jagielski my $utf32 = $_[0]; 36*b1cdbd2cSJim Jagielski return sprintf("U+%04X", $utf32); 37*b1cdbd2cSJim Jagielski} 38*b1cdbd2cSJim Jagielski 39*b1cdbd2cSJim Jagielskisub printGb 40*b1cdbd2cSJim Jagielski{ 41*b1cdbd2cSJim Jagielski if (defined($_[2])) 42*b1cdbd2cSJim Jagielski { 43*b1cdbd2cSJim Jagielski return sprintf("%02X%02X%02X%02X", $_[0], $_[1], $_[2], $_[3]); 44*b1cdbd2cSJim Jagielski } 45*b1cdbd2cSJim Jagielski elsif (defined($_[1])) 46*b1cdbd2cSJim Jagielski { 47*b1cdbd2cSJim Jagielski return sprintf("%02X%02X", $_[0], $_[1]); 48*b1cdbd2cSJim Jagielski } 49*b1cdbd2cSJim Jagielski else 50*b1cdbd2cSJim Jagielski { 51*b1cdbd2cSJim Jagielski return sprintf("%02X", $_[0]); 52*b1cdbd2cSJim Jagielski } 53*b1cdbd2cSJim Jagielski} 54*b1cdbd2cSJim Jagielski 55*b1cdbd2cSJim Jagielski$gb_map_2_count = 0; 56*b1cdbd2cSJim Jagielski$gb_map_4_count = 0; 57*b1cdbd2cSJim Jagielski$gb_map_4_ranges = 0; 58*b1cdbd2cSJim Jagielski$gb_map_4_max = 0; 59*b1cdbd2cSJim Jagielski$uni_map_count = 0; 60*b1cdbd2cSJim Jagielski 61*b1cdbd2cSJim Jagielski$range_count = 0; 62*b1cdbd2cSJim Jagielski 63*b1cdbd2cSJim Jagielskiif (1) 64*b1cdbd2cSJim Jagielski{ 65*b1cdbd2cSJim Jagielski $filename = "gb-18030-2000.xml"; 66*b1cdbd2cSJim Jagielski open IN, ("input/" . $filename) or die "Cannot read " . $filename; 67*b1cdbd2cSJim Jagielski while (<IN>) 68*b1cdbd2cSJim Jagielski { 69*b1cdbd2cSJim Jagielski if (/^[ \t]*<a +u=\"([0-9A-F]+)\" +b=\"([0-7][0-9A-F])\"\/>$/) 70*b1cdbd2cSJim Jagielski { 71*b1cdbd2cSJim Jagielski $utf32 = oct("0x" . $1); 72*b1cdbd2cSJim Jagielski $gb1 = oct("0x" . $2); 73*b1cdbd2cSJim Jagielski ($utf32 == $gb1) 74*b1cdbd2cSJim Jagielski or die "Bad " . printUtf32($utf32) . " to " . printGb($gb1); 75*b1cdbd2cSJim Jagielski } 76*b1cdbd2cSJim Jagielski elsif (/^[ \t]*<a +u=\"([0-9A-F]+)\" +b=\"([89A-F][0-9A-F]) ([4-789A-F][0-9A-F])\"\/>$/) 77*b1cdbd2cSJim Jagielski { 78*b1cdbd2cSJim Jagielski $utf32 = oct("0x" . $1); 79*b1cdbd2cSJim Jagielski $gb1 = oct("0x" . $2); 80*b1cdbd2cSJim Jagielski $gb2 = oct("0x" . $3); 81*b1cdbd2cSJim Jagielski $gb_code = ($gb1 - 0x81) * 190 82*b1cdbd2cSJim Jagielski + ($gb2 <= 0x7E ? $gb2 - 0x40 : $gb2 - 0x80 + 63); 83*b1cdbd2cSJim Jagielski !defined($gb_map_2[$gb_code]) 84*b1cdbd2cSJim Jagielski or die "Redefined " . printGb($gb1, $gb2); 85*b1cdbd2cSJim Jagielski $gb_map_2[$gb_code] = $utf32; 86*b1cdbd2cSJim Jagielski ++$gb_map_2_count; 87*b1cdbd2cSJim Jagielski 88*b1cdbd2cSJim Jagielski !defined($uni_map[$utf32]) or die "Double Unicode mapping"; 89*b1cdbd2cSJim Jagielski $uni_map[$utf32] = $gb1 << 8 | $gb2; 90*b1cdbd2cSJim Jagielski ++$uni_map_count; 91*b1cdbd2cSJim Jagielski } 92*b1cdbd2cSJim Jagielski elsif (/^[ \t]*<a +u=\"([0-9A-F]+)\" +b=\"([89A-F][0-9A-F]) (3[0-9]) ([89A-F][0-9A-F]) (3[0-9])\"\/>$/) 93*b1cdbd2cSJim Jagielski { 94*b1cdbd2cSJim Jagielski $utf32 = oct("0x" . $1); 95*b1cdbd2cSJim Jagielski $gb1 = oct("0x" . $2); 96*b1cdbd2cSJim Jagielski $gb2 = oct("0x" . $3); 97*b1cdbd2cSJim Jagielski $gb3 = oct("0x" . $4); 98*b1cdbd2cSJim Jagielski $gb4 = oct("0x" . $5); 99*b1cdbd2cSJim Jagielski $gb_code = ($gb1 - 0x81) * 12600 100*b1cdbd2cSJim Jagielski + ($gb2 - 0x30) * 1260 101*b1cdbd2cSJim Jagielski + ($gb3 - 0x81) * 10 102*b1cdbd2cSJim Jagielski + ($gb4 - 0x30); 103*b1cdbd2cSJim Jagielski !defined($gb_map_4[$gb_code]) 104*b1cdbd2cSJim Jagielski or die "Redefined " . printGb($gb1, $gb2, $gb3, $gb4); 105*b1cdbd2cSJim Jagielski $gb_map_4[$gb_code] = $utf32; 106*b1cdbd2cSJim Jagielski ++$gb_map_4_count; 107*b1cdbd2cSJim Jagielski $gb_map_4_max = $gb_code if ($gb_code > $gb_map_4_max); 108*b1cdbd2cSJim Jagielski 109*b1cdbd2cSJim Jagielski !defined($uni_map[$utf32]) or die "Double Unicode mapping"; 110*b1cdbd2cSJim Jagielski $uni_map[$utf32] = $gb1 << 24 | $gb2 << 16 | $gb3 << 8 | $gb4; 111*b1cdbd2cSJim Jagielski ++$uni_map_count; 112*b1cdbd2cSJim Jagielski } 113*b1cdbd2cSJim Jagielski elsif (/<a /) 114*b1cdbd2cSJim Jagielski { 115*b1cdbd2cSJim Jagielski die "Bad format"; 116*b1cdbd2cSJim Jagielski } 117*b1cdbd2cSJim Jagielski elsif (/^[ \t]*<range +uFirst=\"([0-9A-F]+)\" +uLast=\"([0-9A-F]+)\" +bFirst=\"([89A-F][0-9A-F]) (3[0-9]) ([89A-F][0-9A-F]) (3[0-9])\" +bLast=\"([89A-F][0-9A-F]) (3[0-9]) ([89A-F][0-9A-F]) (3[0-9])\" +bMin=\"81 30 81 30\" +bMax=\"FE 39 FE 39\"\/>$/) 118*b1cdbd2cSJim Jagielski { 119*b1cdbd2cSJim Jagielski $utf32_first = oct("0x" . $1); 120*b1cdbd2cSJim Jagielski $utf32_last = oct("0x" . $2); 121*b1cdbd2cSJim Jagielski $gb1_first = oct("0x" . $3); 122*b1cdbd2cSJim Jagielski $gb2_first = oct("0x" . $4); 123*b1cdbd2cSJim Jagielski $gb3_first = oct("0x" . $5); 124*b1cdbd2cSJim Jagielski $gb4_first = oct("0x" . $6); 125*b1cdbd2cSJim Jagielski $gb1_last = oct("0x" . $7); 126*b1cdbd2cSJim Jagielski $gb2_last = oct("0x" . $8); 127*b1cdbd2cSJim Jagielski $gb3_last = oct("0x" . $9); 128*b1cdbd2cSJim Jagielski $gb4_last = oct("0x" . $10); 129*b1cdbd2cSJim Jagielski $linear_first 130*b1cdbd2cSJim Jagielski = ($gb1_first - 0x81) * 12600 131*b1cdbd2cSJim Jagielski + ($gb2_first - 0x30) * 1260 132*b1cdbd2cSJim Jagielski + ($gb3_first - 0x81) * 10 133*b1cdbd2cSJim Jagielski + ($gb4_first - 0x30); 134*b1cdbd2cSJim Jagielski $linear_last 135*b1cdbd2cSJim Jagielski = ($gb1_last - 0x81) * 12600 136*b1cdbd2cSJim Jagielski + ($gb2_last - 0x30) * 1260 137*b1cdbd2cSJim Jagielski + ($gb3_last - 0x81) * 10 138*b1cdbd2cSJim Jagielski + ($gb4_last - 0x30); 139*b1cdbd2cSJim Jagielski ($utf32_last - $utf32_first == $linear_last - $linear_first) 140*b1cdbd2cSJim Jagielski or die "Bad range"; 141*b1cdbd2cSJim Jagielski if ($linear_first != 189000 || $linear_last != 1237575) 142*b1cdbd2cSJim Jagielski { 143*b1cdbd2cSJim Jagielski $range_uni_first[$range_count] = $utf32_first; 144*b1cdbd2cSJim Jagielski $range_uni_last[$range_count] 145*b1cdbd2cSJim Jagielski = ($utf32_last == 0xD7FF ? 0xDFFF : $utf32_last); 146*b1cdbd2cSJim Jagielski $range_linear_first[$range_count] = $linear_first; 147*b1cdbd2cSJim Jagielski $range_linear_last[$range_count] = $linear_last; 148*b1cdbd2cSJim Jagielski ++$range_count; 149*b1cdbd2cSJim Jagielski $gb_map_4_ranges += $linear_last - $linear_first + 1; 150*b1cdbd2cSJim Jagielski $gb_map_4_max = $linear_last 151*b1cdbd2cSJim Jagielski if ($linear_last > $gb_map_4_max); 152*b1cdbd2cSJim Jagielski } 153*b1cdbd2cSJim Jagielski } 154*b1cdbd2cSJim Jagielski elsif (/<range /) 155*b1cdbd2cSJim Jagielski { 156*b1cdbd2cSJim Jagielski die "Bad format"; 157*b1cdbd2cSJim Jagielski } 158*b1cdbd2cSJim Jagielski } 159*b1cdbd2cSJim Jagielski close IN; 160*b1cdbd2cSJim Jagielski} 161*b1cdbd2cSJim Jagielski 162*b1cdbd2cSJim Jagielskiprint "gb_map_2_count = ", $gb_map_2_count, 163*b1cdbd2cSJim Jagielski ", gb_map_4_count = ", $gb_map_4_count, 164*b1cdbd2cSJim Jagielski ", gb_map_4_ranges = ", $gb_map_4_ranges, 165*b1cdbd2cSJim Jagielski ", gb_map_4_max = ", $gb_map_4_max, 166*b1cdbd2cSJim Jagielski ", uni_map_count = ", $uni_map_count, "\n"; 167*b1cdbd2cSJim Jagielski($gb_map_2_count == 23940) or die "Bad gb_map_2_count != 23940"; 168*b1cdbd2cSJim Jagielski($gb_map_4_max == $gb_map_4_count + $gb_map_4_ranges - 1) 169*b1cdbd2cSJim Jagielski or die "Bad gb_map_4_max != gb_map_4_count + gb_map_4_ranges"; 170*b1cdbd2cSJim Jagielski($uni_map_count + $gb_map_4_ranges == 0x10000 - (0xE000 - 0xD800) - 0x80) 171*b1cdbd2cSJim Jagielski or die "Bad uni_map_count"; 172*b1cdbd2cSJim Jagielski 173*b1cdbd2cSJim Jagielski$range_index = 0; 174*b1cdbd2cSJim Jagielski$gb_nonrangedataindex[$range_index] = $gb_map_2_count; 175*b1cdbd2cSJim Jagielskifor ($gb_code = 0; $gb_code < $gb_map_4_max; ++$gb_code) 176*b1cdbd2cSJim Jagielski{ 177*b1cdbd2cSJim Jagielski if (defined($gb_map_4[$gb_code])) 178*b1cdbd2cSJim Jagielski { 179*b1cdbd2cSJim Jagielski $gb_map_2[$gb_map_2_count++] = $gb_map_4[$gb_code]; 180*b1cdbd2cSJim Jagielski } 181*b1cdbd2cSJim Jagielski else 182*b1cdbd2cSJim Jagielski { 183*b1cdbd2cSJim Jagielski ($gb_code == $range_linear_first[$range_index]) or die "Bad input"; 184*b1cdbd2cSJim Jagielski $gb_code = $range_linear_last[$range_index]; 185*b1cdbd2cSJim Jagielski ++$range_index; 186*b1cdbd2cSJim Jagielski $gb_nonrangedataindex[$range_index] = $gb_map_2_count; 187*b1cdbd2cSJim Jagielski } 188*b1cdbd2cSJim Jagielski} 189*b1cdbd2cSJim Jagielski($range_index == $range_count) or die "Bad input"; 190*b1cdbd2cSJim Jagielski 191*b1cdbd2cSJim Jagielski$filename = lc($id) . ".tab"; 192*b1cdbd2cSJim Jagielskiopen OUT, ("> " . $filename) or die "Cannot write " . $filename; 193*b1cdbd2cSJim Jagielski 194*b1cdbd2cSJim Jagielski{ 195*b1cdbd2cSJim Jagielski $filename = lc($id). ".pl"; 196*b1cdbd2cSJim Jagielski open IN, $filename or die "Cannot read ". $filename; 197*b1cdbd2cSJim Jagielski $first = 1; 198*b1cdbd2cSJim Jagielski while (<IN>) 199*b1cdbd2cSJim Jagielski { 200*b1cdbd2cSJim Jagielski if (/^\#!.*$/) 201*b1cdbd2cSJim Jagielski { 202*b1cdbd2cSJim Jagielski } 203*b1cdbd2cSJim Jagielski elsif (/^\#(\*.*)$/) 204*b1cdbd2cSJim Jagielski { 205*b1cdbd2cSJim Jagielski if ($first == 1) 206*b1cdbd2cSJim Jagielski { 207*b1cdbd2cSJim Jagielski print OUT "/", $1, "\n"; 208*b1cdbd2cSJim Jagielski $first = 0; 209*b1cdbd2cSJim Jagielski } 210*b1cdbd2cSJim Jagielski else 211*b1cdbd2cSJim Jagielski { 212*b1cdbd2cSJim Jagielski print OUT " ", substr($1, 0, length($1) - 1), "/\n"; 213*b1cdbd2cSJim Jagielski } 214*b1cdbd2cSJim Jagielski } 215*b1cdbd2cSJim Jagielski elsif (/^\# (.*)$/) 216*b1cdbd2cSJim Jagielski { 217*b1cdbd2cSJim Jagielski print OUT " *", $1, "\n"; 218*b1cdbd2cSJim Jagielski } 219*b1cdbd2cSJim Jagielski elsif (/^\#(.*)$/) 220*b1cdbd2cSJim Jagielski { 221*b1cdbd2cSJim Jagielski print OUT " *", $1, "\n"; 222*b1cdbd2cSJim Jagielski } 223*b1cdbd2cSJim Jagielski else 224*b1cdbd2cSJim Jagielski { 225*b1cdbd2cSJim Jagielski goto done; 226*b1cdbd2cSJim Jagielski } 227*b1cdbd2cSJim Jagielski } 228*b1cdbd2cSJim Jagielski done: 229*b1cdbd2cSJim Jagielski} 230*b1cdbd2cSJim Jagielski 231*b1cdbd2cSJim Jagielskiprint OUT "\n", 232*b1cdbd2cSJim Jagielski "#ifndef INCLUDED_RTL_TEXTENC_CONVERTGB18030_H\n", 233*b1cdbd2cSJim Jagielski "#include \"convertgb18030.h\"\n", 234*b1cdbd2cSJim Jagielski "#endif\n", 235*b1cdbd2cSJim Jagielski "\n", 236*b1cdbd2cSJim Jagielski "#ifndef _SAL_TYPES_H_\n", 237*b1cdbd2cSJim Jagielski "#include \"sal/types.h\"\n", 238*b1cdbd2cSJim Jagielski "#endif\n", 239*b1cdbd2cSJim Jagielski "\n"; 240*b1cdbd2cSJim Jagielski 241*b1cdbd2cSJim Jagielskiprint OUT "static sal_Unicode const aImpl", $id, "ToUnicodeData[] = {\n "; 242*b1cdbd2cSJim Jagielskifor ($gb_code = 0; $gb_code < $gb_map_2_count; ++$gb_code) 243*b1cdbd2cSJim Jagielski{ 244*b1cdbd2cSJim Jagielski printf OUT "0x%04X,", $gb_map_2[$gb_code]; 245*b1cdbd2cSJim Jagielski if ($gb_code % 8 == 7 && $gb_code != $gb_map_2_count - 1) 246*b1cdbd2cSJim Jagielski { 247*b1cdbd2cSJim Jagielski print OUT "\n "; 248*b1cdbd2cSJim Jagielski } 249*b1cdbd2cSJim Jagielski} 250*b1cdbd2cSJim Jagielskiprint OUT "\n};\n\n"; 251*b1cdbd2cSJim Jagielski 252*b1cdbd2cSJim Jagielskiprint OUT "static ImplGb180302000ToUnicodeRange const\n aImpl", 253*b1cdbd2cSJim Jagielski $id, 254*b1cdbd2cSJim Jagielski "ToUnicodeRanges[] = {\n"; 255*b1cdbd2cSJim Jagielskifor ($range_index = 0; $range_index < $range_count; ++$range_index) 256*b1cdbd2cSJim Jagielski{ 257*b1cdbd2cSJim Jagielski printf OUT " { %d, %d, %d, 0x%04X },\n", 258*b1cdbd2cSJim Jagielski $gb_nonrangedataindex[$range_index], 259*b1cdbd2cSJim Jagielski $range_linear_first[$range_index], 260*b1cdbd2cSJim Jagielski $range_linear_last[$range_index] + 1, 261*b1cdbd2cSJim Jagielski $range_uni_first[$range_index]; 262*b1cdbd2cSJim Jagielski} 263*b1cdbd2cSJim Jagielskiprint OUT " { -1, 0, 0, 0 }\n};\n\n"; 264*b1cdbd2cSJim Jagielski 265*b1cdbd2cSJim Jagielskiprint OUT "static sal_uInt32 const aImplUnicodeTo", $id, "Data[] = {\n "; 266*b1cdbd2cSJim Jagielski$index = 0; 267*b1cdbd2cSJim Jagielski$range_index = 0; 268*b1cdbd2cSJim Jagielski$uni_nonrangedataindex[$range_index] = $index; 269*b1cdbd2cSJim Jagielskifor ($utf32 = 0x80; $utf32 <= 0xFFFF; ++$utf32) 270*b1cdbd2cSJim Jagielski{ 271*b1cdbd2cSJim Jagielski if (defined($uni_map[$utf32])) 272*b1cdbd2cSJim Jagielski { 273*b1cdbd2cSJim Jagielski if ($index > 0 && ($index - 1) % 6 == 5) 274*b1cdbd2cSJim Jagielski { 275*b1cdbd2cSJim Jagielski print OUT "\n "; 276*b1cdbd2cSJim Jagielski } 277*b1cdbd2cSJim Jagielski $bytes = $uni_map[$utf32]; 278*b1cdbd2cSJim Jagielski printf OUT ($bytes <= 0xFFFF ? " 0x%04X," : "0x%08X,"), $bytes; 279*b1cdbd2cSJim Jagielski ++$index; 280*b1cdbd2cSJim Jagielski } 281*b1cdbd2cSJim Jagielski else 282*b1cdbd2cSJim Jagielski { 283*b1cdbd2cSJim Jagielski ($utf32 == $range_uni_first[$range_index]) or die "Bad input"; 284*b1cdbd2cSJim Jagielski $utf32 = $range_uni_last[$range_index]; 285*b1cdbd2cSJim Jagielski ++$range_index; 286*b1cdbd2cSJim Jagielski $uni_nonrangedataindex[$range_index] = $index; 287*b1cdbd2cSJim Jagielski } 288*b1cdbd2cSJim Jagielski} 289*b1cdbd2cSJim Jagielski($range_index == $range_count) or die "Bad input"; 290*b1cdbd2cSJim Jagielskiprint OUT "\n};\n\n"; 291*b1cdbd2cSJim Jagielski 292*b1cdbd2cSJim Jagielskiprint OUT "static ImplUnicodeToGb180302000Range const\n aImplUnicodeTo", 293*b1cdbd2cSJim Jagielski $id, 294*b1cdbd2cSJim Jagielski "Ranges[] = {\n"; 295*b1cdbd2cSJim Jagielskifor ($range_index = 0; $range_index < $range_count; ++$range_index) 296*b1cdbd2cSJim Jagielski{ 297*b1cdbd2cSJim Jagielski printf OUT " { %d, 0x%04X, 0x%04X, %d },\n", 298*b1cdbd2cSJim Jagielski $uni_nonrangedataindex[$range_index], 299*b1cdbd2cSJim Jagielski $range_uni_first[$range_index], 300*b1cdbd2cSJim Jagielski $range_uni_last[$range_index], 301*b1cdbd2cSJim Jagielski $range_linear_first[$range_index]; 302*b1cdbd2cSJim Jagielski} 303*b1cdbd2cSJim Jagielskiprint OUT "};\n"; 304*b1cdbd2cSJim Jagielski 305*b1cdbd2cSJim Jagielskiclose OUT; 306