diff --git a/tools/tools/vt/keymaps/convert-keymap.pl b/tools/tools/vt/keymaps/convert-keymap.pl index 42349faeaf62..f2a0799b0c32 100755 --- a/tools/tools/vt/keymaps/convert-keymap.pl +++ b/tools/tools/vt/keymaps/convert-keymap.pl @@ -1,106 +1,123 @@ #!/usr/bin/perl # $FreeBSD$ use Text::Iconv; use Encode; use strict; use utf8; die "Usage: $0 filename.kbd CHARSET" unless ($ARGV[1]); my $converter = Text::Iconv->new($ARGV[1], "UTF-8"); sub local_to_UCS_string { my ($string) = @_; return $converter->convert($string); } sub prettyprint_token { my ($code) = @_; return "'" . chr($code) . "'" if 32 <= $code and $code <= 126; # print as ASCII if possible # return sprintf "%d", $code; # <---- temporary decimal return sprintf "0x%02x", $code if $code <= 255; # print as hex number, else return sprintf "0x%04x", $code; } sub local_to_UCS_code { my ($char) = @_; return prettyprint_token(ord(Encode::decode("UTF-8", local_to_UCS_string($char)))); } +sub malformed_to_UCS_code +{ + my ($char) = @_; + + return prettyprint_token(ord(Encode::decode("UTF-8", $char))); +} sub convert_token { my ($C) = @_; return $1 - if $C =~ m/^([a-z][a-z0-9]*)$/; # key token + if $C =~ m/^([a-z][a-z0-9]*)$/; # key token return local_to_UCS_code(chr($1)) - if $C =~ m/^(\d+)$/; # decimal number + if $C =~ m/^(\d+)$/; # decimal number return local_to_UCS_code(chr(hex($1))) - if $C =~ m/^0x([0-9a-f]+)$/i; # hex number + if $C =~ m/^0x([0-9a-f]+)$/i; # hex number return local_to_UCS_code(chr(ord($1))) - if $C =~ m/^'(.)'$/; # character - return ""; # uncovered case + if $C =~ m/^'(.)'$/; # character + return malformed_to_UCS_code($1) + if $C =~ m/^'(.+)'$/; # character + return ""; # uncovered case } sub tokenize { # split on white space and parentheses (but not within token) my ($line) = @_; - $line =~ s/' '/ _spc_ /g; # prevent splitting of ' ' +#print "<< $line"; $line =~ s/'\('/ _lpar_ /g; # prevent splitting of '(' $line =~ s/'\)'/ _rpar_ /g; # prevent splitting of ')' + $line =~ s/'''/'_squote_'/g; # remove quoted single quotes from matches below $line =~ s/([()])/ $1 /g; # insert blanks around remaining parentheses + my $matches; + do { + $matches = ($line =~ s/^([^']*)'([^']+)'/$1_squoteL_$2_squoteR_/g); +# print "-> $line<> $matches: ('$1','$2')\n"; + } while $matches; + $line =~ s/_squoteL_ _squoteR_/ _spc_ /g; # prevent splitting of ' ' my @KEYTOKEN = split (" ", $line); + grep(s/_squote[LR]?_/'/g, @KEYTOKEN); grep(s/_spc_/' '/, @KEYTOKEN); grep(s/_lpar_/'('/, @KEYTOKEN); grep(s/_rpar_/')'/, @KEYTOKEN); +#printf ">> $line%s\n", join('|', @KEYTOKEN); return @KEYTOKEN; } # main program open FH, "<$ARGV[0]"; while () { if (m/^#/) { print local_to_UCS_string($_); } elsif (m/^\s*$/) { print "\n"; } else { my @KEYTOKEN = tokenize($_); my $at_bol = 1; my $C; foreach $C (@KEYTOKEN) { if ($at_bol) { if ($C =~ m/^\s*\d/) { # line begins with key code number printf " %03d ", $C; } elsif ($C =~ m/^[a-z]/) { # line begins with accent name or paren printf " %-4s ", $C; # accent name starts accent definition } elsif ($C eq "(") { printf "%17s", "( "; # paren continues accent definition } else { - print "UNKNOWN DEFINITION: $_"; + print "Unknown input line format: $_"; } $at_bol = 0; } else { if ($C =~ m/^([BCNO])$/) { print " $1"; # special case: effect of Caps Lock/Num Lock } elsif ($C eq "(") { print " ( "; } elsif ($C eq ")") { print " )"; } else { printf "%-6s ", convert_token($C); } } } print "\n"; } } close FH; diff --git a/tools/tools/vt/keymaps/convert-keymaps.pl b/tools/tools/vt/keymaps/convert-keymaps.pl index d60b79795192..dd452af1c12b 100755 --- a/tools/tools/vt/keymaps/convert-keymaps.pl +++ b/tools/tools/vt/keymaps/convert-keymaps.pl @@ -1,99 +1,99 @@ #!/usr/local/bin/perl # $FreeBSD$ use Text::Iconv; use Encode; use strict; use utf8; # directories and filenames $0 =~ m:^(.*)/:; my $dir_convtool = $1 || "."; my $dir_keymaps_syscons = "/usr/src/share/syscons/keymaps"; my $dir_keymaps_config = "$dir_convtool"; my $dir_keymaps_vt = "/usr/src/share/vt/keymaps"; my $dir_keymaps_output = "$dir_keymaps_vt/OUTPUT"; my $keymap_index = "$dir_keymaps_syscons/INDEX.keymaps"; my $language_map = "$dir_keymaps_config/LANG.map"; my $keymapfile_map = "$dir_keymaps_config/KBDFILES.map"; # global variables my %LANG_NEW; # index: lang_old my %ENCODING; # index: lang_old, file_old my %FILE_NEW; # index: file_old # subroutines sub local_to_UCS_string { my ($string, $old_enc) = @_; my $converter = Text::Iconv->new($old_enc, "UTF-8"); my $result = $converter->convert($string); printf "!!! conversion failed for '$string' ($old_enc)\n" unless $result; return $result; } sub lang_fixup { my ($langlist) = @_; my $result; my $lang; for $lang (split(/,/, $langlist)) { $result .= "," if $result; $result .= $LANG_NEW{$lang}; } return $result; } # main program open LANGMAP, "<$language_map" or die "$!"; while () { next if m/^#/; my ($lang_old, $lang_new, $encoding) = split(" "); # print "$lang_old|$lang_new|$encoding\n"; $LANG_NEW{$lang_old} = $lang_new; $ENCODING{$lang_old} = $encoding; $ENCODING{$lang_new} = $encoding; } close LANGMAP; $FILE_NEW{"MENU"} = "MENU"; # dummy identity mapping $FILE_NEW{"FONT"} = "FONT"; # dummy identity mapping open FILEMAP, "<$keymapfile_map" or die "$!"; while () { next if m/^#/; my ($encoding, $file_old, $file_new) = split(" "); # print "--> ", join("|", $encoding, $file_old, $file_new, $file_locale), "\n"; if ($encoding and $file_old and $file_new) { $ENCODING{$file_old} = $encoding; $FILE_NEW{$file_old} = $file_new; } } close FILEMAP; my $kbdfile; foreach $kbdfile (glob("$dir_keymaps_syscons/*.kbd")) { my $basename; ($basename = $kbdfile) =~ s:.*/::; my $encoding = $ENCODING{$basename}; my $outfile = $FILE_NEW{$basename}; if ($encoding and $outfile) { if (-r $kbdfile) { print "converting from '$basename' ($encoding) to '$outfile' (Unicode)\n"; my $cmdline = "$dir_convtool/convert-keymap.pl $kbdfile $ENCODING{$basename} > $dir_keymaps_output/$outfile"; system "$cmdline"; } else { print "$kbdfile not found\n"; } } else { - print "Unknown input file: $basename\n"; + print "Ignore '$basename': No encoding defined in KBDFILES.map\n"; } }