# Copyright 1998-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

__docformat__ = "epytext"

import codecs
try:
	from subprocess import getstatusoutput as subprocess_getstatusoutput
except ImportError:
	from commands import getstatusoutput as subprocess_getstatusoutput
import errno
import formatter
import re
import sys

import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.util:writemsg',
)

from portage import os
from portage import _encodings
from portage import _unicode_encode
from portage import _unicode_decode
from portage.const import COLOR_MAP_FILE
from portage.exception import CommandNotFound, FileNotFound, \
	ParseError, PermissionDenied, PortageException
from portage.localization import _

havecolor=1
dotitles=1

_styles = {}
"""Maps style class to tuple of attribute names."""

codes = {}
"""Maps attribute name to ansi code."""

esc_seq = "\x1b["

codes["normal"]       =  esc_seq + "0m"
codes["reset"]        =  esc_seq + "39;49;00m"

codes["bold"]         =  esc_seq + "01m"
codes["faint"]        =  esc_seq + "02m"
codes["standout"]     =  esc_seq + "03m"
codes["underline"]    =  esc_seq + "04m"
codes["blink"]        =  esc_seq + "05m"
codes["overline"]     =  esc_seq + "06m"
codes["reverse"]      =  esc_seq + "07m"
codes["invisible"]    =  esc_seq + "08m"

codes["no-attr"]      = esc_seq + "22m"
codes["no-standout"]  = esc_seq + "23m"
codes["no-underline"] = esc_seq + "24m"
codes["no-blink"]     = esc_seq + "25m"
codes["no-overline"]  = esc_seq + "26m"
codes["no-reverse"]   = esc_seq + "27m"

codes["bg_black"]      = esc_seq + "40m"
codes["bg_darkred"]    = esc_seq + "41m"
codes["bg_darkgreen"]  = esc_seq + "42m"
codes["bg_brown"]      = esc_seq + "43m"
codes["bg_darkblue"]   = esc_seq + "44m"
codes["bg_purple"]     = esc_seq + "45m"
codes["bg_teal"]       = esc_seq + "46m"
codes["bg_lightgray"]  = esc_seq + "47m"
codes["bg_default"]    = esc_seq + "49m"
codes["bg_darkyellow"] = codes["bg_brown"]

def color(fg, bg="default", attr=["normal"]):
	mystr = codes[fg]
	for x in [bg]+attr:
		mystr += codes[x]
	return mystr


ansi_codes = []
for x in range(30, 38):
	ansi_codes.append("%im" % x)
	ansi_codes.append("%i;01m" % x)

rgb_ansi_colors = ['0x000000', '0x555555', '0xAA0000', '0xFF5555', '0x00AA00',
	'0x55FF55', '0xAA5500', '0xFFFF55', '0x0000AA', '0x5555FF', '0xAA00AA',
	'0xFF55FF', '0x00AAAA', '0x55FFFF', '0xAAAAAA', '0xFFFFFF']

for x in range(len(rgb_ansi_colors)):
	codes[rgb_ansi_colors[x]] = esc_seq + ansi_codes[x]

del x

codes["black"]     = codes["0x000000"]
codes["darkgray"]  = codes["0x555555"]

codes["red"]       = codes["0xFF5555"]
codes["darkred"]   = codes["0xAA0000"]

codes["green"]     = codes["0x55FF55"]
codes["darkgreen"] = codes["0x00AA00"]

codes["yellow"]    = codes["0xFFFF55"]
codes["brown"]     = codes["0xAA5500"]

codes["blue"]      = codes["0x5555FF"]
codes["darkblue"]  = codes["0x0000AA"]

codes["fuchsia"]   = codes["0xFF55FF"]
codes["purple"]    = codes["0xAA00AA"]

codes["turquoise"] = codes["0x55FFFF"]
codes["teal"]      = codes["0x00AAAA"]

codes["white"]     = codes["0xFFFFFF"]
codes["lightgray"] = codes["0xAAAAAA"]

codes["darkteal"]   = codes["turquoise"]
# Some terminals have darkyellow instead of brown.
codes["0xAAAA00"]   = codes["brown"]
codes["darkyellow"] = codes["0xAAAA00"]



