query-status.pl revision f2e35a3a
1#!/usr/bin/env perl
2# $XTermId: query-status.pl,v 1.7 2019/05/19 08:57:41 tom Exp $
3# -----------------------------------------------------------------------------
4# this file is part of xterm
5#
6# Copyright 2017-2018,2019 by Thomas E. Dickey
7#
8#                         All Rights Reserved
9#
10# Permission is hereby granted, free of charge, to any person obtaining a
11# copy of this software and associated documentation files (the
12# "Software"), to deal in the Software without restriction, including
13# without limitation the rights to use, copy, modify, merge, publish,
14# distribute, sublicense, and/or sell copies of the Software, and to
15# permit persons to whom the Software is furnished to do so, subject to
16# the following conditions:
17#
18# The above copyright notice and this permission notice shall be included
19# in all copies or substantial portions of the Software.
20#
21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
25# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28#
29# Except as contained in this notice, the name(s) of the above copyright
30# holders shall not be used in advertising or otherwise to promote the
31# sale, use or other dealings in this Software without prior written
32# authorization.
33# -----------------------------------------------------------------------------
34# Test the status features of xterm using DECRQSS.
35#
36# TODO: use Term::ReadKey rather than system/stty
37
38use strict;
39use warnings;
40
41use Getopt::Std;
42use IO::Handle;
43
44our ($opt_8);
45
46$Getopt::Std::STANDARD_HELP_VERSION = 1;
47&getopts('8') || die(
48    "Usage: $0 [options]\n
49Options:\n
50  -8      use 8-bit controls
51
52Options which use C1 controls may not work with UTF-8.
53"
54);
55
56our $ST = $opt_8 ? "\x9c" : "\x1b\\";
57
58our %suffixes;
59$suffixes{DECSCA}   = '"q';
60$suffixes{DECSCL}   = '"p';
61$suffixes{DECSTBM}  = 'r';
62$suffixes{DECSLRM}  = 's';
63$suffixes{SGR}      = 'm';
64$suffixes{DECSCUSR} = ' q';
65
66sub get_reply($) {
67    open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n");
68    autoflush TTY 1;
69    my $old = `stty -g`;
70    system "stty raw -echo min 0 time 5";
71
72    print TTY @_;
73    my $reply = <TTY>;
74    close TTY;
75    system "stty $old";
76    if ( defined $reply ) {
77        die("^C received\n") if ( "$reply" eq "\003" );
78    }
79    return $reply;
80}
81
82sub visible($) {
83    my $reply = $_[0];
84    my $n;
85    my $result = "";
86    for ( $n = 0 ; $n < length($reply) ; ) {
87        my $c = substr( $reply, $n, 1 );
88        if ( $c =~ /[[:print:]]/ ) {
89            $result .= $c;
90        }
91        else {
92            my $k = ord substr( $reply, $n, 1 );
93            if ( ord $k == 0x1b ) {
94                $result .= "\\E";
95            }
96            elsif ( $k == 0x7f ) {
97                $result .= "^?";
98            }
99            elsif ( $k == 32 ) {
100                $result .= "\\s";
101            }
102            elsif ( $k < 32 ) {
103                $result .= sprintf( "^%c", $k + 64 );
104            }
105            elsif ( $k > 128 ) {
106                $result .= sprintf( "\\%03o", $k );
107            }
108            else {
109                $result .= chr($k);
110            }
111        }
112        $n += 1;
113    }
114
115    return $result;
116}
117
118sub query_one($) {
119    my $name   = shift;
120    my $suffix = $suffixes{$name};
121    my $prefix = $opt_8 ? "\x90" : "\x1bP";
122    my $reply;
123    my $n;
124    my $st    = $opt_8 ? "\x9c" : qr/\x1b\\/;
125    my $DCS   = qr/${prefix}/;
126    my $match = qr/${DCS}.*${st}/;
127
128    $reply = get_reply( $prefix . '$q' . $suffix . $ST );
129
130    printf "%-10s query{%s}%*s", $name,    #
131      &visible($suffix),                   #
132      4 - length($suffix), " ";
133
134    if ( defined $reply ) {
135        printf "%2d ", length($reply);
136        if ( $reply =~ /${match}/ ) {
137
138            $reply =~ s/^${DCS}//;
139            $reply =~ s/^;//;
140            $reply =~ s/${st}$//;
141        }
142        else {
143            printf "? ";
144        }
145
146        printf "{%s}", visible($reply);
147    }
148    printf "\n";
149}
150
151printf "\x1b G" if ($opt_8);
152
153if ( $#ARGV >= 0 ) {
154    while ( $#ARGV >= 0 ) {
155        &query_one( shift @ARGV );
156    }
157}
158else {
159    for my $key ( sort keys %suffixes ) {
160        &query_one($key);
161    }
162}
163
164printf "\x1b F" if ($opt_8);
165