#This script is designed to run with Understand - CodeCheck use base ("Understand::Codecheck"); use strict; use constant ERR1 => 'Identifier %1 reused'; sub register_tr_text() { my $check = shift; $check->add_tr_text(ERR1); } sub name { return "5.7 No identifier name should be reused";} sub description { return "5.7 (Advisory): No identifier name should be reused";} sub detailed_description { return <<"END_DESC" Regardless of scope, no identifier should be re-used across any files in the system. This rule incorporates the provisions of Rules 5.2, 5.3, 5.4, 5.5 and 5.6. struct air_speed { uint16_t speed; /* knots */ } * x; struct gnd_speed { uint16_t speed; /* mph */ /* Not Compliant - speed is in different units */ } * y; x->speed = y->speed; Where an identifier name is used in a header file, and that header file is included in multiple source files, this rule is not violated. The use of a rigorous naming convention can support the implementation of this rule. The 'Exceptions' field can be used to bypass specific entities. The field can take one entity, or multiple entities separated by a comma ie., ent1,ent2,ent3 END_DESC } sub test_language { my $language = shift; return $language =~ /C\+\+/; #Handles C and C++ } sub test_entity { return 0;} sub test_global { return 1;} sub define_options{ my $check = shift; $check->option->text('exceptions','Exceptions',''); $check->option->checkbox('overloads','Ignore Overloads',''); } sub check { my $check = shift; my %entNames; my $prevent; my $prevParent; my @ents = $check->db->ents("~unknown ~unresolved ~unnamed"); my @exceptions = split(',',$check->option->lookup('exceptions')); foreach my $ent (sort {$a->name cmp $b->name;} @ents){ next if $ent->name ~~ @exceptions; if ($entNames{$ent->name}){ if($ent->kind("Function") && $check->option->lookup('overloads')){ next if($ent->parent && $ent->parent->id == $prevParent); } if ($prevent && reference($prevent)){ my $ref = reference($prevent); $check->violation($prevent,$ref->file,$ref->line,$ref->column,ERR1,$prevent->name); } my $ref = reference($ent); if($ref){ $check->violation($ent,$ref->file,$ref->line,$ref->column,ERR1,$ent->name); } else{ $check->violation(0,0,-1,-1,ERR1,$ent->name); } $prevent = ""; } else { $entNames{$ent->name} = 1; $prevParent = $ent->parent->id() if $ent->parent; $prevent = $ent; } } } sub reference { my $ent = shift; return unless $ent; my $defined = $ent->ref("definein, declarein"); return $defined if $defined; return $ent->ref if $ent->ref; return; }