# Colors from /etc/init.d/functions.sh
_styles["NORMAL"]     = ( "normal", )
_styles["GOOD"]       = ( "green", )
_styles["WARN"]       = ( "yellow", )
_styles["BAD"]        = ( "red", )
_styles["HILITE"]     = ( "teal", )
_styles["BRACKET"]    = ( "blue", )

# Portage functions
_styles["INFORM"]                  = ( "darkgreen", )
_styles["UNMERGE_WARN"]            = ( "red", )
_styles["SECURITY_WARN"]           = ( "red", )
_styles["MERGE_LIST_PROGRESS"]     = ( "yellow", )
_styles["PKG_BLOCKER"]             = ( "red", )
_styles["PKG_BLOCKER_SATISFIED"]   = ( "darkblue", )
_styles["PKG_MERGE"]               = ( "darkgreen", )
_styles["PKG_MERGE_SYSTEM"]        = ( "darkgreen", )
_styles["PKG_MERGE_WORLD"]         = ( "green", )
_styles["PKG_BINARY_MERGE"]        = ( "purple", )
_styles["PKG_BINARY_MERGE_SYSTEM"] = ( "purple", )
_styles["PKG_BINARY_MERGE_WORLD"]  = ( "fuchsia", )
_styles["PKG_UNINSTALL"]           = ( "red", )
_styles["PKG_NOMERGE"]             = ( "darkblue", )
_styles["PKG_NOMERGE_SYSTEM"]      = ( "darkblue", )
_styles["PKG_NOMERGE_WORLD"]       = ( "blue", )
_styles["PROMPT_CHOICE_DEFAULT"]   = ( "green", )
_styles["PROMPT_CHOICE_OTHER"]     = ( "red", )

