use base ("Understand::IReport"); sub name { return "Struct Report"; } sub test_entity { my $entity = shift; return is_struct($entity) ? 1 : -1; } sub test_global { return 0; } sub init { my $report = shift; } sub generate { my $report = shift; my $entity = shift; if ($entity) { print_struct($report, $entity, 0); } } sub is_struct { my $entity = shift; return ($entity->kind->check("struct ~unresolved") || # struct ($entity->kind->check("typedef") && # typedef $entity->ref("typed","struct"))); # to struct } sub print_struct { my $report = shift; my $entity = shift; my $depth = shift; $report->tree($depth + 1, 1); $report->entity($entity); $report->bold; $report->print($entity->longname); $report->nobold; $report->entity; my $struct = $entity; if ($entity->kind->check("typedef")) { ($struct) = $entity->ents("typed", "struct"); } foreach my $member ($struct->ents("define","member")) { if (is_struct($member)) { print_struct($report, $member, $depth + 1); } else { $report->tree($depth + 2, 1); $report->entity($member); $report->print($member->name); $report->entity; foreach my $ref ($member->refs("useby,setby,modifyby,callby")) { my $lexer = $ref->file->lexer(1); my $lexeme = $lexer->lexeme($ref->line, $ref->column); my $object = $lexeme->previous->previous->ent; # Could use some other heuristics to find the object. $report->tree($depth + 3, 1); $report->syncfile($ref->file, $ref->line, $ref->column); $report->print($ref->kindname); $report->print(" in "); $report->entity($ref->ent); $report->fontcolor("blue"); $report->print($ref->ent->longname); $report->entity; $report->fontcolor("black"); if ($object) { $report->print(" on "); $report->entity($object); $report->fontcolor("red"); $report->print($object->longname); $report->entity; $report->fontcolor("black"); } $report->syncfile; } } } }