From 07ce662bd212246e20d85de1e4f3d537565449d1 Mon Sep 17 00:00:00 2001 From: Sean Wilson Date: Thu, 3 Aug 2017 11:28:49 -0500 Subject: tests,ext: Add a new testing library proposal The new test library is split into two parts: The framework which resides in ext/, and the gem5 helping components in /tests/gem5. Change-Id: Ib4f3ae8d7eb96a7306335a3e739b7e8041aa99b9 Signed-off-by: Sean Wilson Reviewed-on: https://gem5-review.googlesource.com/4421 Reviewed-by: Giacomo Travaglini Maintainer: Jason Lowe-Power --- ext/testlib/terminal.py | 165 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 ext/testlib/terminal.py (limited to 'ext/testlib/terminal.py') diff --git a/ext/testlib/terminal.py b/ext/testlib/terminal.py new file mode 100644 index 000000000..3afbb42a2 --- /dev/null +++ b/ext/testlib/terminal.py @@ -0,0 +1,165 @@ +# Copyright (c) 2011 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: Steve Reinhardt + +import sys +import fcntl +import termios +import struct + +# Intended usage example: +# +# if force_colors: +# from m5.util.terminal import termcap +# elif no_colors: +# from m5.util.terminal import no_termcap as termcap +# else: +# from m5.util.terminal import tty_termcap as termcap +# print termcap.Blue + "This could be blue!" + termcap.Normal + +# ANSI color names in index order +color_names = "Black Red Green Yellow Blue Magenta Cyan White".split() +default_separator = '=' + +# Character attribute capabilities. Note that not all terminals +# support all of these capabilities, or support them +# differently/meaningfully. For example: +# +# - In PuTTY (with the default settings), Dim has no effect, Standout +# is the same as Reverse, and Blink does not blink but switches to a +# gray background. +# +# Please feel free to add information about other terminals here. +# +capability_map = { + 'Bold': 'bold', + 'Dim': 'dim', + 'Blink': 'blink', + 'Underline': 'smul', + 'Reverse': 'rev', + 'Standout': 'smso', + 'Normal': 'sgr0' +} + +capability_names = capability_map.keys() + +def null_cap_string(s, *args): + return '' + +try: + import curses + curses.setupterm() + def cap_string(s, *args): + cap = curses.tigetstr(s) + if cap: + return curses.tparm(cap, *args) + else: + return '' +except: + cap_string = null_cap_string + +class ColorStrings(object): + def __init__(self, cap_string): + for i, c in enumerate(color_names): + setattr(self, c, cap_string('setaf', i)) + for name, cap in capability_map.iteritems(): + setattr(self, name, cap_string(cap)) + +termcap = ColorStrings(cap_string) +no_termcap = ColorStrings(null_cap_string) + +if sys.stdout.isatty(): + tty_termcap = termcap +else: + tty_termcap = no_termcap + +def get_termcap(use_colors = None): + if use_colors: + return termcap + elif use_colors is None: + # option unspecified; default behavior is to use colors iff isatty + return tty_termcap + else: + return no_termcap + +def terminal_size(): + '''Return the (width, heigth) of the terminal screen.''' + h, w, hp, wp = struct.unpack('HHHH', + fcntl.ioctl(0, termios.TIOCGWINSZ, + struct.pack('HHHH', 0, 0, 0, 0))) + return w, h + +def separator(char=default_separator, color=None): + ''' + Return a separator of the given character that is the length of the full + width of the terminal screen. + ''' + (w, h) = terminal_size() + if color: + return color + char*w + termcap.Normal + else: + return char*w + +def insert_separator(inside, char=default_separator, + min_barrier=3, color=None): + ''' + Place the given string inside of the separator. If it does not fit inside, + expand the separator to fit it with at least min_barrier. + + .. seealso:: :func:`separator` + ''' + # Use a bytearray so it's efficient to manipulate + string = bytearray(separator(char, color=color)) + + # Check if we can fit inside with at least min_barrier. + gap = (len(string) - len(inside)) - min_barrier * 2 + if gap > 0: + # We'll need to expand the string to fit us. + string.extend([ char for _ in range(-gap)]) + # Emplace inside + middle = ((len(string)-1)/2) + start_idx = middle - len(inside)/2 + string[start_idx:len(inside)+start_idx] = inside + return str(string) + + +if __name__ == '__main__': + def test_termcap(obj): + for c_name in color_names: + c_str = getattr(obj, c_name) + print c_str + c_name + obj.Normal + for attr_name in capability_names: + if attr_name == 'Normal': + continue + attr_str = getattr(obj, attr_name) + print attr_str + c_str + attr_name + " " + c_name + obj.Normal + print obj.Bold + obj.Underline + \ + c_name + "Bold Underline " + c_str + obj.Normal + + print "=== termcap enabled ===" + test_termcap(termcap) + print termcap.Normal + print "=== termcap disabled ===" + test_termcap(no_termcap) -- cgit v1.2.3