#-------------------------------------------------------------------------------
# Copyright (C) 2016  DjAlex88 (https://github.com/djalex88/)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#-------------------------------------------------------------------------------


__all__ = ['log', 'error', 'set_log_file', 'close_log_file', 'chunk', 'chain', 'repeat', 'to_hex', 'Raise']

import sys
from itertools import chain, repeat

log_file = None

def set_log_file(f):
	global log_file
	log_file = f

def close_log_file():
	global log_file
	if log_file != None:
		log_file.close() ; log_file = None

def log(*args):
	s = '\x20'.join(str(x) for x in args)
	print s
	if log_file != None: print >> log_file, s

def error(*args):
	s = '\x20'.join(str(x) for x in args)
	print >> sys.stderr, s
	if log_file != None: print >> log_file, s

def to_hex(s):
	return '\x20'.join('%02X'%ord(x) for x in s)

def chunk(seq, sublen):
	return [seq[i:i+sublen] for i in xrange(0, len(seq), sublen)]

# Wrapper for raise Exception(message) statement so it can be used in expressions
def Raise(message):
	raise Exception(message)

@@ -1376,21 +1376,36 @@
 _hex', '
-Raise
+print_last_exception
 '%5D%0A%0Aimpo
@@ -1448,33 +1448,16 @@
 repeat%0A%0A
-log_file = None%0A%0A
 def set_
@@ -1987,132 +1987,269 @@
 )%5D%0A%0A
-# Wrapper for raise Exception(message) statement so it can be used in expressions%0Adef Raise(message):%0A%09raise Exception(message)
+def print_last_exception():%0A%09t, e, tb = sys.exc_info()%0A%09error( repr(e) )%0A%09i = 0%0A%09while tb:%0A%09%09c = tb.tb_frame.f_code%0A%09%09error( '%5Cx20%5Cx20'*i + '--Function: %22%25s%22 in %22%25s%22, line: %25i' %25 (c.co_name, c.co_filename, tb.tb_lineno) )%0A%09%09tb = tb.tb_next ; i+= 1%0A%0Alog_file = None
 %0A

Update _common.py