-my @nibble = (0..9, 'A'..'F');
-my $nibsize = 1;
-
-use Encode qw(decode resolve_alias);
-# generate character table(s)
-# (~16x faster than decoding in loop;
-# substr strings is twice as fast as splitting to an array)
-my %ALIAS = (
-# default => [qw(unicode utf-8 iso-8859-1 cp437 -cp1252- --iso-8859-15- -koi8-f)],
- default => [qw(unicode- utf-8 iso-8859-1 -cp1252- --iso-8859-15- cp437 -cp850)],
- 0 => [qw(cp437 -cp863)],
- 1 => [qw(iso-8859-1 -cp1252 -MacRoman -cp850)],
- 2 => [qw(iso-8859-2 -cp1250 -cp852 -MacCentralEurRoman -MacCroatian -MacRumanian)],
- 5 => [qw(koi8-f -iso-8859-5 -cp1251 -MacCyrillic -cp855 -cp866)],
- 7 => [qw(iso-8859-7 -cp1253 -MacGreek -cp737 -cp869)],
- 8 => [qw(iso-8859-8 -cp1255 -MacHebrew -cp862)],
-);
-my @request = map {
- if (my $input = $_) {
- my %row = (offset => 0);
- my $endpoint = 255;
- if ($input =~ s/^--//) {
- $row{offset} = $endpoint > 160 ? 160 : 48;
- }
- elsif ($input =~ s/^-//) {
- $row{offset} = $endpoint > 128 ? 128 : 32;
+my @request;
+
+sub tabinput {
+ # generate character table(s)
+ my $input = shift or return;
+
+ state $ALIAS = {
+ default => [qw( unicode+0-192 utf-8 iso-8859-1 iso-8859-15 cp1252 cp437 cp850 )],
+ us => [qw( cp437 cp863 AdobeStandardEncoding gsm0338 )],
+ ebcdic => [qw( cp37 cp500 cp875 cp1026 cp1047 posix-bc )],
+ iso => [map {"iso-8859-$_"} 1 .. 11, 13 .. 16],
+ dos => [qw( cp437 cp865 cp861 cp860 cp863 cp850 cp857 cp852 cp775
+ cp737 cp869 cp866 cp855 cp862 cp864 )],
+ aix => [qw( cp1006 )],
+ win => [qw( cp1252 cp1250 cp1254 cp1257 cp1258 cp1253 cp1251 cp1255 cp1256 cp874 )],
+
+ westeur => [qw( iso-8859-1 iso-8859-15 cp1252 iso-8859-14 cp850 hp-roman8 nextstep MacRoman )],
+ centeur => [qw( iso-8859-2 iso-8859-16 cp1250 cp852 MacRomanian MacCroatian MacCentralEurRoman )], # MacRumanian only for DB
+ turkish => [qw( iso-8859-9 iso-8859-3 cp1254 cp857 MacTurkish )],
+ baltic => [qw( iso-8859-4 iso-8859-13 cp1257 cp775 )],
+ nordic => [qw( iso-8859-10 cp865 cp861 MacIcelandic MacSami )],
+ cyrillic => [qw( koi8-r koi8-u koi8-f iso-8859-5 cp1251 MacCyrillic cp866 cp855 )], # MacUkrainian is broken
+ arabic => [qw( iso-8859-6 cp1006 cp864 cp1256 MacArabic )], # MacFarsi same as MacArabic?
+ greek => [qw( iso-8859-7 cp1253 MacGreek cp737 cp869 )],
+ hebrew => [qw( iso-8859-8 cp1255 MacHebrew cp862 )],
+ thai => [qw( iso-8859-11 cp874 MacThai )],
+ vietnamese => [qw( viscii cp1258 MacVietnamese )],
+ symbol => [qw( symbol dingbats MacDingbats AdobeZdingbat AdobeSymbol )],
+ # iso-code shorthand
+ 1 => 'westeur',
+ 2 => 'centeur',
+ 3 => 'turkish',
+ 4 => 'baltic',
+ 5 => 'cyrillic',
+ 6 => 'arabic',
+ 7 => 'greek',
+ 8 => 'hebrew',
+ 9 => 'turkish',
+ 10 => 'nordic',
+ 11 => 'thai',
+ };
+ if (my $follow = $ALIAS->{$input}) {
+ tabinput($_) for ref $follow ? @{$follow} : $follow;
+ return;
+ }
+
+ state $visible = {}; # all present tables
+ my %row = (offset => 0, cols => 16);
+ my $endpoint = 255;
+ my $params = $input =~ s/[+](.*)\z// ? $1 : undef;
+
+ if (not defined $params) {
+ use List::Util qw( first pairfirst pairs );
+
+ state $INHERIT = {
+ 'cp437' => ['cp850' => 0], # ascii range overridden later
+ 'gsm0338' => ['ascii' => '0-127'],
+
+ 'iso-8859-2' => ['iso-8859-1' => '160'],
+ 'iso-8859-3' => ['iso-8859-1' => '160'],
+ 'iso-8859-4' => ['iso-8859-2' => '160'],
+ 'iso-8859-5' => ['iso-8859-1' => '160'],
+ 'iso-8859-6' => ['iso-8859-1' => '160'],
+ 'iso-8859-7' => ['iso-8859-1' => '160'],
+ 'iso-8859-8' => ['iso-8859-1' => '160'],
+ 'iso-8859-9' => ['iso-8859-1' => '208'],
+ 'iso-8859-10' => ['iso-8859-4' => '160'],
+ 'iso-8859-11' => ['iso-8859-1' => '160'],
+ 'iso-8859-13' => ['iso-8859-4' => '160'],
+ 'iso-8859-14' => ['iso-8859-1' => '160'],
+ 'iso-8859-15' => ['iso-8859-1' => '160-191'],
+ 'iso-8859-16' => ['iso-8859-2' => '160'],
+ 'hp-roman8' => ['iso-8859-1' => '160'],
+
+ 'cp1252' => ['iso-8859-1' => '128-159'],
+ 'cp1250' => ['iso-8859-2' => '128-191', 'cp1252' => '128'],
+ 'cp1254' => ['iso-8859-9' => '128-159', 'cp1252' => '128'],
+ 'cp874' => ['iso-8859-11' => '128-159', 'cp1252' => '128'], # windows-874 actually cp1162
+ 'cp1257' => ['iso-8859-13' => '128', 'cp1252' => '128'],
+ 'cp1251' => ['cp1252' => '128'],
+ 'cp1253' => ['cp1252' => '128'],
+ 'cp1255' => ['iso-8859-8' => '128-223', 'cp1252' => '128'],
+ 'cp1256' => ['cp1252' => '128'],
+ 'cp1258' => ['cp1252' => '128'],
+
+ 'cp850' => ['cp437' => '144'],
+ 'cp860' => ['cp437' => '128-175'],
+ 'cp861' => ['cp865' => '128-175'],
+ 'cp863' => ['cp437' => '128-175'],
+ 'cp865' => ['cp437' => '144-175'],
+ 'cp852' => ['cp850' => '128', 'cp437' => '128'],
+ 'cp857' => ['cp850' => '128-239', 'cp437' => '128'],
+ 'cp775' => ['cp850' => '128'], # partial cp437
+ 'cp866' => ['cp437' => '128'],
+ 'cp855' => ['cp437' => '128'],
+ 'cp1006' => ['cp437' => '128'],
+ 'cp737' => ['cp437' => '128'],
+ 'cp869' => ['cp437' => '128'],
+ 'cp862' => ['cp437' => '128'],
+ 'cp864' => ['cp437' => '128'],
+
+ 'koi8-u' => ['koi8-r' => 128],
+ 'koi8-f' => ['koi8-u' => 128],
+
+ 'MacRomanian' => ['MacRoman' => '160'],
+ 'MacCroatian' => ['MacRoman' => '160'],
+ 'MacCentralEurRoman' => ['MacRoman' => '128'],
+ 'MacTurkish' => ['MacRoman' => '208-223'], # F5 is unassigned
+ 'MacCyrillic' => ['MacRoman' => '128'],
+ 'MacHebrew' => ['MacRoman' => '128'],
+ };
+
+ my @parents = @{ $INHERIT->{$input} || [] };
+
+ if (my ($parent, $part) = pairfirst { defined $visible->{$a} } @parents) {
+ $row{parent} = $parent;
+ $params = $part;
+ $params = 128 unless $visible->{$parent}
+ or ($input eq 'MacCroatian' and defined $visible->{MacRomanian});