.NAME Defined preprocessor operator

.DESCRIPTION
The defined preprocessor operator shall only be used in 
one of the two standard forms. 

.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 if nodes
  utilities::filterTree $tree [list [namespace current]::check]
}

proc check { node } {
	if { [::utilities::isTreeOperator $node pp_if] } {
		set pp_text [::logiscope::treeDown $node 0]
		# get all lines of content
		set content ""
		::logiscope::forobj line $pp_text treeChild {
			set content $content[::utilities::treeAtomString $line]
		}
		# suppress comments
		set idx [string first // $content]
		if { $idx >= 0 } {
			incr idx -1
			set content [string range $content 0 $idx]
		}
		set idx [string first /* $content]
		if { $idx >= 0 } {
			set idy [string first */ $content $idx]
			if { $idy >= 0 } {
				incr idx -1
				incr idy 2
				set content "[string range $content 0 $idx][string range $content $idy end]"
			} else {
				incr idx -1
				set content [string range $content 0 $idx]
			}
		}
		set l [string length $content]
		for {set k 0} {$k < $l} {incr k} {
			set idx [string first defined $content $k]
			if { $idx >= 0 } {
				set partialContent [string range $content [expr $idx + 7] end]
				# keeping part before || or &&
				set idx1 [string first "||" $partialContent]
				if { $idx1 < 0 } {
					set idx1 [string length $partialContent]
				} else {
					incr idx1 -1
				}
				set idx2 [string first "&&" $partialContent]
				if { $idx2 < 0 } {
					set idx2 [string length $partialContent]
				} else {
					incr idx2 -1
				}
				if { $idx2 < $idx1 } {
					set idx1 $idx2
				}
				set partialContent [string range $partialContent 0 $idx1]
				if { ![regexp {^\s*\(?\s*\w+\s*\)?\s*$} $partialContent] } {
					::logiscope::addViolation $node
				}
				set k [expr $idx + 6]
			} else {
				set k $l
			}
		}
	}
	return 1
}
