📄 mktbl.pl
字号:
# ################################################################################ SUPPLEMENTARY FUNCTIONS## ############################################################################### =============================================================================## Generate 8bit "to_ucs" table. Store table data in %ToSpeedTbl hash.# Store table size in $ToSpeedBytes scalar.## =============================================================================sub Generate8bitToUCS(){ for (my $i = 0; $i <= 255; $i++) { $ToSpeedTbl[$i] = defined $CCSUCS{$i} ? $CCSUCS{$i} : $InvCode; } $ToSpeedBytes = 256*2;}# =============================================================================## Generate speed-optimized table.## Parameter 1: # "to_ucs" - generate "to_ucs" table, store table data in @ToSpeedTbl# array, store table size in $ToSpeedBytes scalar.# "from_ucs" - generate "from_ucs" table, store table data in @FromSpeedTbl# array, store table size in $FromSpeedBytes scalar.## Data is written to @ToSpeedTbl or @FromSpeedTbl (@map) table and has the# following format:# $table[0] - 256-element array (control block);# $table[1 .. $#table] - 256-element arrays (data blocks).## =============================================================================sub GenerateSpeed($){ my $map; my $tbl; my $bytes; if ($_[0] eq "to_ucs") { $map = \%CCSUCS; $tbl = \@ToSpeedTbl; $bytes = \$ToSpeedBytes; } elsif ($_[0] eq "from_ucs") { $map = \%UCSCCS; $tbl = \@FromSpeedTbl; $bytes = \$FromSpeedBytes; } else { Err "Internal script error in GenerateSpeed()\n"; } # Identify unused blocks my @busy_blocks; $busy_blocks[$_ >> 8] = 1 foreach (keys %$map); # GENERATE FIRST 256-ELEMENT CONTROL BLOCK for (my $i = 0, my $idx = $Bits == 16 ? 0 : 256 + $Hdr8bitFromUCS; $i <= 0xFF; $i++) { $tbl->[0]->[$i] = $busy_blocks[$i] ? $idx += 256 : undef; } # GENERATE DATA BLOCKS $$bytes = 0; for (my $i = 0; $i <= 0xFF; $i++) { next unless $busy_blocks[$i]; $$bytes += 256; for (my $j = 0; $j <= 0xFF; $j++) { $tbl->[$i+1]->[$j] = $map->{($i << 8) | $j}; } } $$bytes *= 2 if $Bits == 16; $$bytes += $Hdr8bitFromUCS if $Bits == 8; $$bytes += 512;}# =============================================================================## Generate 16bit size-optimized table.## Parameter 1: # "to_ucs" - generate "to_ucs" table, store table data in @ToSizeTbl# array, store table size in $ToSizeBytes scalar.# "from_ucs" - generate "from_ucs" table, store table data in @FromSizeTbl# array, store table size in $FromSizeBytes scalar.## Data is written to @ToSizeTbl or @FromSizeTbl (@map) table and has the# following format:# $table[0] - number of ranges;# $table[1] - number of unranged codes;# $table[2] - unranged codes index in resulting array;# $table[3]->[0 .. $table[0]] - array of arrays of ranges:# $table[3]->[x]->[0] - first code;# $table[3]->[x]->[1] - last code;# $table[3]->[x]->[2] - range index in resulting array;# $table[4]->[0 .. $table[0]] - array of arrays of ranges content;# $table[5]->[0 .. $table[1]] - array of arrays of unranged codes;# $table[5]->[x]->[0] - CCS code;# $table[5]->[x]->[0] - UCS code;## =============================================================================sub Generate16bitSize($){ my $map; my $tbl; my $bytes; if ($_[0] eq "to_ucs") { $map = \%CCSUCS; $tbl = \@ToSizeTbl; $bytes = \$ToSizeBytes; } elsif ($_[0] eq "from_ucs") { $map = \%UCSCCS; $tbl = \@FromSizeTbl; $bytes = \$FromSizeBytes; } else { Err "Internal script error Generate16bitSize()\n"; } # CREATE LIST OF RANGES. my @codes = sort {$a <=> $b} keys %$map; my @ranges; # Code ranges my @range; # Current working range foreach (@codes) { if (not @range or $_ - 1 == $range[$#range]) { push @range, $_; } else { my @tmp = @range; push @ranges, \@tmp; undef @range; redo; } } # Add Last range too if (@range) { my @tmp = @range; push @ranges, \@tmp; } # OPTIMIZE LIST OF RANGES. my $r = 0; # Working range number while (1) { last if ($r == $#ranges); my @r1 = @{$ranges[$r]}; my @r2 = @{$ranges[$r + 1]}; # Calculate how many array entries two ranges need my ($s1, $s2); if ($#r1 == 0) { $s1 = 2; } elsif ($#r1 == 1) { $s1 = 4; } else { $s1 = $#r1 + 1 + 3; } if ($#r2 == 0) { $s2 = 2; } elsif ($#r2 == 1) { $s2 = 4; } else { $s2 = $#r2 + 1 + 3; } my $two = $s1 + $s2; # Calculate how many array entries will be needed if we join them my $one = $r2[$#r2] - $r1[0] + 1 + 3; $r += 1, next if ($one > $two); # Join ranges my @r; # New range. push @r, $_ foreach (@r1); for (my $i = $r1[$#r1]+1; $i < $r2[0]; $i++) { push @r, undef; } push @r, $_ foreach (@r2); $ranges[$r] = \@r; splice @ranges, $r+1, 1; } # SEPARATE RANGED AND UNRANGED CODES. SPLIT 2-CODES RANGES ON 2 UNRANGED. my @unranged; foreach (@ranges) { if ($#$_ == 0) { push @unranged, $$_[0]; undef $_; } elsif ($#$_ == 1) { push @unranged, $$_[0]; push @unranged, $$_[1]; undef $_; } } # DELETE UNUSED ELEMENTS for (my $i = 0; $i <= $#ranges; $i++) { splice @ranges, $i--, 1 unless defined $ranges[$i]; } # CALCULATE UNRANGED CODES ARRAY INDEX my $idx = 3 + ($#ranges + 1)*3; $idx += $#$_ + 1 foreach @ranges; # COMPOSE TABLE $tbl->[0] = $#ranges + 1; # Number of ranges $tbl->[1] = $#unranged + 1; # Number of unranged codes $tbl->[2] = $idx; # Array index of unranged codes # Generate ranges list $idx = 3 + ($#ranges + 1)*3; # First range data index $$bytes = $idx*2; my $num = 0; foreach (@ranges) { $tbl->[3]->[$num]->[0] = $_->[0]; $tbl->[3]->[$num]->[1] = $_->[$#$_]; $tbl->[3]->[$num]->[2] = $idx; $idx += $#$_ + 1; $num += 1; } # Generate ranges content $num = 0; foreach (@ranges) { for (my $i = 0; $i <= $#$_; $i++) { $tbl->[4]->[$num]->[$i] = defined $_->[$i] ? $map->{$_->[$i]} : undef; } $num += 1; $$bytes += ($#$_ + 1)*2; } # Generate unranged codes list $num = 0; foreach (@unranged) { $tbl->[5]->[$num]->[0] = $_; $tbl->[5]->[$num]->[1] = $map->{$_}; $num += 1; } $$bytes += ($#unranged + 1)*4;} # =============================================================================## Output 8bit "to UCS" table. Output table's source code if $Source# and table's binary data if !$Source.# # Parameter 1: Not used when sources are output. Output BE binary if 'n' and# LE binary if 'v'.## =============================================================================sub Output8bitToUCS(;$){ my $endian = $_[0]; my $br = 0; printf "Output%s 8-bit UCS -> $CCSName table ($ToSpeedBytes bytes).\n", defined $endian ? ($endian eq 'n' ? " Big Endian" : " Little Endian") : "" if $Verbose; if ($Source) { # Output heading information printf OUTFILE"/* * 8-bit $CCSName -> UCS table ($ToSpeedBytes bytes). * $Separator */#if defined ($GuardToUCS)static _CONST __uint16_t${VarToUCSSpeed}\[] ={\n\t"; } if ($Source) { foreach (@ToSpeedTbl) { $br += 1; if ($_ != $InvCode) { if ($_ != $TmpLost) { printf OUTFILE "0x%.4X,", $_; } else { print OUTFILE "$MacroLostCode,"; } } else { print OUTFILE "$MacroInvCode,"; } print(OUTFILE "\n\t"), $br = 0 unless $br % 8; } print OUTFILE "\n};\n\n#endif /* $GuardToUCS */\n\n"; } else { foreach (@ToSpeedTbl) { print OUTFILE pack($endian, $_ == $TmpLost ? $LostCode : $_); } }}# =============================================================================## Output 8bit "from UCS" table. Output table's source code if $Source# and table's binary data if !$Source.# # Parameter 1: Not used when sources are output. Output BE binary if 'n' and# LE binary if 'v'.## =============================================================================sub Output8bitFromUCS(;$){ my $endian = $_[0]; printf "Output%s 8-bit $CCSName -> UCS table ($FromSpeedBytes bytes).\n", defined $endian ? ($endian eq 'n' ? " Big Endian" : " Little Endian") : "" if $Verbose; if ($Source) { print OUTFILE"/* * 8-bit UCS -> $CCSName speed-optimized table ($FromSpeedBytes bytes). * $Separator */#if defined ($GuardFromUCS)static _CONST unsigned char${VarFromUCSSpeed}\[] ={"; } # SAVE 0xFF MAPPING. if ($Source) { printf OUTFILE "\tW(0x%.4X), /* Real 0xFF mapping. 0xFF is used " . "to mark invalid codes */\n", $FFMap; } else { print OUTFILE pack($endian, $FFMap); } # OUTPUT HEADING BLOCK (ALWAYS 16 BIT) if ($Source) { my $count = 0; print OUTFILE "\t/* Heading Block */"; for (my $i = 0, my $br = 0; $i < 256; $br = ++$i % 4) { print OUTFILE "\n\t" unless $br; if (defined $FromSpeedTbl[0]->[$i]) { printf OUTFILE "W(0x%.4X),", $FromSpeedTbl[0]->[$i]; } else { print OUTFILE "W($MacroInvBlock),"; } } } else { print OUTFILE pack($endian, defined $_ ? $_ : $InvBlock) foreach @{$FromSpeedTbl[0]}; } if ($Source) { my $index = 512 + $Hdr8bitFromUCS; for (my $blk = 1; $blk <= $#FromSpeedTbl; $blk++) { next unless defined $FromSpeedTbl[$blk]; printf OUTFILE "\n\t/* Block $blk, Array index 0x%.4X */", $index; $index += 256; for (my $i = 0, my $br = 0; $i < 256; $i++, $br = $i % 8) { print OUTFILE "\n\t" unless $br; my $code = $FromSpeedTbl[$blk]->[$i]; if (!defined $code) { printf OUTFILE "0x%.2X,", $InvCode8bit; } else { printf OUTFILE "0x%.2X,", $code == $TmpLost ? $LostCode : $code; } } } print OUTFILE "\n};\n\n#endif /* $GuardFromUCS */\n\n"; } else { for (my $blk = 1; $blk <= $#FromSpeedTbl; $blk++) { next unless defined $FromSpeedTbl[$blk]; for (my $i = 0, my $br = 0; $i < 256; $br = ++$i % 8) { my $code = $FromSpeedTbl[$blk]->[$i]; if (!defined $code) { printf OUTFILE pack 'C', $InvCode8bit; } else { print OUTFILE $code == $TmpLost ? pack('C', $LostCode) : pack('C', $code); } } } }}# =============================================================================## Output 16bit Speed-optimized table. Output table's source code if $Source# and table's binary data if !$Source.# # Parameter 1: # "to_ucs" - Output "to_ucs" table.# "from_ucs" - Output "from_ucs" table.# Parameter 2: Not used when sources are output. Output BE binary if 'n' and# LE binary if 'v'.## =============================================================================sub OutputSpeed($;$){ my $endian = $_[1]; my $tbl; my ($direction, $optimiz, $e, $bytes); $optimiz = $Bits == 16 ? " speed-optimized" : ""; $e = $endian ? ($endian eq 'n' ? " Big Endian" : " Little Endian") : ""; if ($_[0] eq "to_ucs") { $tbl = \@ToSpeedTbl; $direction = " $CCSName -> UCS"; $bytes = $ToSpeedBytes; if ($Source) { print OUTFILE"/* * 16-bit $CCSName -> UCS speed-optimized table ($ToSpeedBytes bytes). * $Separator */#if defined ($GuardToUCS) \\ && !($GuardSize)static _CONST __uint16_t${VarToUCSSpeed}\[] ={"; } } elsif ($_[0] eq "from_ucs")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -