Skip to content

Commit

Permalink
Add support for complex arrays. "config types" not tested. No unittests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sigurdw committed Oct 30, 2011
1 parent a3310ec commit 4d18c94
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 145 deletions.
12 changes: 11 additions & 1 deletion CSjark/csjark/config.py
Expand Up @@ -85,7 +85,17 @@ def create_field(self, proto, name, ctype, size=None, alignment_size = None):

# Create basic Field if no rules fired
return proto.add_field(name, type_, size, alignment_size)


def get_field_attributes(self, name, ctype):
"""Create a field depending on rules."""
# Sort the rules
types = (Bitstring, Enum, Range, Custom)
values = [[], [], [], []]
for rule in self.get_rules(name, ctype):
for i, tmp in enumerate(types):
if isinstance(rule, tmp):
values[i].append(rule)
return values

class BaseRule:
"""A base class for rules referring to protocol fields."""
Expand Down
51 changes: 37 additions & 14 deletions CSjark/csjark/cparser.py
Expand Up @@ -232,7 +232,7 @@ def handle_array_decl(self, node, depth=None):

# String array
if (isinstance(child, c_ast.TypeDecl) and
child.children()[0].names[0] == 'char'):
hasattr(child.children()[0], 'names') and child.children()[0].names[0] == 'char'): #hack
size *= self.size_of('char')
return child.declname, 'string', size, self.alignment('char'), depth

Expand All @@ -244,29 +244,52 @@ def handle_array_decl(self, node, depth=None):

# Single dimensional normal array
depth.append(size)
ctype = self._get_type(child.children()[0])

if isinstance(child.children()[0], c_ast.IdentifierType):
ctype = self._get_type(child.children()[0])

# Support for typedef
if ctype in self.aliases:
token, ctype = self.aliases[ctype]
if token == 'array': # Hack I think
return child.declname, ctype[1], ctype[2], ctype[3], depth+ctype[4]
elif token is not None:
print(token, ctype) # TODO
raise ParseError('Incomplete support for array of typedefs')

return child.declname, ctype, self.size_of(ctype), self.alignment(ctype), depth
# Typedef type, which is an alias for another type
if ctype in self.aliases:
token, base = self.aliases[ctype]
if token in ('struct', 'union'):
subproto = self.all_protocols[base, self.platform]
return child.declname, subproto, subproto.get_size(), subproto.get_alignment_size(), depth
elif token == 'enum':
return child.declname, token, self.size_of(token), self.alignment(token), depth, self.enums[ctype]
elif token == 'array':
tmp, ctype, size, alignment, inner_depth = base
return child.declname, ctype, size, alignment, depth + inner_depth
else:
base_size = self.size_of(base)
base_alignment_size = self.alignment(base)
return child.declname, base, base_size, base_alignment_size, depth
else:
base_size = self.size_of(ctype)
base_alignment_size = self.alignment(ctype)
return child.declname, ctype, base_size, base_alignment_size, depth
# Enum
elif isinstance(child.children()[0], c_ast.Enum):
return child.declname, 'enum', self.size_of('enum'), self.alignment('enum'), depth, self.enums[child.children()[0].name]
# Union and struct
elif isinstance(child.children()[0], c_ast.Union) or isinstance(child.children()[0], c_ast.Struct):
subproto = self.all_protocols[child.children()[0].name, self.platform]
return child.declname, subproto, subproto.get_size(), subproto.get_alignment_size(), depth
# Error
else:

raise ParseError('Unknown type in array declaration: %s' % repr(child.children()[0]))

def handle_protocol(self, proto, name, proto_name):
"""Add an protocol field or union field to the protocol."""
sub_proto = StructVisitor.all_protocols[(proto_name, self.platform)]
return proto.add_protocol(name, sub_proto)

def handle_array(self, proto, name, ctype, size, alignment, depth):
def handle_array(self, proto, name, ctype, size, alignment, depth, enum_members = None):
"""Add an ArrayField to the protocol."""
if not depth:
return self.handle_field(proto, name, ctype, size, alignment)
return proto.add_array(name, self.map_type(ctype), size, alignment, depth)

return proto.add_array(name, ctype, size, alignment, depth, enum_members)

def handle_pointer(self, node, proto):
"""Find member details in a pointer declaration."""
Expand Down
1 change: 1 addition & 0 deletions CSjark/csjark/csjark.py
Expand Up @@ -157,6 +157,7 @@ def create_dissectors(filename):

# Silence errors if not in strict mode
except Exception as err:
Options.strict = 1
if Options.strict:
raise
else:
Expand Down

0 comments on commit 4d18c94

Please sign in to comment.