You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

160 lines
3.5 KiB

#!/usr/bin/python
#
# Python utilities shared by the build scripts.
#
import datetime
import json
class BitEncoder:
"Bitstream encoder."
_bits = None
def __init__(self):
self._bits = []
def bits(self, x, nbits):
if (x >> nbits) != 0:
raise Exception('input value has too many bits (value: %d, bits: %d)' % (x, nbits))
for i in xrange(nbits):
t = (x >> (nbits - i - 1)) & 0x01
self._bits.append(t)
def string(self, x):
nbits = len(x) * 8
for i in xrange(nbits):
byteidx = i / 8
bitidx = i % 8
if byteidx < 0 or byteidx >= len(x):
self._bits.append(0)
else:
t = (ord(x[byteidx]) >> (7 - bitidx)) & 0x01
self._bits.append(t)
def getNumBits(self):
"Get current number of encoded bits."
return len(self._bits)
def getNumBytes(self):
"Get current number of encoded bytes, rounded up."
nbits = len(self._bits)
while (nbits % 8) != 0:
nbits += 1
return nbits / 8
def getBytes(self):
"Get current bitstream as a byte sequence, padded with zero bits."
bytes = []
for i in xrange(self.getNumBytes()):
t = 0
for j in xrange(8):
off = i*8 + j
if off >= len(self._bits):
t = (t << 1)
else:
t = (t << 1) + self._bits[off]
bytes.append(t)
return bytes
def getByteString(self):
"Get current bitstream as a string."
return ''.join([chr(i) for i in self.getBytes()])
class GenerateC:
"Helper for generating C source and header files."
_data = None
wrap_col = 76
def __init__(self):
self._data = []
def emitRaw(self, text):
"Emit raw text (without automatic newline)."
self._data.append(text)
def emitLine(self, text):
"Emit a raw line (with automatic newline)."
self._data.append(text + '\n')
def emitHeader(self, autogen_by):
"Emit file header comments."
# Note: a timestamp would be nice but it breaks incremental building
self.emitLine('/*')
self.emitLine(' * Automatically generated by %s, do not edit!' % autogen_by)
self.emitLine(' */')
self.emitLine('')
def emitArray(self, data, tablename, typename='char', bytesize=None, intvalues=False, const=True):
"Emit an array as a C array."
# lenient input
if isinstance(data, unicode):
data = data.encode('utf-8')
if isinstance(data, str):
tmp = []
for i in xrange(len(data)):
tmp.append(ord(data[i]))
data = tmp
size_spec = ''
if bytesize is not None:
size_spec = '%d' % bytesize
const_qual = ''
if const:
const_qual = 'const '
self.emitLine('%s%s %s[%s] = {' % (const_qual, typename, tablename, size_spec))
line = ''
for i in xrange(len(data)):
if intvalues:
t = "%d," % data[i]
else:
t = "(%s)'\\x%02x', " % (typename, data[i])
if len(line) + len(t) >= self.wrap_col:
self.emitLine(line)
line = t
else:
line += t
if line != '':
self.emitLine(line)
self.emitLine('};')
def emitDefine(self, name, value, comment=None):
"Emit a C define with an optional comment."
# XXX: there is no escaping right now (for comment or value)
if comment is not None:
self.emitLine('#define %-60s %-30s /* %s */' % (name, value, comment))
else:
self.emitLine('#define %-60s %s' % (name, value))
def getString(self):
"Get the entire file as a string."
return ''.join(self._data)
def json_encode(x):
"JSON encode a value."
try:
return json.dumps(x)
except AttributeError:
pass
# for older library versions
return json.write(x)
def json_decode(x):
"JSON decode a value."
try:
return json.loads(x)
except AttributeError:
pass
# for older library versions
return json.read(x)