parent
32403b618e
commit
e6df94cbd5
@ -1,5 +1,12 @@
|
||||
def hexlify(data: bytes) -> str:
|
||||
return ''.join(['%02x' % b for b in data])
|
||||
import sys
|
||||
import gc
|
||||
|
||||
def unhexlify(data: str) -> bytes:
|
||||
return bytes([int(data[i:i+2], 16) for i in range(0, len(data), 2)])
|
||||
def unimport(func):
|
||||
def inner(*args, **kwargs):
|
||||
mods = set(sys.modules)
|
||||
ret = func(*args, **kwargs)
|
||||
for to_remove in set(sys.modules) - mods:
|
||||
print(to_remove)
|
||||
del sys.modules[to_remove]
|
||||
return ret
|
||||
return inner
|
||||
|
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
CURDIR=$(pwd)
|
||||
|
||||
|
||||
for i in messages types storage ; do
|
||||
|
||||
# Compile .proto files to python2 modules using google protobuf library
|
||||
cd $CURDIR/../../trezor-common/protob
|
||||
protoc --python_out=$CURDIR/pb2/ -I/usr/include -I. $i.proto
|
||||
|
||||
# Convert google protobuf library to trezor's internal format
|
||||
cd $CURDIR
|
||||
./pb2py $i ../src/trezor/messages/
|
||||
done
|
||||
|
@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
|
||||
|
||||
def process_type(t, cls):
|
||||
imports = ["from protobuf import protobuf as p",]
|
||||
|
||||
out = ["t = p.MessageType()", ]
|
||||
|
||||
print("Processing type %s" % t)
|
||||
|
||||
TYPE_STRING = 9
|
||||
TYPE_BYTES = 12
|
||||
|
||||
TYPE_MESSAGE = 11
|
||||
|
||||
for k, v in cls.DESCRIPTOR.fields_by_name.items():
|
||||
|
||||
#print k
|
||||
|
||||
number = v.number
|
||||
fieldname = k
|
||||
type = None
|
||||
repeated = v.label == 3
|
||||
required = v.label == 2
|
||||
|
||||
#print v.has_default_value, v.default_value
|
||||
|
||||
if v.type in (4, 13, 14):
|
||||
# TYPE_UINT64 = 4
|
||||
# TYPE_UINT32 = 13
|
||||
# TYPE_ENUM = 14
|
||||
type = 'p.UVarintType'
|
||||
|
||||
elif v.type == 9:
|
||||
# TYPE_STRING = 9
|
||||
type = 'p.UnicodeType'
|
||||
|
||||
elif v.type == 8:
|
||||
# TYPE_BOOL = 8
|
||||
type = 'p.BoolType'
|
||||
|
||||
elif v.type == 12:
|
||||
# TYPE_BYTES = 12
|
||||
type = 'p.BytesType'
|
||||
|
||||
elif v.type == 11:
|
||||
# TYPE_MESSAGE = 1
|
||||
type = "p.EmbeddedMessage(%s)" % v.message_type.name
|
||||
imports.append("from .%s import %s" % (v.message_type.name, v.message_type.name))
|
||||
|
||||
else:
|
||||
raise Exception("Unknown field type %s for field %s" % (v.type, k))
|
||||
|
||||
if repeated:
|
||||
flags = ', flags=p.FLAG_REPEATED'
|
||||
elif required:
|
||||
flags = ', flags=p.FLAG_REQUIRED'
|
||||
else:
|
||||
flags = ''
|
||||
|
||||
if v.has_default_value:
|
||||
default = ', default=%s' % repr(v.default_value)
|
||||
else:
|
||||
default = ''
|
||||
|
||||
out.append("t.add_field(%d, '%s', %s%s%s)" % \
|
||||
(number, fieldname, type, flags, default))
|
||||
|
||||
#print fieldname, number, type, repeated, default
|
||||
#print v.__dict__
|
||||
#print v.CPPTYPE_STRING
|
||||
#print v.LABEL_REPEATED
|
||||
#print v.enum_type
|
||||
# v.has_default_value, v.default_value
|
||||
# v.label == 3 # repeated
|
||||
#print v.number
|
||||
|
||||
out.append("%s = t" % t)
|
||||
return imports + out
|
||||
|
||||
def process_enum(t, cls):
|
||||
out = []
|
||||
|
||||
print("Processing enum %s" % t)
|
||||
|
||||
for k, v in cls.items():
|
||||
# Remove type name from the beginning of the constant
|
||||
# For example "PinMatrixRequestType_Current" -> "Current"
|
||||
if k.startswith("%s_" % t):
|
||||
k = k.replace("%s_" % t, '')
|
||||
|
||||
# If type ends with *Type, but constant use type name without *Type, remove it too :)
|
||||
# For example "ButtonRequestType & ButtonRequest_Other" => "Other"
|
||||
if t.endswith("Type") and k.startswith("%s_" % t.replace("Type", '')):
|
||||
k = k.replace("%s_" % t.replace("Type", ''), '')
|
||||
|
||||
out.append("%s = %s" % (k, v))
|
||||
|
||||
return out
|
||||
|
||||
def process_module(mod, genpath):
|
||||
types = dict([(name, cls) for name, cls in mod.__dict__.items() if isinstance(cls, type)])
|
||||
|
||||
for t, cls in types.iteritems():
|
||||
out = process_type(t, cls)
|
||||
write_to_file(genpath, t, out)
|
||||
|
||||
enums = dict([(name, cls) for name, cls in mod.__dict__.items() if isinstance(cls, EnumTypeWrapper)])
|
||||
|
||||
for t, cls in enums.iteritems():
|
||||
out = process_enum(t, cls)
|
||||
write_to_file(genpath, t, out)
|
||||
|
||||
def write_to_file(genpath, t, out):
|
||||
# Write generated sourcecode to given file
|
||||
f = open(os.path.join(genpath, "%s.py" % t), 'w')
|
||||
out = ["# Automatically generated by ./pb2py"] + out
|
||||
|
||||
data = "\n".join(out)
|
||||
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: ./pb2py modulename genpath")
|
||||
sys.exit()
|
||||
|
||||
modulename = sys.argv[1]
|
||||
genpath = sys.argv[2]
|
||||
|
||||
# Dynamically load module from argv[1]
|
||||
tmp = __import__('pb2', globals(), locals(), ['%s_pb2' % modulename])
|
||||
mod = getattr(tmp, "%s_pb2" % modulename)
|
||||
|
||||
process_module(mod, genpath)
|
Loading…
Reference in new issue