112882Sspwilson2@wisc.edu# Copyright (c) 2011 Advanced Micro Devices, Inc.
212882Sspwilson2@wisc.edu# All rights reserved.
312882Sspwilson2@wisc.edu#
412882Sspwilson2@wisc.edu# Redistribution and use in source and binary forms, with or without
512882Sspwilson2@wisc.edu# modification, are permitted provided that the following conditions are
612882Sspwilson2@wisc.edu# met: redistributions of source code must retain the above copyright
712882Sspwilson2@wisc.edu# notice, this list of conditions and the following disclaimer;
812882Sspwilson2@wisc.edu# redistributions in binary form must reproduce the above copyright
912882Sspwilson2@wisc.edu# notice, this list of conditions and the following disclaimer in the
1012882Sspwilson2@wisc.edu# documentation and/or other materials provided with the distribution;
1112882Sspwilson2@wisc.edu# neither the name of the copyright holders nor the names of its
1212882Sspwilson2@wisc.edu# contributors may be used to endorse or promote products derived from
1312882Sspwilson2@wisc.edu# this software without specific prior written permission.
1412882Sspwilson2@wisc.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1512882Sspwilson2@wisc.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1612882Sspwilson2@wisc.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1712882Sspwilson2@wisc.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1812882Sspwilson2@wisc.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1912882Sspwilson2@wisc.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2012882Sspwilson2@wisc.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2112882Sspwilson2@wisc.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2212882Sspwilson2@wisc.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2312882Sspwilson2@wisc.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2412882Sspwilson2@wisc.edu#
2512882Sspwilson2@wisc.edu# Author: Steve Reinhardt
2612882Sspwilson2@wisc.edu
2712882Sspwilson2@wisc.eduimport sys
2812882Sspwilson2@wisc.eduimport fcntl
2912882Sspwilson2@wisc.eduimport termios
3012882Sspwilson2@wisc.eduimport struct
3112882Sspwilson2@wisc.edu
3212882Sspwilson2@wisc.edu# Intended usage example:
3312882Sspwilson2@wisc.edu#
3412882Sspwilson2@wisc.edu# if force_colors:
3512882Sspwilson2@wisc.edu#    from m5.util.terminal import termcap
3612882Sspwilson2@wisc.edu# elif no_colors:
3712882Sspwilson2@wisc.edu#    from m5.util.terminal import no_termcap as termcap
3812882Sspwilson2@wisc.edu# else:
3912882Sspwilson2@wisc.edu#    from m5.util.terminal import tty_termcap as termcap
4012882Sspwilson2@wisc.edu# print termcap.Blue + "This could be blue!" + termcap.Normal
4112882Sspwilson2@wisc.edu
4212882Sspwilson2@wisc.edu# ANSI color names in index order
4312882Sspwilson2@wisc.educolor_names = "Black Red Green Yellow Blue Magenta Cyan White".split()
4412882Sspwilson2@wisc.edudefault_separator = '='
4512882Sspwilson2@wisc.edu
4612882Sspwilson2@wisc.edu# Character attribute capabilities.  Note that not all terminals
4712882Sspwilson2@wisc.edu# support all of these capabilities, or support them
4812882Sspwilson2@wisc.edu# differently/meaningfully.  For example:
4912882Sspwilson2@wisc.edu#
5012882Sspwilson2@wisc.edu# - In PuTTY (with the default settings), Dim has no effect, Standout
5112882Sspwilson2@wisc.edu#   is the same as Reverse, and Blink does not blink but switches to a
5212882Sspwilson2@wisc.edu#   gray background.
5312882Sspwilson2@wisc.edu#
5412882Sspwilson2@wisc.edu# Please feel free to add information about other terminals here.
5512882Sspwilson2@wisc.edu#
5612882Sspwilson2@wisc.educapability_map = {
5712882Sspwilson2@wisc.edu         'Bold': 'bold',
5812882Sspwilson2@wisc.edu          'Dim': 'dim',
5912882Sspwilson2@wisc.edu        'Blink': 'blink',
6012882Sspwilson2@wisc.edu    'Underline': 'smul',
6112882Sspwilson2@wisc.edu      'Reverse': 'rev',
6212882Sspwilson2@wisc.edu     'Standout': 'smso',
6312882Sspwilson2@wisc.edu       'Normal': 'sgr0'
6412882Sspwilson2@wisc.edu}
6512882Sspwilson2@wisc.edu
6612882Sspwilson2@wisc.educapability_names = capability_map.keys()
6712882Sspwilson2@wisc.edu
6812882Sspwilson2@wisc.edudef null_cap_string(s, *args):
6912882Sspwilson2@wisc.edu    return ''
7012882Sspwilson2@wisc.edu
7112882Sspwilson2@wisc.edutry:
7212882Sspwilson2@wisc.edu    import curses
7312882Sspwilson2@wisc.edu    curses.setupterm()
7412882Sspwilson2@wisc.edu    def cap_string(s, *args):
7512882Sspwilson2@wisc.edu        cap = curses.tigetstr(s)
7612882Sspwilson2@wisc.edu        if cap:
7712882Sspwilson2@wisc.edu            return curses.tparm(cap, *args)
7812882Sspwilson2@wisc.edu        else:
7912882Sspwilson2@wisc.edu            return ''
8012882Sspwilson2@wisc.eduexcept:
8112882Sspwilson2@wisc.edu    cap_string = null_cap_string
8212882Sspwilson2@wisc.edu
8312882Sspwilson2@wisc.educlass ColorStrings(object):
8412882Sspwilson2@wisc.edu    def __init__(self, cap_string):
8512882Sspwilson2@wisc.edu        for i, c in enumerate(color_names):
8612882Sspwilson2@wisc.edu            setattr(self, c, cap_string('setaf', i))
8712882Sspwilson2@wisc.edu        for name, cap in capability_map.iteritems():
8812882Sspwilson2@wisc.edu            setattr(self, name, cap_string(cap))
8912882Sspwilson2@wisc.edu
9012882Sspwilson2@wisc.edutermcap = ColorStrings(cap_string)
9112882Sspwilson2@wisc.eduno_termcap = ColorStrings(null_cap_string)
9212882Sspwilson2@wisc.edu
9312882Sspwilson2@wisc.eduif sys.stdout.isatty():
9412882Sspwilson2@wisc.edu    tty_termcap = termcap
9512882Sspwilson2@wisc.eduelse:
9612882Sspwilson2@wisc.edu    tty_termcap = no_termcap
9712882Sspwilson2@wisc.edu
9812882Sspwilson2@wisc.edudef get_termcap(use_colors = None):
9912882Sspwilson2@wisc.edu    if use_colors:
10012882Sspwilson2@wisc.edu        return termcap
10112882Sspwilson2@wisc.edu    elif use_colors is None:
10212882Sspwilson2@wisc.edu        # option unspecified; default behavior is to use colors iff isatty
10312882Sspwilson2@wisc.edu        return tty_termcap
10412882Sspwilson2@wisc.edu    else:
10512882Sspwilson2@wisc.edu        return no_termcap
10612882Sspwilson2@wisc.edu
10712882Sspwilson2@wisc.edudef terminal_size():
10812882Sspwilson2@wisc.edu    '''Return the (width, heigth) of the terminal screen.'''
10913788Sjason@lowepower.com    try:
11013788Sjason@lowepower.com        h, w, hp, wp = struct.unpack('HHHH',
11113788Sjason@lowepower.com            fcntl.ioctl(0, termios.TIOCGWINSZ,
11213788Sjason@lowepower.com            struct.pack('HHHH', 0, 0, 0, 0)))
11313788Sjason@lowepower.com        return w, h
11413788Sjason@lowepower.com    except IOError:
11513788Sjason@lowepower.com        # It's possible that in sandboxed environments the above ioctl is not
11613788Sjason@lowepower.com        # allowed (e.g., some jenkins setups)
11713788Sjason@lowepower.com        return 80, 24
11813788Sjason@lowepower.com
11912882Sspwilson2@wisc.edu
12012882Sspwilson2@wisc.edudef separator(char=default_separator, color=None):
12112882Sspwilson2@wisc.edu    '''
12212882Sspwilson2@wisc.edu    Return a separator of the given character that is the length of the full
12312882Sspwilson2@wisc.edu    width of the terminal screen.
12412882Sspwilson2@wisc.edu    '''
12512882Sspwilson2@wisc.edu    (w, h) = terminal_size()
12612882Sspwilson2@wisc.edu    if color:
12712882Sspwilson2@wisc.edu        return color + char*w + termcap.Normal
12812882Sspwilson2@wisc.edu    else:
12912882Sspwilson2@wisc.edu        return char*w
13012882Sspwilson2@wisc.edu
13112882Sspwilson2@wisc.edudef insert_separator(inside, char=default_separator,
13212882Sspwilson2@wisc.edu                     min_barrier=3, color=None):
13312882Sspwilson2@wisc.edu    '''
13412882Sspwilson2@wisc.edu    Place the given string inside of the separator. If it does not fit inside,
13512882Sspwilson2@wisc.edu    expand the separator to fit it with at least min_barrier.
13612882Sspwilson2@wisc.edu
13712882Sspwilson2@wisc.edu    .. seealso:: :func:`separator`
13812882Sspwilson2@wisc.edu    '''
13912882Sspwilson2@wisc.edu    # Use a bytearray so it's efficient to manipulate
14012882Sspwilson2@wisc.edu    string = bytearray(separator(char, color=color))
14112882Sspwilson2@wisc.edu
14212882Sspwilson2@wisc.edu    # Check if we can fit inside with at least min_barrier.
14312882Sspwilson2@wisc.edu    gap = (len(string) - len(inside)) - min_barrier * 2
14412882Sspwilson2@wisc.edu    if gap > 0:
14512882Sspwilson2@wisc.edu        # We'll need to expand the string to fit us.
14612882Sspwilson2@wisc.edu        string.extend([ char for _ in range(-gap)])
14712882Sspwilson2@wisc.edu    # Emplace inside
14812882Sspwilson2@wisc.edu    middle = ((len(string)-1)/2)
14912882Sspwilson2@wisc.edu    start_idx = middle - len(inside)/2
15012882Sspwilson2@wisc.edu    string[start_idx:len(inside)+start_idx] = inside
15112882Sspwilson2@wisc.edu    return str(string)
15212882Sspwilson2@wisc.edu
15312882Sspwilson2@wisc.edu
15412882Sspwilson2@wisc.eduif __name__ == '__main__':
15512882Sspwilson2@wisc.edu    def test_termcap(obj):
15612882Sspwilson2@wisc.edu        for c_name in color_names:
15712882Sspwilson2@wisc.edu            c_str = getattr(obj, c_name)
15812882Sspwilson2@wisc.edu            print c_str + c_name + obj.Normal
15912882Sspwilson2@wisc.edu            for attr_name in capability_names:
16012882Sspwilson2@wisc.edu                if attr_name == 'Normal':
16112882Sspwilson2@wisc.edu                    continue
16212882Sspwilson2@wisc.edu                attr_str = getattr(obj, attr_name)
16312882Sspwilson2@wisc.edu                print attr_str + c_str + attr_name + " " + c_name + obj.Normal
16412882Sspwilson2@wisc.edu            print obj.Bold + obj.Underline + \
16512882Sspwilson2@wisc.edu                  c_name + "Bold Underline " + c_str + obj.Normal
16612882Sspwilson2@wisc.edu
16712882Sspwilson2@wisc.edu    print "=== termcap enabled ==="
16812882Sspwilson2@wisc.edu    test_termcap(termcap)
16912882Sspwilson2@wisc.edu    print termcap.Normal
17012882Sspwilson2@wisc.edu    print "=== termcap disabled ==="
17112882Sspwilson2@wisc.edu    test_termcap(no_termcap)
172