xref: /rk3399_rockchip-uboot/tools/patman/terminal.py (revision 8b4919ed29f51075e85a7358db75b66a226d5b1e)
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
11bbd01435SSimon Glassimport os
12bbd01435SSimon Glassimport sys
13bbd01435SSimon Glass
14bbd01435SSimon Glass# Selection of when we want our output to be colored
15bbd01435SSimon GlassCOLOR_IF_TERMINAL, COLOR_ALWAYS, COLOR_NEVER = range(3)
16bbd01435SSimon Glass
173c6c0f81SSimon Glass# Initially, we are set up to print to the terminal
183c6c0f81SSimon Glassprint_test_mode = False
193c6c0f81SSimon Glassprint_test_list = []
203c6c0f81SSimon Glass
213c6c0f81SSimon Glassclass PrintLine:
223c6c0f81SSimon Glass    """A line of text output
233c6c0f81SSimon Glass
243c6c0f81SSimon Glass    Members:
253c6c0f81SSimon Glass        text: Text line that was printed
263c6c0f81SSimon Glass        newline: True to output a newline after the text
273c6c0f81SSimon Glass        colour: Text colour to use
283c6c0f81SSimon Glass    """
293c6c0f81SSimon Glass    def __init__(self, text, newline, colour):
303c6c0f81SSimon Glass        self.text = text
313c6c0f81SSimon Glass        self.newline = newline
323c6c0f81SSimon Glass        self.colour = colour
333c6c0f81SSimon Glass
343c6c0f81SSimon Glass    def __str__(self):
353c6c0f81SSimon Glass        return 'newline=%s, colour=%s, text=%s' % (self.newline, self.colour,
363c6c0f81SSimon Glass                self.text)
373c6c0f81SSimon Glass
383c6c0f81SSimon Glassdef Print(text='', newline=True, colour=None):
393c6c0f81SSimon Glass    """Handle a line of output to the terminal.
403c6c0f81SSimon Glass
413c6c0f81SSimon Glass    In test mode this is recorded in a list. Otherwise it is output to the
423c6c0f81SSimon Glass    terminal.
433c6c0f81SSimon Glass
443c6c0f81SSimon Glass    Args:
453c6c0f81SSimon Glass        text: Text to print
463c6c0f81SSimon Glass        newline: True to add a new line at the end of the text
473c6c0f81SSimon Glass        colour: Colour to use for the text
483c6c0f81SSimon Glass    """
493c6c0f81SSimon Glass    if print_test_mode:
503c6c0f81SSimon Glass        print_test_list.append(PrintLine(text, newline, colour))
513c6c0f81SSimon Glass    else:
523c6c0f81SSimon Glass        if colour:
533c6c0f81SSimon Glass            col = Color()
543c6c0f81SSimon Glass            text = col.Color(colour, text)
553c6c0f81SSimon Glass        print text,
563c6c0f81SSimon Glass        if newline:
573c6c0f81SSimon Glass            print
58*8b4919edSSimon Glass        else:
59*8b4919edSSimon Glass            sys.stdout.flush()
603c6c0f81SSimon Glass
613c6c0f81SSimon Glassdef SetPrintTestMode():
623c6c0f81SSimon Glass    """Go into test mode, where all printing is recorded"""
633c6c0f81SSimon Glass    global print_test_mode
643c6c0f81SSimon Glass
653c6c0f81SSimon Glass    print_test_mode = True
663c6c0f81SSimon Glass
673c6c0f81SSimon Glassdef GetPrintTestLines():
683c6c0f81SSimon Glass    """Get a list of all lines output through Print()
693c6c0f81SSimon Glass
703c6c0f81SSimon Glass    Returns:
713c6c0f81SSimon Glass        A list of PrintLine objects
723c6c0f81SSimon Glass    """
733c6c0f81SSimon Glass    global print_test_list
743c6c0f81SSimon Glass
753c6c0f81SSimon Glass    ret = print_test_list
763c6c0f81SSimon Glass    print_test_list = []
773c6c0f81SSimon Glass    return ret
783c6c0f81SSimon Glass
793c6c0f81SSimon Glassdef EchoPrintTestLines():
803c6c0f81SSimon Glass    """Print out the text lines collected"""
813c6c0f81SSimon Glass    for line in print_test_list:
823c6c0f81SSimon Glass        if line.colour:
833c6c0f81SSimon Glass            col = Color()
843c6c0f81SSimon Glass            print col.Color(line.colour, line.text),
853c6c0f81SSimon Glass        else:
863c6c0f81SSimon Glass            print line.text,
873c6c0f81SSimon Glass        if line.newline:
883c6c0f81SSimon Glass            print
893c6c0f81SSimon Glass
903c6c0f81SSimon Glass
910d24de9dSSimon Glassclass Color(object):
920d24de9dSSimon Glass    """Conditionally wraps text in ANSI color escape sequences."""
930d24de9dSSimon Glass    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
940d24de9dSSimon Glass    BOLD = -1
9543bca004SSimon Glass    BRIGHT_START = '\033[1;%dm'
9643bca004SSimon Glass    NORMAL_START = '\033[22;%dm'
970d24de9dSSimon Glass    BOLD_START = '\033[1m'
980d24de9dSSimon Glass    RESET = '\033[0m'
990d24de9dSSimon Glass
100bbd01435SSimon Glass    def __init__(self, colored=COLOR_IF_TERMINAL):
1010d24de9dSSimon Glass        """Create a new Color object, optionally disabling color output.
1020d24de9dSSimon Glass
1030d24de9dSSimon Glass        Args:
1040d24de9dSSimon Glass          enabled: True if color output should be enabled. If False then this
1050d24de9dSSimon Glass            class will not add color codes at all.
1060d24de9dSSimon Glass        """
107e752edcbSSimon Glass        try:
108bbd01435SSimon Glass            self._enabled = (colored == COLOR_ALWAYS or
109e752edcbSSimon Glass                    (colored == COLOR_IF_TERMINAL and
110e752edcbSSimon Glass                     os.isatty(sys.stdout.fileno())))
111e752edcbSSimon Glass        except:
112e752edcbSSimon Glass            self._enabled = False
1130d24de9dSSimon Glass
11443bca004SSimon Glass    def Start(self, color, bright=True):
1150d24de9dSSimon Glass        """Returns a start color code.
1160d24de9dSSimon Glass
1170d24de9dSSimon Glass        Args:
1180d24de9dSSimon Glass          color: Color to use, .e.g BLACK, RED, etc.
1190d24de9dSSimon Glass
1200d24de9dSSimon Glass        Returns:
1216ba5737fSSimon Glass          If color is enabled, returns an ANSI sequence to start the given
1226ba5737fSSimon Glass          color, otherwise returns empty string
1230d24de9dSSimon Glass        """
1240d24de9dSSimon Glass        if self._enabled:
12543bca004SSimon Glass            base = self.BRIGHT_START if bright else self.NORMAL_START
12643bca004SSimon Glass            return base % (color + 30)
1270d24de9dSSimon Glass        return ''
1280d24de9dSSimon Glass
1290d24de9dSSimon Glass    def Stop(self):
1300d24de9dSSimon Glass        """Retruns a stop color code.
1310d24de9dSSimon Glass
1320d24de9dSSimon Glass        Returns:
1336ba5737fSSimon Glass          If color is enabled, returns an ANSI color reset sequence,
1346ba5737fSSimon Glass          otherwise returns empty string
1350d24de9dSSimon Glass        """
1360d24de9dSSimon Glass        if self._enabled:
1370d24de9dSSimon Glass            return self.RESET
1380d24de9dSSimon Glass        return ''
1390d24de9dSSimon Glass
14043bca004SSimon Glass    def Color(self, color, text, bright=True):
1410d24de9dSSimon Glass        """Returns text with conditionally added color escape sequences.
1420d24de9dSSimon Glass
1430d24de9dSSimon Glass        Keyword arguments:
1446ba5737fSSimon Glass          color: Text color -- one of the color constants defined in this
1456ba5737fSSimon Glass                  class.
1460d24de9dSSimon Glass          text: The text to color.
1470d24de9dSSimon Glass
1480d24de9dSSimon Glass        Returns:
1490d24de9dSSimon Glass          If self._enabled is False, returns the original text. If it's True,
1506ba5737fSSimon Glass          returns text with color escape sequences based on the value of
1516ba5737fSSimon Glass          color.
1520d24de9dSSimon Glass        """
1530d24de9dSSimon Glass        if not self._enabled:
1540d24de9dSSimon Glass            return text
1550d24de9dSSimon Glass        if color == self.BOLD:
1560d24de9dSSimon Glass            start = self.BOLD_START
1570d24de9dSSimon Glass        else:
15843bca004SSimon Glass            base = self.BRIGHT_START if bright else self.NORMAL_START
15943bca004SSimon Glass            start = base % (color + 30)
1600d24de9dSSimon Glass        return start + text + self.RESET
161