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 170d24de9dSSimon Glassclass Color(object): 180d24de9dSSimon Glass """Conditionally wraps text in ANSI color escape sequences.""" 190d24de9dSSimon Glass BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) 200d24de9dSSimon Glass BOLD = -1 2143bca004SSimon Glass BRIGHT_START = '\033[1;%dm' 2243bca004SSimon Glass NORMAL_START = '\033[22;%dm' 230d24de9dSSimon Glass BOLD_START = '\033[1m' 240d24de9dSSimon Glass RESET = '\033[0m' 250d24de9dSSimon Glass 26bbd01435SSimon Glass def __init__(self, colored=COLOR_IF_TERMINAL): 270d24de9dSSimon Glass """Create a new Color object, optionally disabling color output. 280d24de9dSSimon Glass 290d24de9dSSimon Glass Args: 300d24de9dSSimon Glass enabled: True if color output should be enabled. If False then this 310d24de9dSSimon Glass class will not add color codes at all. 320d24de9dSSimon Glass """ 33*e752edcbSSimon Glass try: 34bbd01435SSimon Glass self._enabled = (colored == COLOR_ALWAYS or 35*e752edcbSSimon Glass (colored == COLOR_IF_TERMINAL and 36*e752edcbSSimon Glass os.isatty(sys.stdout.fileno()))) 37*e752edcbSSimon Glass except: 38*e752edcbSSimon Glass self._enabled = False 390d24de9dSSimon Glass 4043bca004SSimon Glass def Start(self, color, bright=True): 410d24de9dSSimon Glass """Returns a start color code. 420d24de9dSSimon Glass 430d24de9dSSimon Glass Args: 440d24de9dSSimon Glass color: Color to use, .e.g BLACK, RED, etc. 450d24de9dSSimon Glass 460d24de9dSSimon Glass Returns: 476ba5737fSSimon Glass If color is enabled, returns an ANSI sequence to start the given 486ba5737fSSimon Glass color, otherwise returns empty string 490d24de9dSSimon Glass """ 500d24de9dSSimon Glass if self._enabled: 5143bca004SSimon Glass base = self.BRIGHT_START if bright else self.NORMAL_START 5243bca004SSimon Glass return base % (color + 30) 530d24de9dSSimon Glass return '' 540d24de9dSSimon Glass 550d24de9dSSimon Glass def Stop(self): 560d24de9dSSimon Glass """Retruns a stop color code. 570d24de9dSSimon Glass 580d24de9dSSimon Glass Returns: 596ba5737fSSimon Glass If color is enabled, returns an ANSI color reset sequence, 606ba5737fSSimon Glass otherwise returns empty string 610d24de9dSSimon Glass """ 620d24de9dSSimon Glass if self._enabled: 630d24de9dSSimon Glass return self.RESET 640d24de9dSSimon Glass return '' 650d24de9dSSimon Glass 6643bca004SSimon Glass def Color(self, color, text, bright=True): 670d24de9dSSimon Glass """Returns text with conditionally added color escape sequences. 680d24de9dSSimon Glass 690d24de9dSSimon Glass Keyword arguments: 706ba5737fSSimon Glass color: Text color -- one of the color constants defined in this 716ba5737fSSimon Glass class. 720d24de9dSSimon Glass text: The text to color. 730d24de9dSSimon Glass 740d24de9dSSimon Glass Returns: 750d24de9dSSimon Glass If self._enabled is False, returns the original text. If it's True, 766ba5737fSSimon Glass returns text with color escape sequences based on the value of 776ba5737fSSimon Glass color. 780d24de9dSSimon Glass """ 790d24de9dSSimon Glass if not self._enabled: 800d24de9dSSimon Glass return text 810d24de9dSSimon Glass if color == self.BOLD: 820d24de9dSSimon Glass start = self.BOLD_START 830d24de9dSSimon Glass else: 8443bca004SSimon Glass base = self.BRIGHT_START if bright else self.NORMAL_START 8543bca004SSimon Glass start = base % (color + 30) 860d24de9dSSimon Glass return start + text + self.RESET 87