query-status.pl revision 913cc679
1913cc679Smrg#!/usr/bin/env perl
2913cc679Smrg# $XTermId: query-status.pl,v 1.2 2017/01/22 20:25:59 tom Exp $
3913cc679Smrg# -----------------------------------------------------------------------------
4913cc679Smrg# this file is part of xterm
5913cc679Smrg#
6913cc679Smrg# Copyright 2017 by Thomas E. Dickey
7913cc679Smrg#
8913cc679Smrg#                         All Rights Reserved
9913cc679Smrg#
10913cc679Smrg# Permission is hereby granted, free of charge, to any person obtaining a
11913cc679Smrg# copy of this software and associated documentation files (the
12913cc679Smrg# "Software"), to deal in the Software without restriction, including
13913cc679Smrg# without limitation the rights to use, copy, modify, merge, publish,
14913cc679Smrg# distribute, sublicense, and/or sell copies of the Software, and to
15913cc679Smrg# permit persons to whom the Software is furnished to do so, subject to
16913cc679Smrg# the following conditions:
17913cc679Smrg#
18913cc679Smrg# The above copyright notice and this permission notice shall be included
19913cc679Smrg# in all copies or substantial portions of the Software.
20913cc679Smrg#
21913cc679Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22913cc679Smrg# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23913cc679Smrg# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24913cc679Smrg# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
25913cc679Smrg# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26913cc679Smrg# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27913cc679Smrg# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28913cc679Smrg#
29913cc679Smrg# Except as contained in this notice, the name(s) of the above copyright
30913cc679Smrg# holders shall not be used in advertising or otherwise to promote the
31913cc679Smrg# sale, use or other dealings in this Software without prior written
32913cc679Smrg# authorization.
33913cc679Smrg# -----------------------------------------------------------------------------
34913cc679Smrg# Test the status features of xterm using DECRQSS.
35913cc679Smrg#
36913cc679Smrg# TODO: use Term::ReadKey rather than system/stty
37913cc679Smrg# TODO: make options work...
38913cc679Smrg
39913cc679Smrguse strict;
40913cc679Smrguse warnings;
41913cc679Smrg
42913cc679Smrguse Getopt::Std;
43913cc679Smrguse IO::Handle;
44913cc679Smrg
45913cc679Smrgour ( $opt_8, $opt_s );
46913cc679Smrg&getopts('8s') || die(
47913cc679Smrg    "Usage: $0 [options]\n
48913cc679SmrgOptions:\n
49913cc679Smrg  -8      use 8-bit controls
50913cc679Smrg  -s      use ^G rather than ST
51913cc679Smrg"
52913cc679Smrg);
53913cc679Smrg
54913cc679Smrgour $ST = $opt_s ? "\007" : ( $opt_8 ? "\x9c" : "\x1b\\");
55913cc679Smrg
56913cc679Smrgour %suffixes;
57913cc679Smrg$suffixes{DECSCA}   = '"q';
58913cc679Smrg$suffixes{DECSCL}   = '"p';
59913cc679Smrg$suffixes{DECSTBM}  = 'r';
60913cc679Smrg$suffixes{DECSLRM}  = 's';
61913cc679Smrg$suffixes{SGR}      = 'm';
62913cc679Smrg$suffixes{DECSCUSR} = ' q';
63913cc679Smrg
64913cc679Smrgsub no_reply($) {
65913cc679Smrg    open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n");
66913cc679Smrg    autoflush TTY 1;
67913cc679Smrg    my $old = `stty -g`;
68913cc679Smrg    system "stty raw -echo min 0 time 5";
69913cc679Smrg
70913cc679Smrg    print TTY @_;
71913cc679Smrg    close TTY;
72913cc679Smrg    system "stty $old";
73913cc679Smrg}
74913cc679Smrg
75913cc679Smrgsub get_reply($) {
76913cc679Smrg    open TTY, "+</dev/tty" or die("Cannot open /dev/tty\n");
77913cc679Smrg    autoflush TTY 1;
78913cc679Smrg    my $old = `stty -g`;
79913cc679Smrg    system "stty raw -echo min 0 time 5";
80913cc679Smrg
81913cc679Smrg    print TTY @_;
82913cc679Smrg    my $reply = <TTY>;
83913cc679Smrg    close TTY;
84913cc679Smrg    system "stty $old";
85913cc679Smrg    if ( defined $reply ) {
86913cc679Smrg        die("^C received\n") if ( "$reply" eq "\003" );
87913cc679Smrg    }
88913cc679Smrg    return $reply;
89913cc679Smrg}
90913cc679Smrg
91913cc679Smrgsub visible($) {
92913cc679Smrg    my $reply = $_[0];
93913cc679Smrg    my $n;
94913cc679Smrg    my $result = "";
95913cc679Smrg    for ( $n = 0 ; $n < length($reply) ; ) {
96913cc679Smrg        my $c = substr( $reply, $n, 1 );
97913cc679Smrg        if ( $c =~ /[[:print:]]/ ) {
98913cc679Smrg            $result .= $c;
99913cc679Smrg        }
100913cc679Smrg        else {
101913cc679Smrg            my $k = ord substr( $reply, $n, 1 );
102913cc679Smrg            if ( ord $k == 0x1b ) {
103913cc679Smrg                $result .= "\\E";
104913cc679Smrg            }
105913cc679Smrg            elsif ( $k == 0x7f ) {
106913cc679Smrg                $result .= "^?";
107913cc679Smrg            }
108913cc679Smrg            elsif ( $k == 32 ) {
109913cc679Smrg                $result .= "\\s";
110913cc679Smrg            }
111913cc679Smrg            elsif ( $k < 32 ) {
112913cc679Smrg                $result .= sprintf( "^%c", $k + 64 );
113913cc679Smrg            }
114913cc679Smrg            elsif ( $k > 128 ) {
115913cc679Smrg                $result .= sprintf( "\\%03o", $k );
116913cc679Smrg            }
117913cc679Smrg            else {
118913cc679Smrg                $result .= chr($k);
119913cc679Smrg            }
120913cc679Smrg        }
121913cc679Smrg        $n += 1;
122913cc679Smrg    }
123913cc679Smrg
124913cc679Smrg    return $result;
125913cc679Smrg}
126913cc679Smrg
127913cc679Smrgsub query_one($) {
128913cc679Smrg    my $name   = shift;
129913cc679Smrg    my $suffix = $suffixes{$name};
130913cc679Smrg    my $prefix = $opt_8 ? "\x90" : "\x1bP";
131913cc679Smrg    my $reply;
132913cc679Smrg    my $n;
133913cc679Smrg    my $st    = $opt_s ? qr/\007/ : ( $opt_8 ? "\x9c" : qr/\x1b\\/ );
134913cc679Smrg    my $DCS   = qr/${prefix}/;
135913cc679Smrg    my $match = qr/${DCS}.*${st}/;
136913cc679Smrg
137913cc679Smrg    $reply = get_reply( $prefix . '$q' . $suffix . $ST );
138913cc679Smrg
139913cc679Smrg    printf "%-10s query{%s}%*s", $name,    #
140913cc679Smrg      &visible($suffix),                   #
141913cc679Smrg      4 - length($suffix), " ";
142913cc679Smrg
143913cc679Smrg    if ( defined $reply ) {
144913cc679Smrg        printf "%2d ", length($reply);
145913cc679Smrg        if ( $reply =~ /${match}/ ) {
146913cc679Smrg
147913cc679Smrg            $reply =~ s/^${DCS}//;
148913cc679Smrg            $reply =~ s/^;//;
149913cc679Smrg            $reply =~ s/${st}$//;
150913cc679Smrg        }
151913cc679Smrg        else {
152913cc679Smrg            printf "? ";
153913cc679Smrg        }
154913cc679Smrg
155913cc679Smrg        printf "{%s}", visible($reply);
156913cc679Smrg    }
157913cc679Smrg    printf "\n";
158913cc679Smrg}
159913cc679Smrg
160913cc679Smrgif ( $#ARGV >= 0 ) {
161913cc679Smrg    while ( $#ARGV >= 0 ) {
162913cc679Smrg        &query_one( shift @ARGV );
163913cc679Smrg    }
164913cc679Smrg}
165913cc679Smrgelse {
166913cc679Smrg    for my $key ( sort keys %suffixes ) {
167913cc679Smrg        &query_one($key);
168913cc679Smrg    }
169913cc679Smrg}
170