Add some classes to be able to store retrieved data from structure and messages. The idea is to generate code dynamically when variable are read. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- python_modules/dissector.py | 104 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/python_modules/dissector.py b/python_modules/dissector.py index ea13033..10da2e7 100644 --- a/python_modules/dissector.py +++ b/python_modules/dissector.py @@ -67,6 +67,106 @@ def write_parser_helpers(writer): writer.writeln('#endif') writer.newline() +# generate code to declare a variable only when needed +# code is generated only when we read the reference +class Reference: + def __init__(self, writer, name): + self.defined = False + self.written = False + self.name = name + # create a subwriter to write code to read variable only once + self.writer = writer.get_subwriter() + + def write(self, size, value, scope): + if not size in (8, 16, 32, 64): + raise Exception('Unknown size %d for %s' % (size, self.name)) + assert(not self.defined or (value, size) == (self.value, self.size)) + if not self.defined: + self.value = value + self.size = size + self.scope = scope + self.defined = True + + def read(self): + # variable not yet defined + assert(self.defined) + if not self.written: + assert(not self.scope.variable_defined(self.name)) + t = { 8: 'guint32', 16: 'guint32', 32: 'guint32', 64: 'guint64' }[self.size] + self.scope.variable_def(t, self.name) + self.writer.assign(self.name, self.value) + self.written = True + return self.name + +class Level: + def __init__(self, n=0): + self.level = n + def __enter__(self): + self.level += 1 + def __exit__(self, exc_type, exc_value, traceback): + self.level -= 1 + def __getattr__(self, name): + if not name in {'tree', 'ti'}: + raise Exception('Not possible to get name %s' % name) + return name if self.level == 0 else name + str(self.level) + +# represent part of a destination to write to +# for instance if we are parsing a structure dest represent that structure output +class Destination: + def __init__(self, scope): + self.refs = {} + self.is_helper = False + self.reuse_scope = scope + self.parent_dest = None + self.level = Level() + + def child_sub(self, member, scope): + return SubDestination(self, member, scope) + + def declare(self, writer): + return writer.optional_block(self.reuse_scope) + + def is_toplevel(self): + return self.parent_dest == None and not self.is_helper + + def read_ref(self, member): + return self.get_ref(member).read() + + def write_ref(self, writer, size, member, value): + ref = self.get_ref(member, writer) + ref.write(size, value, self.reuse_scope) + + def ref_size(self, member): + return self.get_ref(member).size + +class RootDestination(Destination): + def __init__(self, scope): + Destination.__init__(self, scope) + self.base_var = "fld" + + def get_ref(self, member, writer=None): + name = (self.base_var + "." + member).replace('.', '__') + if name in self.refs: + return self.refs[name] + if not writer: + raise Exception('trying to read a reference to %s' % member) + self.refs[name] = ref = Reference(writer, name) + return ref + + def declare(self, writer): + return writer.no_block(self.reuse_scope) + +class SubDestination(Destination): + def __init__(self, parent_dest, member, scope): + Destination.__init__(self, scope) + self.parent_dest = parent_dest + self.member = member + self.level = parent_dest.level + + def get_ref(self, member, writer=None): + return self.parent_dest.get_ref(self.member + "." + member, writer) + + def write_msg_parser(writer, message, server): msg_name = message.c_name() function_name = "dissect_spice_%s_%s" % ('server' if server else 'client', msg_name) @@ -81,7 +181,9 @@ def write_msg_parser(writer, message, server): writer.ifdef(message) parent_scope = writer.function(function_name, "guint32", - "GlobalInfo *glb _U_, proto_tree *tree0 _U_, guint32 offset", True) + "GlobalInfo *glb _U_, proto_tree *tree _U_, guint32 offset", True) + + dest = RootDestination(parent_scope) writer.statement("return offset") writer.end_block() -- 2.1.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel