From 47c6e415d2e8ab0f020c39cb0d8fa0cb7aafbbfb Mon Sep 17 00:00:00 2001 From: Jeff Quast Date: Mon, 24 Nov 2014 20:17:41 -0800 Subject: Fix failing tests, on OSX at least. Pushing .. --- tools/display-terminalinfo.py | 200 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100755 tools/display-terminalinfo.py (limited to 'tools') diff --git a/tools/display-terminalinfo.py b/tools/display-terminalinfo.py new file mode 100755 index 0000000..b3aca73 --- /dev/null +++ b/tools/display-terminalinfo.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +""" Display known information about our terminal. """ +from __future__ import print_function +import termios +import sys +import os + +BITMAP_IFLAG = { + 'IGNBRK': 'ignore BREAK condition', + 'BRKINT': 'map BREAK to SIGINTR', + 'IGNPAR': 'ignore (discard) parity errors', + 'PARMRK': 'mark parity and framing errors', + 'INPCK': 'enable checking of parity errors', + 'ISTRIP': 'strip 8th bit off chars', + 'INLCR': 'map NL into CR', + 'IGNCR': 'ignore CR', + 'ICRNL': 'map CR to NL (ala CRMOD)', + 'IXON': 'enable output flow control', + 'IXOFF': 'enable input flow control', + 'IXANY': 'any char will restart after stop', + 'IMAXBEL': 'ring bell on input queue full', + 'IUCLC': 'translate upper case to lower case', +} + +BITMAP_OFLAG = { + 'OPOST': 'enable following output processing', + 'ONLCR': 'map NL to CR-NL (ala CRMOD)', + 'OXTABS': 'expand tabs to spaces', + 'ONOEOT': 'discard EOT\'s `^D\' on output)', + 'OCRNL': 'map CR to NL', + 'OLCUC': 'translate lower case to upper case', + 'ONOCR': 'No CR output at column 0', + 'ONLRET': 'NL performs CR function', +} + +BITMAP_CFLAG = { + 'CSIZE': 'character size mask', + 'CS5': '5 bits (pseudo)', + 'CS6': '6 bits', + 'CS7': '7 bits', + 'CS8': '8 bits', + 'CSTOPB': 'send 2 stop bits', + 'CREAD': 'enable receiver', + 'PARENB': 'parity enable', + 'PARODD': 'odd parity, else even', + 'HUPCL': 'hang up on last close', + 'CLOCAL': 'ignore modem status lines', + 'CCTS_OFLOW': 'CTS flow control of output', + 'CRTSCTS': 'same as CCTS_OFLOW', + 'CRTS_IFLOW': 'RTS flow control of input', + 'MDMBUF': 'flow control output via Carrier', +} + +BITMAP_LFLAG = { + 'ECHOKE': 'visual erase for line kill', + 'ECHOE': 'visually erase chars', + 'ECHO': 'enable echoing', + 'ECHONL': 'echo NL even if ECHO is off', + 'ECHOPRT': 'visual erase mode for hardcopy', + 'ECHOCTL': 'echo control chars as ^(Char)', + 'ISIG': 'enable signals INTR, QUIT, [D]SUSP', + 'ICANON': 'canonicalize input lines', + 'ALTWERASE': 'use alternate WERASE algorithm', + 'IEXTEN': 'enable DISCARD and LNEXT', + 'EXTPROC': 'external processing', + 'TOSTOP': 'stop background jobs from output', + 'FLUSHO': 'output being flushed (state)', + 'NOKERNINFO': 'no kernel output from VSTATUS', + 'PENDIN': 'XXX retype pending input (state)', + 'NOFLSH': 'don\'t flush after interrupt', +} + +CTLCHAR_INDEX = { + 'VEOF': 'EOF', + 'VEOL': 'EOL', + 'VEOL2': 'EOL2', + 'VERASE': 'ERASE', + 'VWERASE': 'WERASE', + 'VKILL': 'KILL', + 'VREPRINT': 'REPRINT', + 'VINTR': 'INTR', + 'VQUIT': 'QUIT', + 'VSUSP': 'SUSP', + 'VDSUSP': 'DSUSP', + 'VSTART': 'START', + 'VSTOP': 'STOP', + 'VLNEXT': 'LNEXT', + 'VDISCARD': 'DISCARD', + 'VMIN': '---', + 'VTIME': '---', + 'VSTATUS': 'STATUS', +} + + + +def display_bitmask(kind, bitmap, value): + """ Display all matching bitmask values for ``value`` given ``bitmap``. """ + col1_width = max(map(len, bitmap.keys() + [kind])) + col2_width = 7 + FMT = '{name:>{col1_width}} {value:>{col2_width}} {description}' + print(FMT.format(name=kind, + value='Value', + description='Description', + col1_width=col1_width, + col2_width=col2_width)) + print('{0} {1} {2}'.format('-' * col1_width, + '-' * col2_width, + '-' * max(map(len, bitmap.values())))) + for flag_name, description in bitmap.items(): + try: + bitmask = getattr(termios, flag_name) + bit_val = 'on' if bool(value & bitmask) else 'off' + except AttributeError: + bit_val = 'undef' + print(FMT.format(name=flag_name, + value=bit_val, + description=description, + col1_width=col1_width, + col2_width=col2_width)) + print() + + +def display_ctl_chars(index, cc): + """ Display all control character indicies, names, and values. """ + title = 'Special Character' + col1_width = len(title) + col2_width = max(map(len, index.values())) + FMT = '{idx:<{col1_width}} {name:<{col2_width}} {value}' + print('Special line Characters'.center(40).rstrip()) + print(FMT.format(idx='Index', + name='Name', + value='Value', + col1_width=col1_width, + col2_width=col2_width)) + print('{0} {1} {2}'.format('-' * col1_width, + '-' * col2_width, + '-' * 10)) + for index_name, name in index.items(): + try: + index = getattr(termios, index_name) + value = cc[index] + if value == b'\xff': + value = '_POSIX_VDISABLE' + else: + value = repr(value) + except AttributeError: + value = 'undef' + print(FMT.format(idx=index_name, + name=name, + value=value, + col1_width=col1_width, + col2_width=col2_width)) + print() + + +def display_conf(kind, names, getter): + col1_width = max(map(len, names)) + FMT = '{name:>{col1_width}} {value}' + print(FMT.format(name=kind, + value='value', + col1_width=col1_width)) + print('{0} {1}'.format('-' * col1_width, '-' * 27)) + for name in names: + try: + value = getter(name) + except OSError as err: + value = err + print(FMT.format(name=name, value=value, col1_width=col1_width)) + print() + + +def main(): + fd = sys.stdin.fileno() + + display_conf(kind='pathconf', + names=os.pathconf_names, + getter=lambda name: os.fpathconf(fd, name)) + + (iflag, oflag, cflag, lflag, ispeed, ospeed, cc) = termios.tcgetattr(fd) + display_bitmask(kind='Input Mode', + bitmap=BITMAP_IFLAG, + value=iflag) + display_bitmask(kind='Output Mode', + bitmap=BITMAP_OFLAG, + value=oflag) + display_bitmask(kind='Control Mode', + bitmap=BITMAP_CFLAG, + value=cflag) + display_bitmask(kind='Local Mode', + bitmap=BITMAP_LFLAG, + value=lflag) + display_ctl_chars(index=CTLCHAR_INDEX, + cc=cc) + print('os.isatty({0}) => {1}'.format(fd, os.isatty(fd))) + print('os.ttyname({0}) => {1}'.format(fd, os.ttyname(fd))) + print('os.ctermid() => {0}'.format(os.ttyname(fd))) + + +if __name__ == '__main__': + main() -- cgit v1.2.1