.NAME Include guards

.DESCRIPTION
Include guards shall be provided. 

.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 checkDefine { condName def } {
	set ok 1
	if { ![::utilities::isTreeOperator $def extdefs] } {
		set ok 0
	} else {
		set pp_define [::logiscope::treeDown $def 0]
		if { "$pp_define" == "NULL" } {
			set ok 0
		} else {
			if { ![::utilities::isTreeOperator $pp_define pp_define] } {
				set ok 0
			} else {
				set nameNode [::logiscope::treeDown $pp_define 0]
				if { ![::utilities::isTreeOperator $nameNode identifier] } {
					set ok 0
				} else {
					if { "$condName" != "[::utilities::getName $nameNode]" } {
						set ok 0
					}
				}	
			}
		}
	}
	return $ok
}

proc compute {standardName tree} {
  set suffix [file extension [::logiscope::fileName]]
  # check only headers
  if { "$suffix" == ".h" || "$suffix" == ".hh" || "$suffix" == ".hxx" } {
    set ok 1
	set node [::logiscope::treeDown $tree 0]
	if { "$node" == "NULL" || ![::utilities::isTreeOperator $node extdefs] } {
		set ok 0
	} else {
		set node [::logiscope::treeDown $node 0]
		if { "$node" == "NULL" || ![::utilities::isTreeOperator $node pp_conditional] } {
			set ok 0
		} else {
			set cond [::logiscope::treeDown $node 0]
			switch -- [::utilities::treeOperatorName $cond] {
				pp_if {
					set pp_text [::logiscope::treeDown $cond 0]
					if { ![::utilities::isTreeOperator $pp_text pp_text] } {
						set ok 0
					} else {
						set content ""
						::logiscope::forobj line $pp_text treeChild {
							set content $content[::utilities::treeAtomString $line]
						}
						if { ![regexp {^\s*!\s*defined\s*\(?\s*(\w+)\s*\)?} $content str condName] } {
							set ok 0
						} else {
							set def [::logiscope::treeRight $cond]
							set ok [checkDefine $condName $def]
						}
					}
				}
				pp_ifndef {
					set nameNode [::logiscope::treeDown $cond 0]
					if { ![::utilities::isTreeOperator $nameNode identifier] } {
						set ok 0
					} else {
						set condName [::utilities::getName $nameNode]
						set def [::logiscope::treeRight $cond]
						set ok [checkDefine $condName $def]
					}
				}
				default {
					set ok 0
				}
			}
		}
	}
	if { !$ok } {
		::logiscope::addViolation $tree
	}
  }
}
