xref: /rk3399_rockchip-uboot/tools/patman/terminal.py (revision 79493609c5300be6cc555ab8bd38971360b381f6)
10d24de9dSSimon Glass# Copyright (c) 2011 The Chromium OS Authors.
20d24de9dSSimon Glass#
31a459660SWolfgang Denk# SPDX-License-Identifier:	GPL-2.0+
40d24de9dSSimon Glass#
50d24de9dSSimon Glass
60d24de9dSSimon Glass"""Terminal utilities
70d24de9dSSimon Glass
80d24de9dSSimon GlassThis module handles terminal interaction including ANSI color codes.
90d24de9dSSimon Glass"""
100d24de9dSSimon Glass
11*a920a17bSPaul Burtonfrom __future__ import print_function
12*a920a17bSPaul Burton
13bbd01435SSimon Glassimport os
14bbd01435SSimon Glassimport sys
15bbd01435SSimon Glass
16bbd01435SSimon Glass# Selection of when we want our output to be colored
17bbd01435SSimon GlassCOLOR_IF_TERMINAL, COLOR_ALWAYS, COLOR_NEVER = range(3)
18bbd01435SSimon Glass
193c6c0f81SSimon Glass# Initially, we are set up to print to the terminal
203c6c0f81SSimon Glassprint_test_mode = False
213c6c0f81SSimon Glassprint_test_list = []
223c6c0f81SSimon Glass
233c6c0f81SSimon Glassclass PrintLine:
243c6c0f81SSimon Glass    """A line of text output
253c6c0f81SSimon Glass
263c6c0f81SSimon Glass    Members:
273c6c0f81SSimon Glass        text: Text line that was printed
283c6c0f81SSimon Glass        newline: True to output a newline after the text
293c6c0f81SSimon Glass        colour: Text colour to use
303c6c0f81SSimon Glass    """
313c6c0f81SSimon Glass    def __init__(self, text, newline, colour):
323c6c0f81SSimon Glass        self.text = text
333c6c0f81SSimon Glass        self.newline = newline
343c6c0f81SSimon Glass        self.colour = colour
353c6c0f81SSimon Glass
363c6c0f81SSimon Glass    def __str__(self):
373c6c0f81SSimon Glass        return 'newline=%s, colour=%s, text=%s' % (self.newline, self.colour,
383c6c0f81SSimon Glass                self.text)
393c6c0f81SSimon Glass
403c6c0f81SSimon Glassdef Print(text='', newline=True, colour=None):
413c6c0f81SSimon Glass    """Handle a line of output to the terminal.
423c6c0f81SSimon Glass
433c6c0f81SSimon Glass    In test mode this is recorded in a list. Otherwise it is output to the
443c6c0f81SSimon Glass    terminal.
453c6c0f81SSimon Glass
463c6c0f81SSimon Glass    Args:
473c6c0f81SSimon Glass        text: Text to print
483c6c0f81SSimon Glass        newline: True to add a new line at the end of the text
493c6c0f81SSimon Glass        colour: Colour to use for the text
503c6c0f81SSimon Glass    """
513c6c0f81SSimon Glass    if print_test_mode:
523c6c0f81SSimon Glass        print_test_list.append(PrintLine(text, newline, colour))
533c6c0f81SSimon Glass    else:
543c6c0f81SSimon Glass        if colour:
553c6c0f81SSimon Glass            col = Color()
563c6c0f81SSimon Glass            text = col.Color(colour, text)
57*a920a17bSPaul Burton        print(text, end='')
583c6c0f81SSimon Glass        if newline:
59*a920a17bSPaul Burton            print()
608b4919edSSimon Glass        else:
618b4919edSSimon Glass            sys.stdout.flush()
623c6c0f81SSimon Glass
633c6c0f81SSimon Glassdef SetPrintTestMode():
643c6c0f81SSimon Glass    """Go into test mode, where all printing is recorded"""
653c6c0f81SSimon Glass    global print_test_mode
663c6c0f81SSimon Glass
673c6c0f81SSimon Glass    print_test_mode = True
683c6c0f81SSimon Glass
693c6c0f81SSimon Glassdef GetPrintTestLines():
703c6c0f81SSimon Glass    """Get a list of all lines output through Print()
713c6c0f81SSimon Glass
723c6c0f81SSimon Glass    Returns:
733c6c0f81SSimon Glass        A list of PrintLine objects
743c6c0f81SSimon Glass    """
753c6c0f81SSimon Glass    global print_test_list
763c6c0f81SSimon Glass
773c6c0f81SSimon Glass    ret = print_test_list
783c6c0f81SSimon Glass    print_test_list = []
793c6c0f81SSimon Glass    return ret
803c6c0f81SSimon Glass
813c6c0f81SSimon Glassdef EchoPrintTestLines():
823c6c0f81SSimon Glass    """Print out the text lines collected"""
833c6c0f81SSimon Glass    for line in print_test_list:
843c6c0f81SSimon Glass        if line.colour:
853c6c0f81SSimon Glass            col = Color()
86*a920a17bSPaul Burton            print(col.Color(line.colour, line.text), end='')
873c6c0f81SSimon Glass        else:
88*a920a17bSPaul Burton            print(line.text, end='')
893c6c0f81SSimon Glass        if line.newline:
90*a920a17bSPaul Burton            print()
913c6c0f81SSimon Glass
923c6c0f81SSimon Glass
930d24de9dSSimon Glassclass Color(object):
940d24de9dSSimon Glass    """Conditionally wraps text in ANSI color escape sequences."""
950d24de9dSSimon Glass    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
960d24de9dSSimon Glass    BOLD = -1
9743bca004SSimon Glass    BRIGHT_START = '\033[1;%dm'
9843bca004SSimon Glass    NORMAL_START = '\033[22;%dm'
990d24de9dSSimon Glass    BOLD_START = '\033[1m'
1000d24de9dSSimon Glass    RESET = '\033[0m'
1010d24de9dSSimon Glass
102bbd01435SSimon Glass    def __init__(self, colored=COLOR_IF_TERMINAL):
1030d24de9dSSimon Glass        """Create a new Color object, optionally disabling color output.
1040d24de9dSSimon Glass
1050d24de9dSSimon Glass        Args:
1060d24de9dSSimon Glass          enabled: True if color output should be enabled. If False then this
1070d24de9dSSimon Glass            class will not add color codes at all.
1080d24de9dSSimon Glass        """
109e752edcbSSimon Glass        try:
110bbd01435SSimon Glass            self._enabled = (colored == COLOR_ALWAYS or
111e752edcbSSimon Glass                    (colored == COLOR_IF_TERMINAL and
112e752edcbSSimon Glass                     os.isatty(sys.stdout.fileno())))
113e752edcbSSimon Glass        except:
114e752edcbSSimon Glass            self._enabled = False
1150d24de9dSSimon Glass
11643bca004SSimon Glass    def Start(self, color, bright=True):
1170d24de9dSSimon Glass        """Returns a start color code.
1180d24de9dSSimon Glass
1190d24de9dSSimon Glass        Args:
1200d24de9dSSimon Glass          color: Color to use, .e.g BLACK, RED, etc.
1210d24de9dSSimon Glass
1220d24de9dSSimon Glass        Returns:
1236ba5737fSSimon Glass          If color is enabled, returns an ANSI sequence to start the given
1246ba5737fSSimon Glass          color, otherwise returns empty string
1250d24de9dSSimon Glass        """
1260d24de9dSSimon Glass        if self._enabled:
12743bca004SSimon Glass            base = self.BRIGHT_START if bright else self.NORMAL_START
12843bca004SSimon Glass            return base % (color + 30)
1290d24de9dSSimon Glass        return ''
1300d24de9dSSimon Glass
1310d24de9dSSimon Glass    def Stop(self):
1320d24de9dSSimon Glass        """Retruns a stop color code.
1330d24de9dSSimon Glass
1340d24de9dSSimon Glass        Returns:
1356ba5737fSSimon Glass          If color is enabled, returns an ANSI color reset sequence,
1366ba5737fSSimon Glass          otherwise returns empty string
1370d24de9dSSimon Glass        """
1380d24de9dSSimon Glass        if self._enabled:
1390d24de9dSSimon Glass            return self.RESET
1400d24de9dSSimon Glass        return ''
1410d24de9dSSimon Glass
14243bca004SSimon Glass    def Color(self, color, text, bright=True):
1430d24de9dSSimon Glass        """Returns text with conditionally added color escape sequences.
1440d24de9dSSimon Glass
1450d24de9dSSimon Glass        Keyword arguments:
1466ba5737fSSimon Glass          color: Text color -- one of the color constants defined in this
1476ba5737fSSimon Glass                  class.
1480d24de9dSSimon Glass          text: The text to color.
1490d24de9dSSimon Glass
1500d24de9dSSimon Glass        Returns:
1510d24de9dSSimon Glass          If self._enabled is False, returns the original text. If it's True,
1526ba5737fSSimon Glass          returns text with color escape sequences based on the value of
1536ba5737fSSimon Glass          color.
1540d24de9dSSimon Glass        """
1550d24de9dSSimon Glass        if not self._enabled:
1560d24de9dSSimon Glass            return text
1570d24de9dSSimon Glass        if color == self.BOLD:
1580d24de9dSSimon Glass            start = self.BOLD_START
1590d24de9dSSimon Glass        else:
16043bca004SSimon Glass            base = self.BRIGHT_START if bright else self.NORMAL_START
16143bca004SSimon Glass            start = base % (color + 30)
1620d24de9dSSimon Glass        return start + text + self.RESET
163