blob: 9200a29895a3cd40d70ab4ced6d7ee932b3796df [file] [log] [blame]
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -07001#
2# Copyright (C) 2008 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os
17import sys
18
19import pager
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070020
21COLORS = {None :-1,
22 'normal' :-1,
23 'black' : 0,
24 'red' : 1,
25 'green' : 2,
26 'yellow' : 3,
27 'blue' : 4,
28 'magenta': 5,
29 'cyan' : 6,
30 'white' : 7}
31
32ATTRS = {None :-1,
33 'bold' : 1,
34 'dim' : 2,
35 'ul' : 4,
36 'blink' : 5,
37 'reverse': 7}
38
39RESET = "\033[m"
40
David Pursehouse8a68ff92012-09-24 12:15:13 +090041def is_color(s):
42 return s in COLORS
43
44def is_attr(s):
45 return s in ATTRS
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070046
47def _Color(fg = None, bg = None, attr = None):
48 fg = COLORS[fg]
49 bg = COLORS[bg]
50 attr = ATTRS[attr]
51
52 if attr >= 0 or fg >= 0 or bg >= 0:
53 need_sep = False
54 code = "\033["
55
56 if attr >= 0:
57 code += chr(ord('0') + attr)
58 need_sep = True
59
60 if fg >= 0:
61 if need_sep:
62 code += ';'
63 need_sep = True
64
65 if fg < 8:
66 code += '3%c' % (ord('0') + fg)
67 else:
68 code += '38;5;%d' % fg
69
70 if bg >= 0:
71 if need_sep:
72 code += ';'
73 need_sep = True
74
75 if bg < 8:
76 code += '4%c' % (ord('0') + bg)
77 else:
78 code += '48;5;%d' % bg
79 code += 'm'
80 else:
81 code = ''
82 return code
83
84
85class Coloring(object):
David Pursehouse8a68ff92012-09-24 12:15:13 +090086 def __init__(self, config, section_type):
87 self._section = 'color.%s' % section_type
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -070088 self._config = config
89 self._out = sys.stdout
90
91 on = self._config.GetString(self._section)
92 if on is None:
93 on = self._config.GetString('color.ui')
94
95 if on == 'auto':
96 if pager.active or os.isatty(1):
97 self._on = True
98 else:
99 self._on = False
100 elif on in ('true', 'always'):
101 self._on = True
102 else:
103 self._on = False
104
Shawn O. Pearce350cde42009-04-16 11:21:18 -0700105 def redirect(self, out):
106 self._out = out
107
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700108 @property
109 def is_on(self):
110 return self._on
111
112 def write(self, fmt, *args):
113 self._out.write(fmt % args)
114
Shawn O. Pearcedb45da12009-04-18 13:49:13 -0700115 def flush(self):
116 self._out.flush()
117
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700118 def nl(self):
119 self._out.write('\n')
120
121 def printer(self, opt=None, fg=None, bg=None, attr=None):
122 s = self
123 c = self.colorer(opt, fg, bg, attr)
124 def f(fmt, *args):
125 s._out.write(c(fmt, *args))
126 return f
127
128 def colorer(self, opt=None, fg=None, bg=None, attr=None):
129 if self._on:
130 c = self._parse(opt, fg, bg, attr)
131 def f(fmt, *args):
David Pursehouse8a68ff92012-09-24 12:15:13 +0900132 output = fmt % args
133 return ''.join([c, output, RESET])
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700134 return f
135 else:
136 def f(fmt, *args):
137 return fmt % args
138 return f
139
140 def _parse(self, opt, fg, bg, attr):
141 if not opt:
142 return _Color(fg, bg, attr)
143
144 v = self._config.GetString('%s.%s' % (self._section, opt))
145 if v is None:
146 return _Color(fg, bg, attr)
147
Shawn O. Pearcea8e98a62009-02-02 16:17:02 -0800148 v = v.strip().lower()
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700149 if v == "reset":
150 return RESET
151 elif v == '':
152 return _Color(fg, bg, attr)
153
154 have_fg = False
155 for a in v.split(' '):
156 if is_color(a):
David Pursehouse8a68ff92012-09-24 12:15:13 +0900157 if have_fg:
158 bg = a
159 else:
160 fg = a
The Android Open Source Projectcf31fe92008-10-21 07:00:00 -0700161 elif is_attr(a):
162 attr = a
163
164 return _Color(fg, bg, attr)