update msger to refine nocolor output
[tools/mic.git] / mic / msger.py
1 #!/usr/bin/python -tt
2 # vim: ai ts=4 sts=4 et sw=4
3
4 #    Copyright (c) 2009 Intel Corporation
5 #
6 #    This program is free software; you can redistribute it and/or modify it
7 #    under the terms of the GNU General Public License as published by the Free
8 #    Software Foundation; version 2 of the License
9 #
10 #    This program is distributed in the hope that it will be useful, but
11 #    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 #    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 #    for more details.
14 #
15 #    You should have received a copy of the GNU General Public License along
16 #    with this program; if not, write to the Free Software Foundation, Inc., 59
17 #    Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 import os,sys
20 import re
21
22 __ALL__ = ['set_mode', 'set_loglevel', 'raw' 'debug', 'verbose', 'info', 'warning', 'error', 'ask']
23
24 # COLORs in ANSI
25 INFO_COLOR = 32 # green
26 WARN_COLOR = 33 # yellow
27 ERR_COLOR  = 31 # red
28 ASK_COLOR  = 34 # blue
29 NO_COLOR = 0
30
31 PREFIX_RE = re.compile('^<(.*?)>\s*(.*)')
32
33 INTERACTIVE = True
34
35 LOG_LEVELS = {
36                 'quiet': 0,
37                 'normal': 1,
38                 'verbose': 2,
39                 'debug': 3,
40              }
41 LOG_LEVEL = 1
42
43 def _color_print(head, color, msg = None, stream = sys.stdout, level = 'normal'):
44
45     if LOG_LEVELS[level] > LOG_LEVEL:
46         # skip
47         return
48
49     colored = True
50     if color == NO_COLOR or \
51        not stream.isatty() or \
52        os.getenv('ANSI_COLORS_DISABLED') is not None:
53         colored = False
54
55     if head.startswith('\r'):
56         # need not \n at last
57         newline = False
58     else:
59         newline = True
60
61     if colored:
62         head = '\033[%dm%s:\033[0m ' %(color, head)
63         if not newline:
64             # ESC cmd to clear line
65             head = '\033[2K' + head
66     else:
67         if head:
68             head += ': '
69             if head.startswith('\r'):
70                 head = head.lstrip()
71                 newline = True
72
73     if msg:
74         stream.write('%s%s' % (head, msg))
75         if newline:
76             stream.write('\n')
77
78     stream.flush()
79
80 def _color_perror(head, color, msg, level = 'normal'):
81     _color_print(head, color, msg, sys.stderr, level)
82
83 def _split_msg(head, msg):
84     if isinstance(msg, list):
85         msg = '\n'.join(map(str, msg))
86
87     if msg.startswith('\n'):
88         # means print \n at first
89         msg = msg.lstrip()
90         head = '\n' + head
91
92     elif msg.startswith('\r'):
93         # means print \r at first
94         msg = msg.lstrip()
95         head = '\r' + head
96
97     m = PREFIX_RE.match(msg)
98     if m:
99         head += ' <%s>' % m.group(1)
100         msg = m.group(2)
101
102     return head, msg
103
104 def set_loglevel(level):
105     global LOG_LEVEL
106     if level not in LOG_LEVELS:
107         # no effect
108         return
109
110     LOG_LEVEL = LOG_LEVELS[level]
111
112 def set_mode(interactive):
113     global INTERACTIVE
114     if interactive:
115         INTERACTIVE = True
116     else:
117         INTERACTIVE = False
118
119 def raw(msg=None):
120     if msg is None:
121         msg = ''
122     sys.stdout.write(msg)
123     sys.stdout.write('\n')
124
125 def info(msg):
126     head, msg = _split_msg('Info', msg)
127     _color_print(head, INFO_COLOR, msg)
128
129 def verbose(msg):
130     head, msg = _split_msg('Verbose', msg)
131     _color_print(head, INFO_COLOR, msg, level = 'verbose')
132
133 def warning(msg):
134     head, msg = _split_msg('Warning', msg)
135     _color_perror(head, WARN_COLOR, msg)
136
137 def debug(msg):
138     head, msg = _split_msg('Debug', msg)
139     _color_perror(head, ERR_COLOR, msg, level = 'debug')
140
141 def error(msg):
142     head, msg = _split_msg('Error', msg)
143     _color_perror(head, ERR_COLOR, msg)
144     sys.exit(1)
145
146 def ask(msg, default=True):
147     _color_print('Q', ASK_COLOR, '')
148     try:
149         if default:
150             msg += '(Y/n) '
151         else:
152             msg += '(y/N) '
153         if INTERACTIVE:
154             repl = raw_input(msg)
155             if repl.lower() == 'y':
156                 return True
157             elif repl.lower() == 'n':
158                 return False
159             else:
160                 return default
161
162         else:
163             sys.stdout.write('%s ' % msg)
164             if default:
165                 sys.stdout.write('Y\n')
166             else:
167                 sys.stdout.write('N\n')
168             return default
169     except KeyboardInterrupt:
170         sys.stdout.write('\n')
171         sys.exit(2)