from click import secho
from ccrawl.formatters.amoco import id_amoco, c_type, cxx_type, fieldformat
from pyparsing import ParseException
try:
import os
os.environ["AMOCO_LOG_LEVEL"]=u"ERROR"
from amoco.system.structs import (
Alltypes,
Consts,
TypeDefine,
StructDefine,
UnionDefine,
StructFormatter,
)
except ImportError:
secho("amoco package not found", fg="red")
def build(t, db, _bstack=[]):
raise NotImplementedError
else:
def build(obj, db, _bstack=[]):
if obj._is_class:
x = obj.as_cStruct(db)
x.unfold(db)
return build(x, db)
name = id_amoco(obj.identifier)
if obj.identifier in _bstack:
return Alltypes.get(name, None)
else:
_bstack.append(obj.identifier)
if obj.subtypes is None:
obj.unfold(db)
for subtype in (obj.subtypes.values() or []):
if subtype is None:
continue
build(subtype, db, _bstack)
if obj._is_typedef:
t = c_type(obj)
rn, n = fieldformat(t)
TypeDefine(name, rn or n)
return Alltypes[name]
if obj._is_macro:
v = obj.strip()
try:
v = int(v, base=0)
except ValueError:
pass
try:
t = c_type(v)
rn, n = fieldformat(t)
TypeDefine(name, rn or n)
return Alltypes[name]
except ParseException:
pass
globals()[name] = v
return v
if obj._is_enum:
if len(obj) < 256:
sz = "b"
elif len(obj) < (1 << 16):
sz = "h"
else:
sz = "i"
TypeDefine(name, sz)
Consts.All[name] = {}.update(obj)
elif obj._is_struct or obj._is_union:
define = StructDefine
if obj._is_union:
define = UnionDefine
cls = type(name, (StructFormatter,), {})
fmt = []
# if the structure is a bitfield, we
# gather fields as long as they are part of
# the bitfield...
bfmt = []
for t, n, c in iter(obj):
if c and c.count("\n") > 0:
c = None
r = c_type(t)
if r.lbfw > 0:
bfmt.append((r, n))
continue
else:
fmt.extend(format_bitfield(bfmt))
if not n and not r.lbase.startswith("union "):
continue
rt, t = fieldformat(r)
fmt.append("{} : {} ;{}".format(rt or t, n, c or ""))
fmt.extend(format_bitfield(bfmt))
fmt = "\n".join(fmt)
define(fmt)(cls)
else:
raise NotImplementedError
return Alltypes[name]
def format_bitfield(bfmt):
fmt = []
while bfmt:
cur = [bfmt.pop(0)]
basetype = cur[0][0].lbase
sz = Alltypes[cur[0][0].lbase].size() * 8
tot = cur[0][0].lbfw
while bfmt:
if bfmt[0][0].lbase == cur[0][0].lbase:
if (tot + (bfmt[0][0].lbfw)) <= sz:
tot += bfmt[0][0].lbfw
cur.append(bfmt.pop(0))
else:
break
else:
break
lt, ln = list(zip(*cur))
r = lt[0]
rt, t = fieldformat(r)
n = "/".join(ln)
t += "".join(["/%d" % x.lbfw for x in lt[1:]])
fmt.append("{} : {} ;{}".format(t, n, ""))
return fmt
def get_c_or_cxx_type(x):
if not (('&' in x) or ('::' in x)):
try:
t = c_type(x)
except pp.ParseException:
pass
else:
return t
t = cxx_type(x)
return t
A_to_C = {
'P' : 'void*',
'b' : 'char',
'c' : 'char',
'B' : 'unsigned char',
'h' : 'short',
'H' : 'unsigned short',
'i' : 'int',
'I' : 'unsigned int',
'l' : 'long',
'L' : 'unsigned long',
'q' : 'long long',
'Q' : 'unsigned long long',
}
__r = 0
[docs]def to_ccore(ax,identifier,**kargs):
"""
Translate an amoco StructCore type to a ccrawl.ccore object,
thus allowing to export this object to any supported format.
The interface to amoco's StructCore uses its '.typedef' and '.union'
attributes as well as its fields attribute list,
where each field must have:
- a typename attribute
- a subnames/subsizes attribute(s) for bitfields
- a comment attribute
- a count attribute
- a name attribute
"""
from ccrawl.core import ccore
global __r
subs = []
if ax.typedef:
t = ax.fields[0].typename
if t in A_to_C:
t = A_to_C[t]
else:
if t in Alltypes:
subs.append(to_ccore(Alltypes[t],t))
c = ccore.getcls("cTypedef")(t)
else:
if not ax.union:
c = ccore.getcls("cStruct")()
else:
c = ccore.getcls("cUnion")()
ccore.unfold(c,None)
for f in ax.fields:
t = f.typename
if t in A_to_C:
t = A_to_C[t]
else:
if t in Alltypes:
subs.append(to_ccore(Alltypes[t],t))
if hasattr(f,'subnames'):
for sn,ss in zip(f.subnames,f.subsizes):
if sn=="_":
sn = "reserved_%s"%__r
__r+=1
c.append([t+' # %d'%ss, sn, f.comment])
else:
fn = f.name
if fn=="_":
fn = "reserved_%d"%__r
__r+=1
if f.count>0:
t += "[%d]"%f.count
c.append([t,fn,f.comment])
c.identifier = identifier
for sc in subs:
c.subtypes[sc.identifier] = sc
return c