2016-04-26 23:32:57 +00:00
|
|
|
import sys
|
2016-09-26 14:23:48 +00:00
|
|
|
import gc
|
|
|
|
|
2018-03-04 11:59:16 +00:00
|
|
|
from trezorutils import halt, memcpy, set_mode_unprivileged, symbol, model # noqa: F401
|
2016-04-27 19:07:37 +00:00
|
|
|
|
2017-06-14 17:34:23 +00:00
|
|
|
|
2018-04-03 18:38:12 +00:00
|
|
|
def unimport_begin():
|
|
|
|
return set(sys.modules)
|
|
|
|
|
|
|
|
|
|
|
|
def unimport_end(mods):
|
|
|
|
for mod in sys.modules:
|
|
|
|
if mod not in mods:
|
|
|
|
# remove reference from sys.modules
|
|
|
|
del sys.modules[mod]
|
|
|
|
# remove reference from the parent module
|
|
|
|
i = mod.rfind('.')
|
|
|
|
if i < 0:
|
|
|
|
continue
|
|
|
|
path = mod[:i]
|
|
|
|
name = mod[i + 1:]
|
|
|
|
delattr(sys.modules[path], name)
|
|
|
|
# collect removed modules
|
|
|
|
gc.collect()
|
2016-06-09 14:31:53 +00:00
|
|
|
|
2016-09-21 12:24:12 +00:00
|
|
|
|
2018-03-03 22:37:21 +00:00
|
|
|
def ensure(cond, msg=None):
|
2018-02-27 01:35:20 +00:00
|
|
|
if not cond:
|
2018-03-03 22:37:21 +00:00
|
|
|
if msg is None:
|
|
|
|
raise AssertionError()
|
|
|
|
else:
|
|
|
|
raise AssertionError(msg)
|
2018-02-27 01:35:20 +00:00
|
|
|
|
|
|
|
|
2017-06-14 17:34:23 +00:00
|
|
|
def chunks(items, size):
|
|
|
|
for i in range(0, len(items), size):
|
|
|
|
yield items[i:i + size]
|
2016-11-23 13:46:55 +00:00
|
|
|
|
|
|
|
|
2018-02-27 01:35:20 +00:00
|
|
|
def split_words(sentence, width, metric=len):
|
2018-02-27 02:33:59 +00:00
|
|
|
line = []
|
|
|
|
for w in sentence.split(' '):
|
2018-02-27 13:52:21 +00:00
|
|
|
# empty word -> skip
|
2018-02-27 02:33:59 +00:00
|
|
|
if not w:
|
|
|
|
continue
|
2018-02-27 13:52:21 +00:00
|
|
|
# new word will not fit -> break the line
|
2018-02-27 02:33:59 +00:00
|
|
|
if metric(' '.join(line + [w])) >= width:
|
|
|
|
yield ' '.join(line)
|
2018-02-27 13:52:21 +00:00
|
|
|
line = []
|
|
|
|
# word is too wide -> split the word
|
|
|
|
while metric(w) >= width:
|
|
|
|
for i in range(1, len(w) + 1):
|
|
|
|
if metric(w[:-i]) < width:
|
|
|
|
yield w[:-i] + '-'
|
|
|
|
w = w[-i:]
|
|
|
|
break
|
|
|
|
line.append(w)
|
2018-02-27 02:33:59 +00:00
|
|
|
yield ' '.join(line)
|
2018-02-06 17:35:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
def format_amount(amount, decimals):
|
|
|
|
d = pow(10, decimals)
|
|
|
|
amount = ('%d.%0*d' % (amount // d, decimals, amount % d)).rstrip('0')
|
|
|
|
if amount.endswith('.'):
|
2018-02-09 12:36:08 +00:00
|
|
|
amount = amount[:-1]
|
2018-02-06 17:35:14 +00:00
|
|
|
return amount
|
2018-02-25 14:05:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
def format_ordinal(number):
|
|
|
|
return str(number) + {1: 'st', 2: 'nd', 3: 'rd'}.get(4 if 10 <= number % 100 < 20 else number % 10, 'th')
|
2018-02-27 13:45:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
class HashWriter:
|
|
|
|
|
|
|
|
def __init__(self, hashfunc):
|
|
|
|
self.ctx = hashfunc()
|
|
|
|
self.buf = bytearray(1) # used in append()
|
|
|
|
|
|
|
|
def extend(self, buf: bytearray):
|
|
|
|
self.ctx.update(buf)
|
|
|
|
|
|
|
|
def append(self, b: int):
|
|
|
|
self.buf[0] = b
|
|
|
|
self.ctx.update(self.buf)
|
|
|
|
|
|
|
|
def get_digest(self, *args) -> bytes:
|
|
|
|
return self.ctx.digest(*args)
|