xref: /rk3399_rockchip-uboot/tools/patman/terminal.py (revision 3c6c0f81bf3a2edfe4240bf0a3eb0e0c75140ac5)
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
17*3c6c0f81SSimon Glass# Initially, we are set up to print to the terminal
18*3c6c0f81SSimon Glassprint_test_mode = False
19*3c6c0f81SSimon Glassprint_test_list = []
20*3c6c0f81SSimon Glass
21*3c6c0f81SSimon Glassclass PrintLine:
22*3c6c0f81SSimon Glass    """A line of text output
23*3c6c0f81SSimon Glass
24*3c6c0f81SSimon Glass    Members:
25*3c6c0f81SSimon Glass        text: Text line that was printed
26*3c6c0f81SSimon Glass        newline: True to output a newline after the text
27*3c6c0f81SSimon Glass        colour: Text colour to use
28*3c6c0f81SSimon Glass    """
29*3c6c0f81SSimon Glass    def __init__(self, text, newline, colour):
30*3c6c0f81SSimon Glass        self.text = text
31*3c6c0f81SSimon Glass        self.newline = newline
32*3c6c0f81SSimon Glass        self.colour = colour
33*3c6c0f81SSimon Glass
34*3c6c0f81SSimon Glass    def __str__(self):
35*3c6c0f81SSimon Glass        return 'newline=%s, colour=%s, text=%s' % (self.newline, self.colour,
36*3c6c0f81SSimon Glass                self.text)
37*3c6c0f81SSimon Glass
38*3c6c0f81SSimon Glassdef Print(text='', newline=True, colour=None):
39*3c6c0f81SSimon Glass    """Handle a line of output to the terminal.
40*3c6c0f81SSimon Glass
41*3c6c0f81SSimon Glass    In test mode this is recorded in a list. Otherwise it is output to the
42*3c6c0f81SSimon Glass    terminal.
43*3c6c0f81SSimon Glass
44*3c6c0f81SSimon Glass    Args:
45*3c6c0f81SSimon Glass        text: Text to print
46*3c6c0f81SSimon Glass        newline: True to add a new line at the end of the text
47*3c6c0f81SSimon Glass        colour: Colour to use for the text
48*3c6c0f81SSimon Glass    """
49*3c6c0f81SSimon Glass    if print_test_mode:
50*3c6c0f81SSimon Glass        print_test_list.append(PrintLine(text, newline, colour))
51*3c6c0f81SSimon Glass    else:
52*3c6c0f81SSimon Glass        if colour:
53*3c6c0f81SSimon Glass            col = Color()
54*3c6c0f81SSimon Glass            text = col.Color(colour, text)
55*3c6c0f81SSimon Glass        print text,
56*3c6c0f81SSimon Glass        if newline:
57*3c6c0f81SSimon Glass            print
58*3c6c0f81SSimon Glass
59*3c6c0f81SSimon Glassdef SetPrintTestMode():
60*3c6c0f81SSimon Glass    """Go into test mode, where all printing is recorded"""
61*3c6c0f81SSimon Glass    global print_test_mode
62*3c6c0f81SSimon Glass
63*3c6c0f81SSimon Glass    print_test_mode = True
64*3c6c0f81SSimon Glass
65*3c6c0f81SSimon Glassdef GetPrintTestLines():
66*3c6c0f81SSimon Glass    """Get a list of all lines output through Print()
67*3c6c0f81SSimon Glass
68*3c6c0f81SSimon Glass    Returns:
69*3c6c0f81SSimon Glass        A list of PrintLine objects
70*3c6c0f81SSimon Glass    """
71*3c6c0f81SSimon Glass    global print_test_list
72*3c6c0f81SSimon Glass
73*3c6c0f81SSimon Glass    ret = print_test_list
74*3c6c0f81SSimon Glass    print_test_list = []
75*3c6c0f81SSimon Glass    return ret
76*3c6c0f81SSimon Glass
77*3c6c0f81SSimon Glassdef EchoPrintTestLines():
78*3c6c0f81SSimon Glass    """Print out the text lines collected"""
79*3c6c0f81SSimon Glass    for line in print_test_list:
80*3c6c0f81SSimon Glass        if line.colour:
81*3c6c0f81SSimon Glass            col = Color()
82*3c6c0f81SSimon Glass            print col.Color(line.colour, line.text),
83*3c6c0f81SSimon Glass        else:
84*3c6c0f81SSimon Glass            print line.text,
85*3c6c0f81SSimon Glass        if line.newline:
86*3c6c0f81SSimon Glass            print
87*3c6c0f81SSimon Glass
88*3c6c0f81SSimon Glass
890d24de9dSSimon Glassclass Color(object):
900d24de9dSSimon Glass    """Conditionally wraps text in ANSI color escape sequences."""
910d24de9dSSimon Glass    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
920d24de9dSSimon Glass    BOLD = -1
9343bca004SSimon Glass    BRIGHT_START = '\033[1;%dm'
9443bca004SSimon Glass    NORMAL_START = '\033[22;%dm'
950d24de9dSSimon Glass    BOLD_START = '\033[1m'
960d24de9dSSimon Glass    RESET = '\033[0m'
970d24de9dSSimon Glass
98bbd01435SSimon Glass    def __init__(self, colored=COLOR_IF_TERMINAL):
990d24de9dSSimon Glass        """Create a new Color object, optionally disabling color output.
1000d24de9dSSimon Glass
1010d24de9dSSimon Glass        Args:
1020d24de9dSSimon Glass          enabled: True if color output should be enabled. If False then this
1030d24de9dSSimon Glass            class will not add color codes at all.
1040d24de9dSSimon Glass        """
105e752edcbSSimon Glass        try:
106bbd01435SSimon Glass            self._enabled = (colored == COLOR_ALWAYS or
107e752edcbSSimon Glass                    (colored == COLOR_IF_TERMINAL and
108e752edcbSSimon Glass                     os.isatty(sys.stdout.fileno())))
109e752edcbSSimon Glass        except:
110e752edcbSSimon Glass            self._enabled = False
1110d24de9dSSimon Glass
11243bca004SSimon Glass    def Start(self, color, bright=True):
1130d24de9dSSimon Glass        """Returns a start color code.
1140d24de9dSSimon Glass
1150d24de9dSSimon Glass        Args:
1160d24de9dSSimon Glass          color: Color to use, .e.g BLACK, RED, etc.
1170d24de9dSSimon Glass
1180d24de9dSSimon Glass        Returns:
1196ba5737fSSimon Glass          If color is enabled, returns an ANSI sequence to start the given
1206ba5737fSSimon Glass          color, otherwise returns empty string
1210d24de9dSSimon Glass        """
1220d24de9dSSimon Glass        if self._enabled:
12343bca004SSimon Glass            base = self.BRIGHT_START if bright else self.NORMAL_START
12443bca004SSimon Glass            return base % (color + 30)
1250d24de9dSSimon Glass        return ''
1260d24de9dSSimon Glass
1270d24de9dSSimon Glass    def Stop(self):
1280d24de9dSSimon Glass        """Retruns a stop color code.
1290d24de9dSSimon Glass
1300d24de9dSSimon Glass        Returns:
1316ba5737fSSimon Glass          If color is enabled, returns an ANSI color reset sequence,
1326ba5737fSSimon Glass          otherwise returns empty string
1330d24de9dSSimon Glass        """
1340d24de9dSSimon Glass        if self._enabled:
1350d24de9dSSimon Glass            return self.RESET
1360d24de9dSSimon Glass        return ''
1370d24de9dSSimon Glass
13843bca004SSimon Glass    def Color(self, color, text, bright=True):
1390d24de9dSSimon Glass        """Returns text with conditionally added color escape sequences.
1400d24de9dSSimon Glass
1410d24de9dSSimon Glass        Keyword arguments:
1426ba5737fSSimon Glass          color: Text color -- one of the color constants defined in this
1436ba5737fSSimon Glass                  class.
1440d24de9dSSimon Glass          text: The text to color.
1450d24de9dSSimon Glass
1460d24de9dSSimon Glass        Returns:
1470d24de9dSSimon Glass          If self._enabled is False, returns the original text. If it's True,
1486ba5737fSSimon Glass          returns text with color escape sequences based on the value of
1496ba5737fSSimon Glass          color.
1500d24de9dSSimon Glass        """
1510d24de9dSSimon Glass        if not self._enabled:
1520d24de9dSSimon Glass            return text
1530d24de9dSSimon Glass        if color == self.BOLD:
1540d24de9dSSimon Glass            start = self.BOLD_START
1550d24de9dSSimon Glass        else:
15643bca004SSimon Glass            base = self.BRIGHT_START if bright else self.NORMAL_START
15743bca004SSimon Glass            start = base % (color + 30)
1580d24de9dSSimon Glass        return start + text + self.RESET
159