Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/scripts/lib/wic/msger.py b/scripts/lib/wic/msger.py
new file mode 100644
index 0000000..b737554
--- /dev/null
+++ b/scripts/lib/wic/msger.py
@@ -0,0 +1,309 @@
+#!/usr/bin/env python -tt
+# vim: ai ts=4 sts=4 et sw=4
+#
+# Copyright (c) 2009, 2010, 2011 Intel, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; version 2 of the License
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import os
+import sys
+import re
+import time
+
+__ALL__ = ['set_mode',
+           'get_loglevel',
+           'set_loglevel',
+           'set_logfile',
+           'raw',
+           'debug',
+           'verbose',
+           'info',
+           'warning',
+           'error',
+           'ask',
+           'pause',
+          ]
+
+# COLORs in ANSI
+INFO_COLOR = 32 # green
+WARN_COLOR = 33 # yellow
+ERR_COLOR = 31 # red
+ASK_COLOR = 34 # blue
+NO_COLOR = 0
+
+PREFIX_RE = re.compile('^<(.*?)>\s*(.*)', re.S)
+
+INTERACTIVE = True
+
+LOG_LEVEL = 1
+LOG_LEVELS = {
+    'quiet': 0,
+    'normal': 1,
+    'verbose': 2,
+    'debug': 3,
+    'never': 4,
+}
+
+LOG_FILE_FP = None
+LOG_CONTENT = ''
+CATCHERR_BUFFILE_FD = -1
+CATCHERR_BUFFILE_PATH = None
+CATCHERR_SAVED_2 = -1
+
+def _general_print(head, color, msg=None, stream=None, level='normal'):
+    global LOG_CONTENT
+    if not stream:
+        stream = sys.stdout
+
+    if LOG_LEVELS[level] > LOG_LEVEL:
+        # skip
+        return
+
+    # encode raw 'unicode' str to utf8 encoded str
+    if msg and isinstance(msg, unicode):
+        msg = msg.encode('utf-8', 'ignore')
+
+    errormsg = ''
+    if CATCHERR_BUFFILE_FD > 0:
+        size = os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_END)
+        os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_SET)
+        errormsg = os.read(CATCHERR_BUFFILE_FD, size)
+        os.ftruncate(CATCHERR_BUFFILE_FD, 0)
+
+    # append error msg to LOG
+    if errormsg:
+        LOG_CONTENT += errormsg
+
+    # append normal msg to LOG
+    save_msg = msg.strip() if msg else None
+    if save_msg:
+        timestr = time.strftime("[%m/%d %H:%M:%S %Z] ", time.localtime())
+        LOG_CONTENT += timestr + save_msg + '\n'
+
+    if errormsg:
+        _color_print('', NO_COLOR, errormsg, stream, level)
+
+    _color_print(head, color, msg, stream, level)
+
+def _color_print(head, color, msg, stream, level):
+    colored = True
+    if color == NO_COLOR or \
+       not stream.isatty() or \
+       os.getenv('ANSI_COLORS_DISABLED') is not None:
+        colored = False
+
+    if head.startswith('\r'):
+        # need not \n at last
+        newline = False
+    else:
+        newline = True
+
+    if colored:
+        head = '\033[%dm%s:\033[0m ' %(color, head)
+        if not newline:
+            # ESC cmd to clear line
+            head = '\033[2K' + head
+    else:
+        if head:
+            head += ': '
+            if head.startswith('\r'):
+                head = head.lstrip()
+                newline = True
+
+    if msg is not None:
+        if isinstance(msg, unicode):
+            msg = msg.encode('utf8', 'ignore')
+
+        stream.write('%s%s' % (head, msg))
+        if newline:
+            stream.write('\n')
+
+    stream.flush()
+
+def _color_perror(head, color, msg, level='normal'):
+    if CATCHERR_BUFFILE_FD > 0:
+        _general_print(head, color, msg, sys.stdout, level)
+    else:
+        _general_print(head, color, msg, sys.stderr, level)
+
+def _split_msg(head, msg):
+    if isinstance(msg, list):
+        msg = '\n'.join(map(str, msg))
+
+    if msg.startswith('\n'):
+        # means print \n at first
+        msg = msg.lstrip()
+        head = '\n' + head
+
+    elif msg.startswith('\r'):
+        # means print \r at first
+        msg = msg.lstrip()
+        head = '\r' + head
+
+    match = PREFIX_RE.match(msg)
+    if match:
+        head += ' <%s>' % match.group(1)
+        msg = match.group(2)
+
+    return head, msg
+
+def get_loglevel():
+    return (k for k, v in LOG_LEVELS.items() if v == LOG_LEVEL).next()
+
+def set_loglevel(level):
+    global LOG_LEVEL
+    if level not in LOG_LEVELS:
+        # no effect
+        return
+
+    LOG_LEVEL = LOG_LEVELS[level]
+
+def set_interactive(mode=True):
+    global INTERACTIVE
+    if mode:
+        INTERACTIVE = True
+    else:
+        INTERACTIVE = False
+
+def log(msg=''):
+    # log msg to LOG_CONTENT then save to logfile
+    global LOG_CONTENT
+    if msg:
+        LOG_CONTENT += msg
+
+def raw(msg=''):
+    _general_print('', NO_COLOR, msg)
+
+def info(msg):
+    head, msg = _split_msg('Info', msg)
+    _general_print(head, INFO_COLOR, msg)
+
+def verbose(msg):
+    head, msg = _split_msg('Verbose', msg)
+    _general_print(head, INFO_COLOR, msg, level='verbose')
+
+def warning(msg):
+    head, msg = _split_msg('Warning', msg)
+    _color_perror(head, WARN_COLOR, msg)
+
+def debug(msg):
+    head, msg = _split_msg('Debug', msg)
+    _color_perror(head, ERR_COLOR, msg, level='debug')
+
+def error(msg):
+    head, msg = _split_msg('Error', msg)
+    _color_perror(head, ERR_COLOR, msg)
+    sys.exit(1)
+
+def ask(msg, default=True):
+    _general_print('\rQ', ASK_COLOR, '')
+    try:
+        if default:
+            msg += '(Y/n) '
+        else:
+            msg += '(y/N) '
+        if INTERACTIVE:
+            while True:
+                repl = raw_input(msg)
+                if repl.lower() == 'y':
+                    return True
+                elif repl.lower() == 'n':
+                    return False
+                elif not repl.strip():
+                    # <Enter>
+                    return default
+
+                # else loop
+        else:
+            if default:
+                msg += ' Y'
+            else:
+                msg += ' N'
+            _general_print('', NO_COLOR, msg)
+
+            return default
+    except KeyboardInterrupt:
+        sys.stdout.write('\n')
+        sys.exit(2)
+
+def choice(msg, choices, default=0):
+    if default >= len(choices):
+        return None
+    _general_print('\rQ', ASK_COLOR, '')
+    try:
+        msg += " [%s] " % '/'.join(choices)
+        if INTERACTIVE:
+            while True:
+                repl = raw_input(msg)
+                if repl in choices:
+                    return repl
+                elif not repl.strip():
+                    return choices[default]
+        else:
+            msg += choices[default]
+            _general_print('', NO_COLOR, msg)
+
+            return choices[default]
+    except KeyboardInterrupt:
+        sys.stdout.write('\n')
+        sys.exit(2)
+
+def pause(msg=None):
+    if INTERACTIVE:
+        _general_print('\rQ', ASK_COLOR, '')
+        if msg is None:
+            msg = 'press <ENTER> to continue ...'
+        raw_input(msg)
+
+def set_logfile(fpath):
+    global LOG_FILE_FP
+
+    def _savelogf():
+        if LOG_FILE_FP:
+            with open(LOG_FILE_FP, 'w') as log:
+                log.write(LOG_CONTENT)
+
+    if LOG_FILE_FP is not None:
+        warning('duplicate log file configuration')
+
+    LOG_FILE_FP = fpath
+
+    import atexit
+    atexit.register(_savelogf)
+
+def enable_logstderr(fpath):
+    global CATCHERR_BUFFILE_FD
+    global CATCHERR_BUFFILE_PATH
+    global CATCHERR_SAVED_2
+
+    if os.path.exists(fpath):
+        os.remove(fpath)
+    CATCHERR_BUFFILE_PATH = fpath
+    CATCHERR_BUFFILE_FD = os.open(CATCHERR_BUFFILE_PATH, os.O_RDWR|os.O_CREAT)
+    CATCHERR_SAVED_2 = os.dup(2)
+    os.dup2(CATCHERR_BUFFILE_FD, 2)
+
+def disable_logstderr():
+    global CATCHERR_BUFFILE_FD
+    global CATCHERR_BUFFILE_PATH
+    global CATCHERR_SAVED_2
+
+    raw(msg=None) # flush message buffer and print it.
+    os.dup2(CATCHERR_SAVED_2, 2)
+    os.close(CATCHERR_SAVED_2)
+    os.close(CATCHERR_BUFFILE_FD)
+    os.unlink(CATCHERR_BUFFILE_PATH)
+    CATCHERR_BUFFILE_FD = -1
+    CATCHERR_BUFFILE_PATH = None
+    CATCHERR_SAVED_2 = -1