#This script is designed to run with Understand - CodeCheck
use base ("Understand::Codecheck");
use strict;


use constant ERR1 => '#undef used';

sub register_tr_text() {
  my $check = shift;
  $check->add_tr_text(ERR1);
}

sub name { return "16-0-3 #undef shall not be used";}

sub description { return "16-0-3 (Required) #undef shall not be used";}

sub detailed_description { return <<"END_DESC"
<p><b>Rationale</b><br>
#undef should not normally be needed. Its use can lead to confusion with respect to the existence
or meaning of a macro when it is used in the code.
</p><b>Example</b><pre style="margin-top:0;padding-top:0;">
  #ifndef MY_HDR
  #define MY_HDR
  #undef MY_HDR // Non-compliant
  #endif</pre>
END_DESC
}

sub test_language {
  my $language = shift;
  return $language =~ /C\+\+/; #Handles C and C++
}

sub test_entity { return 1;}

sub test_global { return 0;}

sub define_options{}

sub check {
  my $check = shift; 
  my $file = shift; 
  return unless $file->kind->check("file ~unknown ~unresolved");
  return unless $file->filerefs("use","macro");
  
  my $lexer = $file->lexer;
  return unless $lexer;
  my $findEnt = 0;
  foreach my $lexeme ($lexer->lexemes()) {
    if ($lexeme->text eq "undef" && $lexeme->token eq "Preprocessor"){
        $findEnt = 1;
    }elsif($findEnt && $lexeme->ent){
        $check->violation($lexeme->ent,$file,$lexeme->line_begin,$lexeme->column_begin,ERR1); 
        $findEnt=0;
    }
  }
}