#!/usr/bin/perl -w # $Id: print-vt-chars.pl,v 1.1.1.1.2.2 2021/02/17 09:45:01 martin Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # # Copyright 2018,2020 by Thomas E. Dickey # # All Rights Reserved # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- # Print GL and GR, with the same charset (if possible) for testing. use strict; use warnings; $| = 2; use Getopt::Std; our ( $opt_L, $opt_l, $opt_R, $opt_r, $opt_v ); our %charsets; our %caseless; our $vt_level; binmode STDOUT; sub NRC($) { printf "\033[?42%s", $_[0] ? "h" : "l"; } sub LS0($) { printf "\017"; } sub LS1() { printf "\016"; } sub LS1R() { printf "\033~"; } sub LS2() { printf "\033n"; } sub LS2R() { printf "\033}"; } sub LS3() { printf "\033o"; } sub LS3R($) { printf "\033|"; } sub G0($) { my %charset = %{ $_[0] }; printf "\033(%s", $charset{TAG} if ( $charset{HOW} == 0 ); } sub G1($) { my %charset = %{ $_[0] }; printf "\033)%s", $charset{TAG} if ( $charset{HOW} == 0 ); printf "\033-%s", $charset{TAG} if ( $charset{HOW} == 1 ); } sub G2($) { my %charset = %{ $_[0] }; printf "\033*%s", $charset{TAG} if ( $charset{HOW} == 0 ); printf "\033.%s", $charset{TAG} if ( $charset{HOW} == 1 ); } sub G3($) { my %charset = %{ $_[0] }; printf "\033+%s", $charset{TAG} if ( $charset{HOW} == 0 ); printf "\033/%s", $charset{TAG} if ( $charset{HOW} == 1 ); } sub init_charset($$$$$$) { my %charset; my $mixed = shift; $charset{WHO} = $mixed; $charset{HOW} = shift; $charset{TAG} = shift; $charset{MIN} = shift; $charset{MAX} = shift; $charset{NRC} = shift; $charsets{$mixed} = \%charset; my $lower = lc $charset{WHO}; $caseless{$lower} = $charset{WHO}; } sub find_charset($) { my $mixed = shift; my $lower = lc $mixed; my %result; if ( $caseless{$lower} ) { $mixed = $caseless{$lower}; %result = %{ $charsets{$mixed} }; undef %result if ( $result{MAX} < $vt_level or $result{MIN} > $vt_level ); } printf STDERR "? no match for $mixed with VT-level $vt_level\n" unless %result; return \%result; } sub failed($) { my $msg = shift; printf STDERR "? %s\n", $msg; exit 1; } sub valid_code($) { my $code = shift; my $result = 0; $result = 1 if ( $code =~ /^[0-3]$/ ); return $result; } sub valid_name($) { my $mixed = shift; my $lower = lc $mixed; my $result = 0; $result = 1 if ( defined( $caseless{$lower} ) ); return $result; } sub setup_charsets($$$$) { my $gl_code = shift; my $gl_name = shift; my $gr_code = shift; my $gr_name = shift; my %gl_data = %{ &find_charset($gl_name) }; my %gr_data = %{ &find_charset($gr_name) }; return 0 unless %gl_data; return 0 unless %gr_data; &NRC(1) if ( $gl_data{NRC} or $gr_data{NRC} ); if ( $gl_code == 0 ) { &G0( \%gl_data ); &LS0; } elsif ( $gl_code == 1 ) { &G1( \%gl_data ); &LS1; } elsif ( $gl_code == 2 ) { &G2( \%gl_data ); &LS2; } elsif ( $gl_code == 3 ) { &G3( \%gl_data ); &LS3; } if ( $gr_code == 0 ) { &G0( \%gr_data ); } elsif ( $gr_code == 1 ) { &G1( \%gr_data ); &LS1R; } elsif ( $gr_code == 2 ) { &G2( \%gr_data ); &LS2R; } elsif ( $gr_code == 3 ) { &G3( \%gr_data ); &LS3R; } return 1; } sub cleanup() { &setup_charsets( 0, "ASCII", 1, "ASCII" ); &NRC(0); } sub doit($$$$) { my $gl_code = shift; my $gl_name = shift; my $gr_code = shift; my $gr_name = shift; &failed("Illegal left-code $gl_code") unless &valid_code($gl_code); &failed("Illegal right-code $gr_code") unless &valid_code($gr_code); &failed("Unknown left-charset $gl_name") unless &valid_name($gl_name); &failed("Unknown right charset $gr_name") unless &valid_name($gr_name); printf "GL (G%d %s):\n", $gl_code, $gl_name; if ( &setup_charsets( $gl_code, $gl_name, $gr_code, $gr_name ) ) { for my $c ( 32 .. 127 ) { printf "%c", $c; printf "\n" if ( ( ( $c - 31 ) % 16 ) == 0 ); } printf "\n"; &cleanup; } printf "GR (G%d %s):\n", $gr_code, $gr_name; if ( &setup_charsets( $gl_code, $gl_name, $gr_code, $gr_name ) ) { for my $c ( 32 .. 127 ) { printf "%c", $c + 128; printf "\n" if ( ( ( $c - 31 ) % 16 ) == 0 ); } printf "\n"; &cleanup; } } sub main::HELP_MESSAGE() { printf STDERR < $vt_level ); $known[ ++$known ] = $key; $width = length($key) if ( length($key) > $width ); } $width += 3; my $cols = int( 78 / $width ); my $high = int( ( $known + $cols ) / $cols ); for my $y ( 0 .. $high - 1 ) { printf STDERR " "; for my $x ( 0 .. $cols - 1 ) { my $z = $x * $high + $y; next if ( $z > $known ); printf STDERR "%-*s", $width, $known[$z]; } printf STDERR "\n"; } exit 1; } &init_charset( "ASCII", 0, 'B', 1, 9, 0 ); &init_charset( "British", 0, 'A', 1, 9, 0 ); &init_charset( "DEC_Spec_Graphic", 0, '0', 1, 9, 0 ); &init_charset( "DEC_Alt_Chars", 0, '1', 1, 1, 0 ); &init_charset( "DEC_Alt_Graphics", 0, '2', 1, 1, 0 ); &init_charset( "DEC_Supp", 0, '<', 2, 9, 0 ); &init_charset( "Dutch", 0, '4', 2, 9, 1 ); &init_charset( "Finnish", 0, '5', 2, 9, 1 ); &init_charset( "Finnish2", 0, 'C', 2, 9, 1 ); &init_charset( "French", 0, 'R', 2, 9, 1 ); &init_charset( "French2", 0, 'f', 2, 9, 1 ); &init_charset( "French_Canadian", 0, 'Q', 2, 9, 1 ); &init_charset( "German", 0, 'K', 2, 9, 1 ); &init_charset( "Italian", 0, 'Y', 2, 9, 1 ); &init_charset( "Norwegian_Danish2", 0, 'E', 2, 9, 1 ); &init_charset( "Norwegian_Danish3", 0, '6', 2, 9, 1 ); &init_charset( "Spanish", 0, 'Z', 2, 9, 1 ); &init_charset( "Swedish", 0, '7', 2, 9, 1 ); &init_charset( "Swedish2", 0, 'H', 2, 9, 1 ); &init_charset( "Swiss", 0, '=', 2, 9, 1 ); &init_charset( "British_Latin_1", 0, 'A', 3, 9, 1 ); &init_charset( "DEC_Supp_Graphic", 0, '%5', 3, 9, 0 ); &init_charset( "DEC_Technical", 0, '>', 3, 9, 0 ); &init_charset( "French_Canadian2", 0, '9', 3, 9, 1 ); &init_charset( "Norwegian_Danish", 0, '`', 3, 9, 1 ); &init_charset( "Portuguese", 0, '%6', 3, 9, 1 ); &init_charset( "ISO_Greek_Supp", 1, 'F', 5, 9, 0 ); &init_charset( "ISO_Hebrew_Supp", 1, 'H', 5, 9, 0 ); &init_charset( "ISO_Latin_5_Supp", 1, 'M', 5, 9, 0 ); &init_charset( "ISO_Latin_Cyrillic", 1, 'L', 5, 9, 0 ); &init_charset( "Greek", 0, '">', 5, 9, 1 ); &init_charset( "DEC_Greek", 0, '"?', 5, 9, 1 ); &init_charset( "Cyrillic", 0, '&4', 5, 9, 0 ); &init_charset( "DEC_Hebrew", 0, '"4', 5, 9, 0 ); &init_charset( "Hebrew", 0, '%=', 5, 9, 1 ); &init_charset( "Russian", 0, '&5', 5, 9, 1 ); &init_charset( "SCS_NRCS", 0, '%3', 5, 9, 0 ); &init_charset( "Turkish", 0, '%2', 5, 9, 1 ); &init_charset( "DEC_Turkish", 0, '%0', 5, 9, 0 ); $vt_level = 1; # don't expect much if ( -t 0 and -t 1 ) { my $da2 = ` old=\$(stty -g); stty raw -echo min 0 time 5; printf '\033[>c' >/dev/tty; read response; stty \$old; echo "\$response"`; if ( $da2 =~ /^\033\[>\d+;\d+;\d+c$/ ) { my $Pp = $da2; $Pp =~ s/^.*>//; $Pp =~ s/;.*$//; if ( $Pp == 0 ) { $vt_level = 1; } elsif ( $Pp == 1 or $Pp == 2 ) { $vt_level = 2; } elsif ( $Pp == 18 or $Pp == 19 or $Pp == 24 ) { $vt_level = 3; } elsif ( $Pp == 41 ) { $vt_level = 4; } elsif ( $Pp == 61 or $Pp == 64 or $Pp == 65 ) { $vt_level = 5; } } } $Getopt::Std::STANDARD_HELP_VERSION = 1; &getopts('L:l:R:r:v:') || main::HELP_MESSAGE; $vt_level = $opt_v if ( defined $opt_v ); &failed("VT-level must be 1-5") if ( $vt_level < 1 or $vt_level > 5 ); if ( $#ARGV >= 0 ) { while ( $#ARGV >= 0 ) { my $name = shift @ARGV; &doit( defined($opt_L) ? $opt_L : 2, # defined($opt_l) ? $opt_l : $name, # defined($opt_R) ? $opt_R : 3, # defined($opt_r) ? $opt_r : $name ); last if ( defined($opt_L) # and defined($opt_l) # and defined($opt_R) # and defined($opt_r) ); } } else { &doit( defined($opt_L) ? $opt_L : 2, # defined($opt_l) ? $opt_l : "ASCII", # defined($opt_R) ? $opt_R : 3, # defined($opt_r) ? $opt_r : "ASCII" ); } 1;