📄 mktbl.pl
字号:
#!/usr/bin/perl -w## Copyright (c) 2003-2004, Artem B. Bityuckiy, SoftMine Corporation.## Redistribution and use in source and binary forms, with or without# modification, are permitted provided that the following conditions# are met:# 1. Redistributions of source code must retain the above copyright# notice, this list of conditions and the following disclaimer.# 2. Redistributions in binary form must reproduce the above copyright# notice, this list of conditions and the following disclaimer in the# documentation and/or other materials provided with the distribution.## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF# SUCH DAMAGE.#use integer;use Getopt::Std;use IO::Seekable;use strict;# ################################################################################ FUNCTION PROTOTYPES AND GLOBAL DATA DECLARATION SECTION## ############################################################################### SUPPLEMENTARY FUNCTIONS FORWARD DECLARATIONSsub ProcessOptions();sub Err($;$);sub Generate8bitToUCS();sub GenerateSpeed($);sub Generate16bitSize($);sub Output8bitToUCS(;$);sub Output8bitFromUCS(;$);sub OutputSpeed($;$);sub OutputSize($;$);# VARIABLES RELATING TO COMMAND-LINE OPTIONSmy $Verbose; # Be verbose if truemy $Source; # Output C source code instead of binary .cct file if truemy $Plane; # Use this plane if definedmy $InFile; # Use this file for inputmy $OutFile; # Use this file for outputmy $CCSName; # Use this CCS namemy $NoSpeed; # Don't generate speed-optimized tables (binary files only)my $NoSize; # Don't generate size-optimized tables (binary files only)my $NoBE; # Don't generate big-endian tables (binary files only)my $NoLE; # Don't generate big-endian tables (binary files only)my $NoTo; # Don't generate "to_ucs" table (binary files only)my $NoFrom; # Don't generate "from_ucs" table (binary files only)my $CCSCol; # CCS column number in source filemy $UCSCol; # UCS column number in source file# DATA STRUCTURES WITH "TO_UCS" AND "FROM_UCS" SPEED/SIZE -OPTIMIZED TABLESmy (@FromSpeedTbl, @ToSpeedTbl, @FromSizeTbl, @ToSizeTbl);# "TO_UCS" AND "FROM_UCS" SPEED/SIZE -OPTIMIZED TABLES SIZE IN BYTESmy ($FromSpeedBytes, $ToSpeedBytes, $FromSizeBytes, $ToSizeBytes) = (0, 0, 0, 0);my (%CCSUCS, %UCSCCS); # CCS->UCS and UCS->CCS mappingsmy $Bits = 8; # Table bits (8 or 16);# SPECIAL MARKER CODESmy $InvCode = 0xFFFF; # FFFF indicates 18 bit invalid codesmy $InvBlock = 0xFFFF; # FFFF also mark empty blocks in speed-optimized tablesmy $LostCode = 0x3F; # ASCII '?' marks codes lost during CCS->UCS mapping# To mark invalid codes in 8bit encodings 0xFF is used CCS's 0xFF mapping is saved# separately. $FFMap variable stores real 0xFF mapping if defined.my $InvCode8bit = 0xFF;my $FFMap;# 8 Bit "From UCS" table header size (bytes)my $Hdr8bitFromUCS = 2;# Binary table header size (bytes)my $HdrBinary = 8;# At first all lost CCS codes are marked by $TmpLost to distinguish between# code which is equivalent to $LostCode and lost codes. This is done in order to# output $MacroLostCode instead of $LostCode in source file.my $TmpLost = 0x1FFFF;# VARIABLES RELATING TO C SOURCE CODEmy $MacroInvCode = 'INVALC';my $MacroInvBlock = 'INVBLK';my $MacroLostCode = 'LOST_C';my $MacroCCSName = 'ICONV_CCS_%s';my $GuardSize = 'defined (TABLE_USE_SIZE_OPTIMIZATION)';my $GuardToUCS = "ICONV_TO_UCS_CCS_%s";my $GuardFromUCS = "ICONV_FROM_UCS_CCS_%s";my $MacroSpeedTable = 'TABLE_SPEED_OPTIMIZED';my $MacroSizeTable = 'TABLE_SIZE_OPTIMIZED'; my $Macro8bitTable = 'TABLE_8BIT';my $Macro16bitTable = 'TABLE_16BIT';my $MacroVer1Table = 'TABLE_VERSION_1';my $TypeBICCS = 'iconv_ccs_t';my $VarToUCSSize = "to_ucs_size_%s";my $VarToUCSSpeed = "to_ucs_speed_%s";my $VarFromUCSSize = "from_ucs_size_%s";my $VarFromUCSSpeed = "from_ucs_speed_%s";my $VarBICCS = "_iconv_ccs_%s";# Text block that visually separates tables.my $Separator = '=' x 70;# ################################################################################ SCRIPT ENTRY POINT## ############################################################################### Parse command-line options, check them and set correspondent global variablesProcessOptions();# Initialize global variables tat depend on CCS name.$_ = sprintf $_, $CCSName foreach +($VarToUCSSpeed, $VarToUCSSize, $VarToUCSSpeed, $VarFromUCSSpeed, $VarFromUCSSize, $VarBICCS);$_ = sprintf $_, "\U$CCSName" foreach +($GuardToUCS, $GuardFromUCS, $MacroCCSName);# Open input and output filesErr "Can't open \"$InFile\" file for reading: $!.\n", 1unless open(INFILE, '<', $InFile);Err "Can't open \"$OutFile\" file for writing: $!.\n", 1unless open(OUTFILE, '>', $OutFile);# ==============================================================================# EXTRACT CODES MAP FROM INPUT FILE# ==============================================================================for (my $ln = 1; my $l = <INFILE>; $ln += 1){ # Skip comment and empty lines, remove ending CR symbol next if $l =~ /^#.*$/ or $l =~ /^\s*$/; $l =~ s/^(.*)\n$/$1/, $l =~ s/^(.*)\r$/$1/; # Remove comment and extra spaces $l =~ s/(.*)\s*#.*/$1/; $l =~ s/\s+/ /g; $l =~ s/(.*)\s*$/$1/; # Split line into individual codes my @codes = split / /, $l; # Skip line if there is no needed columns unless (defined $codes[$CCSCol]) { print("Warning (line $ln): no CCS column, skip.\n") if $Verbose; next; } unless (defined $codes[$UCSCol]) { print("Warning (line $ln): no UCS column, skip.\n") if $Verbose; next; } # Extract codes strings from needed columns my ($ccs, $ucs) = ($codes[$CCSCol], $codes[$UCSCol]); my $patt = qr/(0[xX])?[0-9a-fA-F]{1,8}/; # HEX digit regexp pattern. # Check that CCS and UCS code strings has right format. unless ($ccs =~ m/^$patt$/) { print("Warning (line $ln): $ccs CCS code isn't recognized, skip.\n") if $Verbose; next; } unless ($ucs =~ m/^($patt(,|\+))*$patt$/) { print("Warning (line $ln): $ucs UCS code isn't recognized, skip.\n") if $Verbose; next; } # Convert code to numeric format (assume hex). $ccs = hex $ccs; if ($ucs =~ m/,/ or $ucs =~ m/\+/) { # Mark CCS codes with "one to many" mappings as lost printf "Warning (line $ln): only one to one mapping is supported, " . "mark 0x%.4X CCS code as lost.\n", hex $ccs if $Verbose; $ucs = $TmpLost; } else { # Convert code to numeric format $ucs = hex $ucs; # Check that UCS code isn't longer than 16 bits. if ($ucs > 0xFFFF) { printf("Warning (line $ln): UCS code should fit 16 bits, " . "mark 0x%.4X CCS code as lost.\n", hex $ccs) if $Verbose; $ucs = $TmpLost; } } # If CCS value > 0xFFFF user should specify plane number. if ($ccs > 0xFFFF && !defined $Plane) { print("Warning (line $ln): $ccs is > 16 bit, plane number should be specified," . " skip this mapping.\n") if $Verbose; next; } if (defined $Plane) { next if (($ccs & 0xFFFF0000) >> 16) != hex $Plane; # Skip alien plane. $ccs &= 0xFFFF; } # Check that reserved codes aren't used. if ($ccs == $InvCode or $ucs == $InvCode) { print("Warning (line $ln): $InvCode is reserved to mark invalid codes and " . "shouldn't be used in mappings, skip.\n") if $Verbose; next; } # Save mapping in UCSCCS and CCSUCS hash arrays. $UCSCCS{$ucs} = $ccs if $ucs != $TmpLost && !defined $UCSCCS{$ucs}; $CCSUCS{$ccs} = $ucs if !defined $CCSUCS{$ccs}; $Bits = 16 if $ccs > 0xFF;}if (not %CCSUCS){ Err "Error: there is no plane $Plane in \"$0\".\n" if defined $Plane; Err "Error: mapping wasn't found.\n";}# ==============================================================================# GENERATE TABLE DATA# ==============================================================================if ($Bits == 8){ $FFMap = $CCSUCS{0xFF}; $FFMap = $InvCode if !defined $FFMap; }if ($Bits == 8){ Generate8bitToUCS() unless $NoTo;}else{ GenerateSpeed("to_ucs") unless $NoTo || $NoSpeed; Generate16bitSize("to_ucs") unless $NoTo || $NoSize;}GenerateSpeed("from_ucs") unless $NoFrom || $NoSpeed;Generate16bitSize("from_ucs") unless $NoFrom || $NoSize;# ==============================================================================# OUTPUT ARRAYS# ==============================================================================if ($Source){ # OUTPUT SOURCE print OUTFILE"/* * This file was generated automatically - don't edit it. * File contains iconv CCS tables for $CCSName encoding. */#include \"ccsbi.h\"#if defined ($GuardToUCS) \\ || defined ($GuardFromUCS)#include <_ansi.h>#include <sys/types.h>#include <sys/param.h>#include \"ccs.h\"#include \"ccsnames.h\""; if ($Bits == 8) { print OUTFILE"#if (BYTE_ORDER == LITTLE_ENDIAN)# define W(word) (word) & 0xFF, (word) >> 8#elif (BYTE_ORDER == BIG_ENDIAN)# define W(word) (word) >> 8, (word) & 0xFF#else# error \"Unknown byte order.\"#endif"; } unless ($NoTo) { if ($Bits == 8) { Output8bitToUCS(); } else { OutputSpeed("to_ucs") unless $NoSpeed; OutputSize("to_ucs") unless $NoSize; } } unless ($NoFrom) { if ($Bits == 8) { Output8bitFromUCS(); } else { OutputSpeed("from_ucs") unless $NoSpeed; OutputSize("from_ucs") unless $NoSize; } } # OUTPUT TABLE DESCRIPTION STRUCTURE print OUTFILE "/* * $CCSName CCS description table. * $Separator */_CONST $TypeBICCS$VarBICCS ={\t$MacroVer1Table, /* Table version */\t$MacroCCSName, /* CCS name */"; if ($Bits == 8) { print OUTFILE"\t$Macro8bitTable, /* Table bits */\t0, /* Not Used */#if defined ($GuardFromUCS)\t(__uint16_t *)&$VarFromUCSSpeed, /* UCS -> $CCSName table */#else\t(__uint16_t *)NULL,#endif\t0, /* Not Used */#if defined ($GuardToUCS)\t(__uint16_t *)&$VarToUCSSpeed /* $CCSName -> UCS table */#else\t(__uint16_t *)NULL,#endif};\n"; } else { print OUTFILE"\t$Macro16bitTable, /* Table bits */#if defined ($GuardFromUCS) \\ && ($GuardSize)\t$MacroSizeTable,\t(__uint16_t *)&$VarFromUCSSize, /* UCS -> $CCSName table size-optimized table */#elif defined ($GuardFromUCS) \\ && !($GuardSize)\t$MacroSpeedTable,\t(__uint16_t *)&$VarFromUCSSpeed, /* UCS -> $CCSName table speed-optimized table */#else\t$MacroSpeedTable,\t(__uint16_t *)NULL,#endif#if defined ($GuardToUCS) \\ && ($GuardSize)\t$MacroSizeTable,\t(__uint16_t *)&$VarToUCSSize /* $CCSName -> UCS table speed-optimized table */#elif defined ($GuardToUCS) \\ && !($GuardSize)\t$MacroSpeedTable,\t(__uint16_t *)&$VarToUCSSpeed /* $CCSName -> UCS table speed-optimized table */#else\t$MacroSpeedTable,\t(__uint16_t *)NULL,#endif};\n"; } print OUTFILE "\n#endif /* $GuardToUCS) || ... */\n\n";}else{ # OUTPUT BINARY TABLES DESCRIPTION STRUCTURE (ALWAYS BIG ENDIAN) print OUTFILE pack "n", 1; print OUTFILE pack "n", $Bits; my $len = length $CCSName; print OUTFILE pack "N", $len; print OUTFILE pack "a$len", $CCSName; my $pos = $HdrBinary + $len; if ($pos & 3) { my $l = 4 - ($pos & 3); print OUTFILE pack "a$l", 'XXX'; $pos += $l; } $pos += 16*4; my @tables; for (my $i = 0; $i < 16; $i++) { $tables[$i] = 0; } $tables[0] = $pos, $tables[1] = $FromSpeedBytes, $pos += $FromSpeedBytes unless $NoFrom || $NoSpeed || $NoBE; $tables[2] = $pos, $tables[3] = $FromSpeedBytes, $pos += $FromSpeedBytes unless $NoFrom || $NoSpeed || $NoLE; if ($Bits == 16) { $tables[4] = $pos, $tables[5] = $FromSizeBytes, $pos += $FromSizeBytes unless $NoFrom || $NoSize || $NoBE; $tables[6] = $pos, $tables[7] = $FromSizeBytes, $pos += $FromSizeBytes unless $NoFrom || $NoSize || $NoLE; } $tables[8] = $pos, $tables[9] = $ToSpeedBytes, $pos += $ToSpeedBytes unless $NoTo || $NoSpeed || $NoBE; $tables[10] = $pos, $tables[11] = $ToSpeedBytes, $pos += $ToSpeedBytes unless $NoTo || $NoSpeed || $NoLE; if ($Bits == 16) { $tables[12] = $pos, $tables[13] = $ToSizeBytes, $pos += $ToSizeBytes unless $NoTo || $NoSize || $NoBE; $tables[14] = $pos, $tables[15] = $ToSizeBytes, $pos += $ToSizeBytes unless $NoTo || $NoSize || $NoLE; } print OUTFILE pack("N", $_) foreach @tables; print "Total bytes for output: $pos.\n" if $Verbose; # OUTPUT BINARY TABLES unless ($NoFrom) { if ($Bits == 8) { Output8bitFromUCS("n") unless $NoBE; Output8bitFromUCS("v") unless $NoLE; } else { unless ($NoSpeed) { OutputSpeed("from_ucs", "n") unless $NoBE; OutputSpeed("from_ucs", "v") unless $NoLE; } unless ($NoSize) { OutputSize("from_ucs", "n") unless $NoBE; OutputSize("from_ucs", "v") unless $NoLE; } } } unless ($NoTo) { if ($Bits == 8) { Output8bitToUCS("n") unless $NoBE; Output8bitToUCS("v") unless $NoLE; } else { unless ($NoSpeed) { OutputSpeed("to_ucs", "n") unless $NoBE; OutputSpeed("to_ucs", "v") unless $NoLE; } unless ($NoSize) { OutputSize("to_ucs", "n") unless $NoBE; OutputSize("to_ucs", "v") unless $NoLE; } } }}close INFILE;close OUTFILE;exit 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -