#This script is designed to run with Understand - CodeCheck use base ("Understand::Codecheck"); use strict; use constant ERR1 => 'Comment appears to contain code'; our @keywords = qw(double not_eq throw and_eq dynamic_cast operator true asm try auto enum or_eq typedef bitand explicit private typeid bitor extern protected typename bool false public union float register unsigned case reinterpret-cast using catch friend virtual char goto short void class signed volatile compl inline sizeof wchar_t const int static const-cast long static_cast xor continue mutable struct xor_eq default namespace switch delete new template); our @strongKeywordsRegExp = ('for\s*\(' , 'while\s*\(' , 'if\s*\('); our @preProc = ("#include", "#define", "#endif","#ifndef", "#ifdef"); our @strongLineEnds = (";","{"); our @maybeLineEnds = (")"); our $multiRatio = .4; sub register_tr_text() { my $check = shift; $check->add_tr_text(ERR1); } sub name { return "2-7-2 Sections of code should not be \"commented out\" using C-style comments";} sub description { return "2-7-2 (Required) Sections of code should not be \"commented out\" using C-style comments.";} sub detailed_description { return <<"END_DESC"

Rationale
Using C-style start and end comment markers for this purpose is dangerous because C-style comments do not support nesting, and any comments already existing in the section of code would change the effect.

Additionally, comments should only be used to explain aspects of the code that may not be clear from the source code itself. Code that is commented-out may become out of date, which may lead to confusion when maintaining the code.

A more appropriate method of recording the history of changes in source code (e.g. a Source Control System) should be used instead of commenting-out.

Example
  void fn ( int32_t i ) 
  { 
     /* 
        ++i;      /* We want to increment "i" */ 
     */
     for ( int32_t j = 0 ; j != i ; ++j ) 
     { 
     } 
  }

See Also
Rule 2-7-1, Rule 2-7-3

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{ my $check = shift; $check->option->radio_vert("strict","Aggresivness",["More Aggresive - may result in false positives, comments that are not really code", "Less Aggressive - may result in missing instances of commented code"],"Less Aggressive - may result in missing instances of commented code"); } sub check { my $check = shift; my $file = shift; return unless $file->kind->check("file"); my $lexer = $file->lexer; return unless $lexer; my $lexeme = $lexer->first; return unless $lexeme; my $reported = 0; LEXEME:foreach my $lexeme($lexer->lexemes()){ $reported=0 unless $lexeme->token =~ /Comment|Whitespace|Newline/; next LEXEME unless $lexeme->token eq "Comment"; my $comment = $lexeme->text; next LEXEME if $comment =~ '^//'; $comment =~ s'^/\*|^//|\*/$''g; #Strip comment character my $isCode = 0; my $maybeCode =0; my $lineNum=$lexeme->line_begin; my $codeLine=0; my $strict = $check->option->lookup("strict") =~ /More Aggresive/; #consider each line of the comment separately LINE:foreach my $line (split('\n',$comment)){ my ($strongCode, $strongEnd,$weakCode, $weakEnd,$preproc); $line =~ s/^\s+//; #trim leading whitespace $line =~ s/\s+$//; #trim trailing whitespace #Test for preprocessors in comments foreach my $word (@preProc){ $preproc = 1 if $line =~ /\Q$word/; } #Test for strong keyword match foreach my $test (@strongKeywordsRegExp){ $strongCode = 1 if $line =~ /(?line_begin); $isCode = 1 if $maybeCode && $totalLines > 2 && (($maybeCode / $totalLines) > $multiRatio); if (!$reported && $isCode){ $check->violation(0,$file,$codeLine,-1,ERR1); $reported=1; } } @keywords = (); @strongKeywordsRegExp = (); @preProc = (); @strongLineEnds = (); @maybeLineEnds = (); $multiRatio = 0; }