def test_field_is_not_read_only(self): self.assertFalse( ir_util.field_is_read_only( ir_pb2.Field(location=ir_pb2.FieldLocation()))) self.assertFalse( ir_util.field_is_read_only( ir_pb2.Field(write_method=ir_pb2.WriteMethod())))
def _add_size_virtuals(structure, type_definition): """Adds a $size_in_bits or $size_in_bytes virtual field to structure.""" names = { ir_pb2.TypeDefinition.BIT: "$size_in_bits", ir_pb2.TypeDefinition.BYTE: "$size_in_bytes", } size_field_name = names[type_definition.addressable_unit] size_clauses = [] for field in structure.field: # Virtual fields do not have a physical location, and thus do not contribute # to the size of the structure. if ir_util.field_is_virtual(field): continue size_clause = ir_pb2.Expression() size_clause.CopyFrom(_SIZE_CLAUSE_SKELETON) # Copy the appropriate clauses into `existence_condition ? start + size : 0` size_clause.function.args[0].CopyFrom(field.existence_condition) size_clause.function.args[1].function.args[0].CopyFrom( field.location.start) size_clause.function.args[1].function.args[1].CopyFrom( field.location.size) size_clauses.append(size_clause) size_expression = ir_pb2.Expression() size_expression.CopyFrom(_SIZE_SKELETON) size_expression.function.args.extend(size_clauses) _mark_as_synthetic(size_expression) size_field = ir_pb2.Field( read_transform=size_expression, name=ir_pb2.NameDefinition(name=ir_pb2.Word(text=size_field_name)), existence_condition=ir_pb2.Expression( boolean_constant=ir_pb2.BooleanConstant(value=True)), attribute=[_skip_text_output_attribute()]) structure.field.extend([size_field])
def _add_size_bound_virtuals(structure, type_definition): """Adds ${min,max}_size_in_{bits,bytes} virtual fields to structure.""" names = { ir_pb2.TypeDefinition.BIT: ("$max_size_in_bits", "$min_size_in_bits"), ir_pb2.TypeDefinition.BYTE: ("$max_size_in_bytes", "$min_size_in_bytes"), } for name in names[type_definition.addressable_unit]: bound_field = ir_pb2.Field( read_transform=_SIZE_BOUNDS[name], name=ir_pb2.NameDefinition(name=ir_pb2.Word(text=name)), existence_condition=expression_parser.parse("true"), attribute=[_skip_text_output_attribute()]) _mark_as_synthetic(bound_field.read_transform) structure.field.extend([bound_field])
def test_field_is_read_only(self): self.assertTrue( ir_util.field_is_read_only( ir_pb2.Field(write_method=ir_pb2.WriteMethod(read_only=True))))
def test_field_is_not_virtual(self): self.assertFalse( ir_util.field_is_virtual( ir_pb2.Field(location=ir_pb2.FieldLocation())))
def test_field_is_virtual(self): self.assertTrue(ir_util.field_is_virtual(ir_pb2.Field()))
def _add_anonymous_aliases(structure, type_definition): """Adds synthetic alias fields for all fields in anonymous fields. This essentially completes the rewrite of this: struct Foo: 0 [+4] bits: 0 [+1] Flag low 31 [+1] Flag high Into this: struct Foo: bits EmbossReservedAnonymous0: [text_output: "Skip"] 0 [+1] Flag low 31 [+1] Flag high 0 [+4] EmbossReservedAnonymous0 emboss_reserved_anonymous_1 let low = emboss_reserved_anonymous_1.low let high = emboss_reserved_anonymous_1.high Note that this pass runs very, very early -- even before symbols have been resolved -- so very little in ir_util will work at this point. Arguments: structure: The ir_pb2.Structure on which to synthesize fields. type_definition: The ir_pb2.TypeDefinition containing structure. Returns: None """ new_fields = [] for field in structure.field: new_fields.append(field) if not field.name.is_anonymous: continue field.attribute.extend([_skip_text_output_attribute()]) for subtype in type_definition.subtype: if (subtype.name.name.text == field.type.atomic_type.reference.source_name[-1].text): field_type = subtype break else: assert False, ( "Unable to find corresponding type {} for anonymous field " "in {}.".format(field.type.atomic_type.reference, type_definition)) anonymous_reference = ir_pb2.Reference(source_name=[field.name.name]) anonymous_field_reference = ir_pb2.FieldReference( path=[anonymous_reference]) for subfield in field_type.structure.field: alias_field_reference = ir_pb2.FieldReference(path=[ anonymous_reference, ir_pb2.Reference(source_name=[subfield.name.name]), ]) new_existence_condition = ir_pb2.Expression() new_existence_condition.CopyFrom( _ANONYMOUS_BITS_ALIAS_EXISTENCE_SKELETON) existence_clauses = new_existence_condition.function.args existence_clauses[0].function.args[0].field_reference.CopyFrom( anonymous_field_reference) existence_clauses[1].function.args[0].field_reference.CopyFrom( alias_field_reference) new_read_transform = ir_pb2.Expression( field_reference=alias_field_reference) # This treats *most* of the alias field as synthetic, but not its name(s): # leaving the name(s) as "real" means that symbol collisions with the # surrounding structure will be properly reported to the user. _mark_as_synthetic(new_existence_condition) _mark_as_synthetic(new_read_transform) new_alias = ir_pb2.Field( read_transform=new_read_transform, existence_condition=new_existence_condition, name=subfield.name) if subfield.HasField("abbreviation"): new_alias.abbreviation.CopyFrom(subfield.abbreviation) _mark_as_synthetic(new_alias.existence_condition) _mark_as_synthetic(new_alias.read_transform) new_fields.append(new_alias) # Since the alias field's name(s) are "real," it is important to mark the # original field's name(s) as synthetic, to avoid duplicate error # messages. _mark_as_synthetic(subfield.name) if subfield.HasField("abbreviation"): _mark_as_synthetic(subfield.abbreviation) del structure.field[:] structure.field.extend(new_fields)