.NAME Enumerator list

.DESCRIPTION
	In an enumerator list, the = construct shall not be used 
to explicitly initialize members other than the first, 
unless all items are explicitly initialized. 

.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 } {
  set curOperator [::logiscope::treeOperator $node]
  set curOperatorName [::logiscope::opName $curOperator]
  # Look for an enum
  if {[string equal $curOperatorName enumlist]} {
    set itemValues ""
	# Build the list of values for the enum item
	::logiscope::forobj curEnumerator $node treeChild {
	  set operatorValue [::utilities::getName $curEnumerator]
	  set curValue [::logiscope::treeDown $curEnumerator 1]
	  lappend itemValues [::utilities::getName $curValue]
    }
	
	# Check that the list is compliant
	set nbItems [llength $itemValues]
	set firstItemDefinedOnly 0
	set firstItemValue ""
	set followingItemsDefined 0
	set firstItemIndex 0
	# Parse the list to check if:
	# - Only the first item has been set
	# - How many items have been set
	for {set itemIdx 0} {$itemIdx<$nbItems} {incr itemIdx} {
	  set curItemValue [lindex $itemValues $itemIdx]
	  if {[string equal $itemIdx 0]} {
	    if {![string equal $curItemValue none]} {
		  set firstItemValue $curItemValue
          if {![string is integer $firstItemValue]} {
              # Limitation : can we get the real value ?
              set firstItemValue 1
          }
		  # This flag is set to 1 when the first item only has been set
	      set firstItemDefinedOnly 1
		}
	  }
	  if {![string equal $itemIdx 0] && ![string equal $curItemValue none]} {
	    set firstItemDefinedOnly 0
		# This counter reprensents the number of set items (in addition to the first one)
		incr followingItemsDefined
	  } 
	}	
	
	if {[expr $firstItemDefinedOnly == 1]} {
	  # If only the first item was assigned, check that its value and the number of items is compatible with MAXINT
	  set MAXINT [expr 0x7[string range [format %X -1] 1 end]]
	  if {[expr ($firstItemValue - 1)>($MAXINT-$nbItems)]} {
	    ::logiscope::addViolation [::logiscope::treeParent $node]
	    return 0
	  }
	} else {
	  if {[expr [expr ($followingItemsDefined+1) != $nbItems] && [expr $followingItemsDefined != 0]]} {
	    ::logiscope::addViolation [::logiscope::treeParent $node]
	    return 0
	  }
	}
  }
return 1
}
