.NAME Break and goto in loops

.DESCRIPTION
	For any iteration statement there shall be no more than 
one break or goto statement used for loop termination. 

.COMMENT V7.0

.SEVERITY Required

.COMMENT
Please refer to the MISRA C++:2008 document for further details (www.misra-cpp.com)

.COMMAND tcl

.CODE

::logiscope::include -once common utilities.tcl

proc compute {standardName tree} {
  variable CurrentParameterList

  # Check all ... nodes
  utilities::filterTree $tree [list [namespace current]::check]
}

proc check { node } {
  # Check if we are in an iteration statement (for, while, do)
  set curName [::utilities::getName $node]
  if {[expr [lsearch "for while do" $curName] != -1]} {
    # Check the number of break statements in the sub-tree
	set nbBreaks [checkBreaks $node 0]
	if {[expr $nbBreaks >= 2]} {
	  return 0
	}
  }
return 1
}

# This recursive procedure counts the number of break statements: only one is allowed
proc checkBreaks {node nbBreaks} {
  set curOperator [::logiscope::treeOperator $node]
  set curOperatorName [::logiscope::opName $curOperator]
  # If it is switch statement do not consider breaks
  if {[string equal $curOperatorName switch]} {
      return  $nbBreaks
  }
  # If the node is a break statement, count it
  if { [expr [lsearch [list goto break] [::utilities::getName $node]] != -1] } {
    # From the second break onwards, violations are generated
	if {[expr $nbBreaks >= 1]} {
	  ::logiscope::addViolation $node
	}
	# Return 1 since we found a break
    return 1
  } else {
    # If the node is not a break statement, recurse on its children
	set foundNbBreaks 0
	::logiscope::forobj curChild $node treeChild {
	  set childNbBreaks [checkBreaks $curChild [expr $nbBreaks + $foundNbBreaks]]
	  set foundNbBreaks [expr $childNbBreaks + $foundNbBreaks]
    }
	return $foundNbBreaks
  }
}