def _parse_color_map(config_root='/', onerror=None):
	"""
	Parse /etc/portage/color.map and return a dict of error codes.

	@param onerror: an optional callback to handle any ParseError that would
		otherwise be raised
	@type onerror: callable
	@rtype: dict
	@return: a dictionary mapping color classes to color codes
	"""
	global codes, _styles
	myfile = os.path.join(config_root, COLOR_MAP_FILE)
	ansi_code_pattern = re.compile("^[0-9;]*m$") 
	quotes = '\'"'
	def strip_quotes(token):
		if token[0] in quotes and token[0] == token[-1]:
			token = token[1:-1]
		return token
	try:
		lineno=0
		for line in codecs.open(_unicode_encode(myfile,
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['content'], errors='replace'):
			lineno += 1

			commenter_pos = line.find("#")
			line = line[:commenter_pos].strip()
			
			if len(line) == 0:
				continue
			
			split_line = line.split("=")
			if len(split_line) != 2:
				e = ParseError(_("'%s', line %s: expected exactly one occurence of '=' operator") % \
					(myfile, lineno))
				raise e
				if onerror:
					onerror(e)
				else:
					raise e
				continue

			k = strip_quotes(split_line[0].strip())
			v = strip_quotes(split_line[1].strip())
			if not k in _styles and not k in codes:
				e = ParseError(_("'%s', line %s: Unknown variable: '%s'") % \
					(myfile, lineno, k))
				if onerror:
					onerror(e)
				else:
					raise e
				continue
			if ansi_code_pattern.match(v):
				if k in _styles:
					_styles[k] = ( esc_seq + v, )
				elif k in codes:
					codes[k] = esc_seq + v
			else:
				code_list = []
				for x in v.split():
					if x in codes:
						if k in _styles:
							code_list.append(x)
						elif k in codes:
							code_list.append(codes[x])
					else:
						e = ParseError(_("'%s', line %s: Undefined: '%s'") % \
							(myfile, lineno, x))
						if onerror:
							onerror(e)
						else:
							raise e
				if k in _styles:
					_styles[k] = tuple(code_list)
				elif k in codes:
					codes[k] = "".join(code_list)
	except (IOError, OSError) as e:
		if e.errno == errno.ENOENT:
			raise FileNotFound(myfile)
		elif e.errno == errno.EACCES:
			raise PermissionDenied(myfile)
		raise

def nc_len(mystr):
	tmp = re.sub(esc_seq + "^m]+m", "", mystr);
	return len(tmp)

_legal_terms_re = re.compile(r'^(xterm|xterm-color|Eterm|aterm|rxvt|screen|kterm|rxvt-unicode|gnome|interix)')
_disable_xtermTitle = None
_max_xtermTitle_len = 253

def xtermTitle(mystr, raw=False):
	global _disable_xtermTitle
	if _disable_xtermTitle is None:
		_disable_xtermTitle = not (sys.stderr.isatty() and \
		'TERM' in os.environ and \
		_legal_terms_re.match(os.environ['TERM']) is not None)

	if dotitles and not _disable_xtermTitle:
		# If the title string is too big then the terminal can
		# misbehave. Therefore, truncate it if it's too big.
		if len(mystr) > _max_xtermTitle_len:
			mystr = mystr[:_max_xtermTitle_len]
		if not raw:
			mystr = '\x1b]0;%s\x07' % mystr

		# avoid potential UnicodeEncodeError
		mystr = _unicode_encode(mystr,
			encoding=_encodings['stdio'], errors='backslashreplace')
		f = sys.stderr
		if sys.hexversion >= 0x3000000:
			f = f.buffer
		f.write(mystr)
		f.flush()

default_xterm_title = None

def xtermTitleReset():
	global default_xterm_title
	if default_xterm_title is None:
		prompt_command = os.environ.get('PROMPT_COMMAND')
		if prompt_command == "":
			default_xterm_title = ""
		elif prompt_command is not None:
			if dotitles and \
				'TERM' in os.environ and \
				_legal_terms_re.match(os.environ['TERM']) is not None and \
				sys.stderr.isatty():
				from portage.process import find_binary, spawn
				shell = os.environ.get("SHELL")
				if not shell or not os.access(shell, os.EX_OK):
					shell = find_binary("sh")
				if shell:
					spawn([shell, "-c", prompt_command], env=os.environ,
						fd_pipes={0:sys.stdin.fileno(),1:sys.stderr.fileno(),
						2:sys.stderr.fileno()})
				else:
					os.system(prompt_command)
			return
		else:
			pwd = os.environ.get('PWD','')
			home = os.environ.get('HOME', '')
			if home != '' and pwd.startswith(home):
				pwd = '~' + pwd[len(home):]
			default_xterm_title = '\x1b]0;%s@%s:%s\x07' % (
				os.environ.get('LOGNAME', ''),
				os.environ.get('HOSTNAME', '').split('.', 1)[0], pwd)
	xtermTitle(default_xterm_title, raw=True)

def notitles():
	"turn off title setting"
	dotitles=0

def nocolor():
	"turn off colorization"
	global havecolor
	havecolor=0

def resetColor():
	return codes["reset"]

def style_to_ansi_code(style):
	"""
	@param style: A style name
	@type style: String
	@rtype: String
	@return: A string containing one or more ansi escape codes that are
		used to render the given style.
	"""
	ret = ""
	for attr_name in _styles[style]:
		# allow stuff that has found it's way through ansi_code_pattern
		ret += codes.get(attr_name, attr_name)
	return ret

def colorize(color_key, text):
	global havecolor
	if havecolor:
		if color_key in codes:
			return codes[color_key] + text + codes["reset"]
		elif color_key in _styles:
			return style_to_ansi_code(color_key) + text + codes["reset"]
		else:
			return text
	else:
		return text

compat_functions_colors = ["bold","white","teal","turquoise","darkteal",
	"fuchsia","purple","blue","darkblue","green","darkgreen","yellow",
	"brown","darkyellow","red","darkred"]

def create_color_func(color_key):
	def derived_func(*args):
		newargs = list(args)
		newargs.insert(0, color_key)
		return colorize(*newargs)
	return derived_func

for c in compat_functions_colors:
	globals()[c] = create_color_func(c)

class ConsoleStyleFile(object):
	"""
	A file-like object that behaves something like
	the colorize() function. Style identifiers
	passed in via the new_styles() method will be used to
	apply console codes to output.
	"""
	def __init__(self, f):
		self._file = f
		self._styles = None
		self.write_listener = None

	def new_styles(self, styles):
		self._styles = styles

	def write(self, s):
		# In python-2.6, DumbWriter.send_line_break() can write
		# non-unicode '\n' which fails with TypeError if self._file
		# is a text stream such as io.StringIO. Therefore, make sure
		# input is converted to unicode when necessary.
		s = _unicode_decode(s)
		global havecolor
		if havecolor and self._styles:
			styled_s = []
			for style in self._styles:
				styled_s.append(style_to_ansi_code(style))
			styled_s.append(s)
			styled_s.append(codes["reset"])
			self._write(self._file, "".join(styled_s))
		else:
			self._write(self._file, s)
		if self.write_listener:
			self._write(self.write_listener, s)

	def _write(self, f, s):
		# avoid potential UnicodeEncodeError
		if f in (sys.stdout, sys.stderr):
			s = _unicode_encode(s,
				encoding=_encodings['stdio'], errors='backslashreplace')
			if sys.hexversion >= 0x3000000:
				f = f.buffer
		f.write(s)

	def writelines(self, lines):
		for s in lines:
			self.write(s)

	def flush(self):
		self._file.flush()

	def close(self):
		self._file.close()

class StyleWriter(formatter.DumbWriter):
	"""
	This is just a DumbWriter with a hook in the new_styles() method
	that passes a styles tuple as a single argument to a callable
	style_listener attribute.
	"""
	def __init__(self, **kwargs):
		formatter.DumbWriter.__init__(self, **kwargs)
		self.style_listener = None

	def new_styles(self, styles):
		formatter.DumbWriter.new_styles(self, styles)
		if self.style_listener:
			self.style_listener(styles)

def get_term_size():
	"""
	Get the number of lines and columns of the tty that is connected to
	stdout.  Returns a tuple of (lines, columns) or (-1, -1) if an error
	occurs. The curses module is used if available, otherwise the output of
	`stty size` is parsed.
	"""
	if not sys.stdout.isatty():
		return -1, -1
	try:
		import curses
		try:
			curses.setupterm()
			return curses.tigetnum('lines'), curses.tigetnum('cols')
		except curses.error:
			pass
	except ImportError:
		pass
	st, out = subprocess_getstatusoutput('stty size')
	if st == os.EX_OK:
		out = out.split()
		if len(out) == 2:
			try:
				return int(out[0]), int(out[1])
			except ValueError:
				pass
	return -1, -1

def set_term_size(lines, columns, fd):
	"""
	Set the number of lines and columns for the tty that is connected to fd.
	For portability, this simply calls `stty rows $lines columns $columns`.
	"""
	from portage.process import spawn
	cmd = ["stty", "rows", str(lines), "columns", str(columns)]
	try:
		spawn(cmd, env=os.environ, fd_pipes={0:fd})
	except CommandNotFound:
		writemsg(_("portage: stty: command not found\n"), noiselevel=-1)

class EOutput(object):
	"""
	Performs fancy terminal formatting for status and informational messages.

	The provided methods produce identical terminal output to the eponymous
	functions in the shell script C{/sbin/functions.sh} and also accept
	identical parameters.

	This is not currently a drop-in replacement however, as the output-related
	functions in C{/sbin/functions.sh} are oriented for use mainly by system
	init scripts and ebuilds and their output can be customized via certain
	C{RC_*} environment variables (see C{/etc/conf.d/rc}). B{EOutput} is not
	customizable in this manner since it's intended for more general uses.
	Likewise, no logging is provided.

	@ivar quiet: Specifies if output should be silenced.
	@type quiet: BooleanType
	@ivar term_columns: Width of terminal in characters. Defaults to the value
		specified by the shell's C{COLUMNS} variable, else to the queried tty
		size, else to C{80}.
	@type term_columns: IntType
	"""

	def __init__(self, quiet=False):
		self.__last_e_cmd = ""
		self.__last_e_len = 0
		self.quiet = quiet
		lines, columns = get_term_size()
		if columns <= 0:
			columns = 80
		self.term_columns = columns
		sys.stdout.flush()
		sys.stderr.flush()

	def _write(self, f, s):
		# avoid potential UnicodeEncodeError
		writemsg(s, noiselevel=-1, fd=f)

	def __eend(self, caller, errno, msg):
		if errno == 0:
			status_brackets = colorize("BRACKET", "[ ") + colorize("GOOD", "ok") + colorize("BRACKET", " ]")
		else:
			status_brackets = colorize("BRACKET", "[ ") + colorize("BAD", "!!") + colorize("BRACKET", " ]")
			if msg:
				if caller == "eend":
					self.eerror(msg[0])
				elif caller == "ewend":
					self.ewarn(msg[0])
		if self.__last_e_cmd != "ebegin":
			self.__last_e_len = 0
		if not self.quiet:
			out = sys.stdout
			self._write(out,
				"%*s%s\n" % ((self.term_columns - self.__last_e_len - 7),
				"", status_brackets))

	def ebegin(self, msg):
		"""
		Shows a message indicating the start of a process.

		@param msg: A very brief (shorter than one line) description of the
			starting process.
		@type msg: StringType
		"""
		msg += " ..."
		if not self.quiet:
			self.einfon(msg)
		self.__last_e_len = len(msg) + 3
		self.__last_e_cmd = "ebegin"

	def eend(self, errno, *msg):
		"""
		Indicates the completion of a process, optionally displaying a message
		via L{eerror} if the process's exit status isn't C{0}.

		@param errno: A standard UNIX C{errno} code returned by processes upon
			exit.
		@type errno: IntType
		@param msg: I{(optional)} An error message, typically a standard UNIX
			error string corresponding to C{errno}.
		@type msg: StringType
		"""
		if not self.quiet:
			self.__eend("eend", errno, msg)
		self.__last_e_cmd = "eend"

	def eerror(self, msg):
		"""
		Shows an error message.

		@param msg: A very brief (shorter than one line) error message.
		@type msg: StringType
		"""
		out = sys.stderr
		if not self.quiet:
			if self.__last_e_cmd == "ebegin":
				self._write(out, "\n")
			self._write(out, colorize("BAD", " * ") + msg + "\n")
		self.__last_e_cmd = "eerror"

	def einfo(self, msg):
		"""
		Shows an informative message terminated with a newline.

		@param msg: A very brief (shorter than one line) informative message.
		@type msg: StringType
		"""
		out = sys.stdout
		if not self.quiet:
			if self.__last_e_cmd == "ebegin":
				self._write(out, "\n")
			self._write(out, colorize("GOOD", " * ") + msg + "\n")
		self.__last_e_cmd = "einfo"

	def einfon(self, msg):
		"""
		Shows an informative message terminated without a newline.

		@param msg: A very brief (shorter than one line) informative message.
		@type msg: StringType
		"""
		out = sys.stdout
		if not self.quiet:
			if self.__last_e_cmd == "ebegin":
				self._write(out, "\n")
			self._write(out, colorize("GOOD", " * ") + msg)
		self.__last_e_cmd = "einfon"

	def ewarn(self, msg):
		"""
		Shows a warning message.

		@param msg: A very brief (shorter than one line) warning message.
		@type msg: StringType
		"""
		out = sys.stderr
		if not self.quiet:
			if self.__last_e_cmd == "ebegin":
				self._write(out, "\n")
			self._write(out, colorize("WARN", " * ") + msg + "\n")
		self.__last_e_cmd = "ewarn"

	def ewend(self, errno, *msg):
		"""
		Indicates the completion of a process, optionally displaying a message
		via L{ewarn} if the process's exit status isn't C{0}.

		@param errno: A standard UNIX C{errno} code returned by processes upon
			exit.
		@type errno: IntType
		@param msg: I{(optional)} A warning message, typically a standard UNIX
			error string corresponding to C{errno}.
		@type msg: StringType
		"""
		if not self.quiet:
			self.__eend("ewend", errno, msg)
		self.__last_e_cmd = "ewend"

class ProgressBar(object):
	"""The interface is copied from the ProgressBar class from the EasyDialogs
	module (which is Mac only)."""
	def __init__(self, title=None, maxval=0, label=None):
		self._title = title
		self._maxval = maxval
		self._label = maxval
		self._curval = 0

	@property
	def curval(self):
		"""
		The current value (of type integer or long integer) of the progress
		bar. The normal access methods coerce curval between 0 and maxval. This
		attribute should not be altered directly.
		"""
		return self._curval

	@property
	def maxval(self):
		"""
		The maximum value (of type integer or long integer) of the progress
		bar; the progress bar (thermometer style) is full when curval equals
		maxval. If maxval is 0, the bar will be indeterminate (barber-pole).
		This attribute should not be altered directly.
		"""
		return self._maxval

	def title(self, newstr):
		"""Sets the text in the title bar of the progress dialog to newstr."""
		self._title = newstr

	def label(self, newstr):
		"""Sets the text in the progress box of the progress dialog to newstr."""
		self._label = newstr

	def set(self, value, maxval=None):
		"""
		Sets the progress bar's curval to value, and also maxval to max if the
		latter is provided. value is first coerced between 0 and maxval. The
		thermometer bar is updated to reflect the changes, including a change
		from indeterminate to determinate or vice versa.
		"""
		if maxval is not None:
			self._maxval = maxval
		if value < 0:
			value = 0
		elif value > self._maxval:
			value = self._maxval
		self._curval = value

	def inc(self, n=1):
		"""Increments the progress bar's curval by n, or by 1 if n is not
		provided. (Note that n may be negative, in which case the effect is a
		decrement.) The progress bar is updated to reflect the change. If the
		bar is indeterminate, this causes one ``spin'' of the barber pole. The
		resulting curval is coerced between 0 and maxval if incrementing causes
		it to fall outside this range.
		"""
		self.set(self._curval+n)

class TermProgressBar(ProgressBar):
	"""A tty progress bar similar to wget's."""
	def __init__(self, **kwargs):
		ProgressBar.__init__(self, **kwargs)
		lines, self.term_columns = get_term_size()
		self.file = sys.stdout
		self._min_columns = 11
		self._max_columns = 80
		# for indeterminate mode, ranges from 0.0 to 1.0
		self._position = 0.0

	def set(self, value, maxval=None):
		ProgressBar.set(self, value, maxval=maxval)
		self._display_image(self._create_image())

	def _display_image(self, image):
		self.file.write('\r')
		self.file.write(image)
		self.file.flush()

	def _create_image(self):
		cols = self.term_columns
		if cols > self._max_columns:
			cols = self._max_columns
		min_columns = self._min_columns
		curval = self._curval
		maxval = self._maxval
		position = self._position
		percentage_str_width = 4
		square_brackets_width = 2
		if cols < percentage_str_width:
			return ""
		bar_space = cols - percentage_str_width - square_brackets_width
		if maxval == 0:
			max_bar_width = bar_space-3
			image = "    "
			if cols < min_columns:
				return image
			if position <= 0.5:
				offset = 2 * position
			else:
				offset = 2 * (1 - position)
			delta = 0.5 / max_bar_width
			position += delta
			if position >= 1.0:
				position = 0.0
			# make sure it touches the ends
			if 1.0 - position < delta:
				position = 1.0
			if position < 0.5 and 0.5 - position < delta:
				position = 0.5
			self._position = position
			bar_width = int(offset * max_bar_width)
			image = image + "[" + (bar_width * " ") + \
				"<=>" + ((max_bar_width - bar_width) * " ") + "]"
			return image
		else:
			percentage = int(100 * float(curval) / maxval)
			if percentage == 100:
				percentage_str_width += 1
				bar_space -= 1
			max_bar_width = bar_space - 1
			image = ("%d%% " % percentage).rjust(percentage_str_width)
			if cols < min_columns:
				return image
			offset = float(curval) / maxval
			bar_width = int(offset * max_bar_width)
			image = image + "[" + (bar_width * "=") + \
				">" + ((max_bar_width - bar_width) * " ") + "]"
			return image

_color_map_loaded = False

def _init(config_root='/'):
	"""
	Load color.map from the given config_root. This is called automatically
	on first access of the codes or _styles attributes (unless it has already
	been called for some other reason).
	"""

	global _color_map_loaded, codes, _styles
	if _color_map_loaded:
		return

	_color_map_loaded = True
	codes = object.__getattribute__(codes, '_attr')
	_styles = object.__getattribute__(_styles, '_attr')

	for k, v in codes.items():
		codes[k] = _unicode_decode(v)

	for k, v in _styles.items():
		_styles[k] = _unicode_decode(v)

	try:
		_parse_color_map(config_root=config_root,
			onerror=lambda e: writemsg("%s\n" % str(e), noiselevel=-1))
	except FileNotFound:
		pass
	except PermissionDenied as e:
		writemsg(_("Permission denied: '%s'\n") % str(e), noiselevel=-1)
		del e
	except PortageException as e:
		writemsg("%s\n" % str(e), noiselevel=-1)
		del e

class _LazyInitColorMap(portage.proxy.objectproxy.ObjectProxy):

	__slots__ = ('_attr',)

	def __init__(self, attr):
		portage.proxy.objectproxy.ObjectProxy.__init__(self)
		object.__setattr__(self, '_attr', attr)

	def _get_target(self):
		_init()
		return object.__getattribute__(self, '_attr')

codes = _LazyInitColorMap(codes)
_styles = _LazyInitColorMap(_styles)
