Blame lib/framework.exp

Packit 62fe53
# Copyright (C) 1992-2016 Free Software Foundation, Inc.
Packit 62fe53
#
Packit 62fe53
# This file is part of DejaGnu.
Packit 62fe53
#
Packit 62fe53
# DejaGnu is free software; you can redistribute it and/or modify it
Packit 62fe53
# under the terms of the GNU General Public License as published by
Packit 62fe53
# the Free Software Foundation; either version 3 of the License, or
Packit 62fe53
# (at your option) any later version.
Packit 62fe53
#
Packit 62fe53
# DejaGnu is distributed in the hope that it will be useful, but
Packit 62fe53
# WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 62fe53
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 62fe53
# General Public License for more details.
Packit 62fe53
#
Packit 62fe53
# You should have received a copy of the GNU General Public License
Packit 62fe53
# along with DejaGnu; if not, write to the Free Software Foundation,
Packit 62fe53
# Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
Packit 62fe53
Packit 62fe53
# This file was written by Rob Savoye <rob@welcomehome.org>.
Packit 62fe53
Packit 62fe53
# These variables are local to this file.
Packit 62fe53
# This or more warnings and a test fails.
Packit 62fe53
set warning_threshold 3
Packit 62fe53
# This or more errors and a test fails.
Packit 62fe53
set perror_threshold 1
Packit 62fe53
Packit 62fe53
proc mail_file { file to subject } {
Packit 62fe53
    if {[file readable $file]} {
Packit 62fe53
	catch "exec mail -s \"$subject\" $to < $file"
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Insert DTD for xml format checking.
Packit 62fe53
#
Packit 62fe53
proc insertdtd { } {
Packit 62fe53
    xml_output "
Packit 62fe53
Packit 62fe53
Packit 62fe53
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
  
Packit 62fe53
\]>"
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Open the output logs.
Packit 62fe53
#
Packit 62fe53
proc open_logs { } {
Packit 62fe53
    global outdir
Packit 62fe53
    global tool
Packit 62fe53
    global sum_file
Packit 62fe53
    global xml_file
Packit 62fe53
    global xml
Packit 62fe53
Packit 62fe53
    if { ${tool} ==  "" } {
Packit 62fe53
	set tool testrun
Packit 62fe53
    }
Packit 62fe53
    catch "file delete -force -- $outdir/$tool.sum"
Packit 62fe53
    set sum_file [open [file join $outdir $tool.sum] w]
Packit 62fe53
    if { $xml } {
Packit 62fe53
	catch "file delete -force -- $outdir/$tool.xml"
Packit 62fe53
	set xml_file [open [file join $outdir $tool.xml] w]
Packit 62fe53
	xml_output ""
Packit 62fe53
	insertdtd
Packit 62fe53
	xml_output "<testsuite>"
Packit 62fe53
    }
Packit 62fe53
    catch "file delete -force -- $outdir/$tool.log"
Packit 62fe53
    log_file -a "$outdir/$tool.log"
Packit 62fe53
    verbose "Opening log files in $outdir"
Packit 62fe53
    if { ${tool} ==  "testrun" } {
Packit 62fe53
	set tool ""
Packit 62fe53
    }
Packit 62fe53
    fconfigure $sum_file -buffering line
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Close the output logs.
Packit 62fe53
#
Packit 62fe53
proc close_logs { } {
Packit 62fe53
    global sum_file
Packit 62fe53
    global xml
Packit 62fe53
    global xml_file
Packit 62fe53
Packit 62fe53
    if { $xml } {
Packit 62fe53
	xml_output "</testsuite>"
Packit 62fe53
	catch "close $xml_file"
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    catch "close $sum_file"
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Check build host triplet for PATTERN.
Packit 62fe53
# With no arguments it returns the triplet string.
Packit 62fe53
#
Packit 62fe53
proc isbuild { pattern } {
Packit 62fe53
    global build_triplet
Packit 62fe53
    global host_triplet
Packit 62fe53
Packit 62fe53
    if {![info exists build_triplet]} {
Packit 62fe53
	set build_triplet ${host_triplet}
Packit 62fe53
    }
Packit 62fe53
    if {[string match "" $pattern]} {
Packit 62fe53
	return $build_triplet
Packit 62fe53
    }
Packit 62fe53
    verbose "Checking pattern \"$pattern\" with $build_triplet" 2
Packit 62fe53
Packit 62fe53
    if {[string match "$pattern" $build_triplet]} {
Packit 62fe53
	return 1
Packit 62fe53
    } else {
Packit 62fe53
	return 0
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Is $board remote? Return a non-zero value if so.
Packit 62fe53
#
Packit 62fe53
proc is_remote { board } {
Packit 62fe53
    global host_board
Packit 62fe53
    global target_list
Packit 62fe53
Packit 62fe53
    verbose "calling is_remote $board" 3
Packit 62fe53
    # Remove any target variant specifications from the name.
Packit 62fe53
    set board [lindex [split $board "/"] 0]
Packit 62fe53
Packit 62fe53
    # Map the host or build back into their short form.
Packit 62fe53
    if { [board_info build name] == $board } {
Packit 62fe53
	set board "build"
Packit 62fe53
    } elseif { [board_info host name] == $board } {
Packit 62fe53
	set board "host"
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # We're on the "build". The check for the empty string is just for
Packit 62fe53
    # paranoia's sake--we shouldn't ever get one. "unix" is a magic
Packit 62fe53
    # string that should really go away someday.
Packit 62fe53
    if { $board == "build" || $board == "unix" || $board == "" } {
Packit 62fe53
	verbose "board is $board, not remote" 3
Packit 62fe53
	return 0
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if { $board == "host" } {
Packit 62fe53
	if { [info exists host_board] && $host_board != "" } {
Packit 62fe53
	    verbose "board is $board, is remote" 3
Packit 62fe53
	    return 1
Packit 62fe53
	} else {
Packit 62fe53
	    verbose "board is $board, host is local" 3
Packit 62fe53
	    return 0
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if { $board == "target" } {
Packit 62fe53
	global current_target_name
Packit 62fe53
Packit 62fe53
	if {[info exists current_target_name]} {
Packit 62fe53
	    # This shouldn't happen, but we'll be paranoid anyway.
Packit 62fe53
	    if { $current_target_name != "target" } {
Packit 62fe53
		return [is_remote $current_target_name]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	return 0
Packit 62fe53
    }
Packit 62fe53
    if {[board_info $board exists isremote]} {
Packit 62fe53
	verbose "board is $board, isremote is [board_info $board isremote]" 3
Packit 62fe53
	return [board_info $board isremote]
Packit 62fe53
    }
Packit 62fe53
    return 1
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# If this is a Canadian (3 way) cross. This means the tools are
Packit 62fe53
# being built with a cross compiler for another host.
Packit 62fe53
#
Packit 62fe53
proc is3way {} {
Packit 62fe53
    global host_triplet
Packit 62fe53
    global build_triplet
Packit 62fe53
Packit 62fe53
    if {![info exists build_triplet]} {
Packit 62fe53
	set build_triplet ${host_triplet}
Packit 62fe53
    }
Packit 62fe53
    verbose "Checking $host_triplet against $build_triplet" 2
Packit 62fe53
    if { "$build_triplet" == "$host_triplet" } {
Packit 62fe53
	return 0
Packit 62fe53
    }
Packit 62fe53
    return 1
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Check host triplet for PATTERN.
Packit 62fe53
# With no arguments it returns the triplet string.
Packit 62fe53
#
Packit 62fe53
proc ishost { pattern } {
Packit 62fe53
    global host_triplet
Packit 62fe53
Packit 62fe53
    if {[string match "" $pattern]} {
Packit 62fe53
	return $host_triplet
Packit 62fe53
    }
Packit 62fe53
    verbose "Checking pattern \"$pattern\" with $host_triplet" 2
Packit 62fe53
Packit 62fe53
    if {[string match "$pattern" $host_triplet]} {
Packit 62fe53
	return 1
Packit 62fe53
    } else {
Packit 62fe53
	return 0
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Check target triplet for pattern.
Packit 62fe53
#
Packit 62fe53
# With no arguments it returns the triplet string.
Packit 62fe53
# Returns 1 if the target looked for, or 0 if not.
Packit 62fe53
#
Packit 62fe53
proc istarget { args } {
Packit 62fe53
    global target_triplet
Packit 62fe53
Packit 62fe53
    # if no arg, return the config string
Packit 62fe53
    if {[string match "" $args]} {
Packit 62fe53
	if {[info exists target_triplet]} {
Packit 62fe53
	    return $target_triplet
Packit 62fe53
	} else {
Packit 62fe53
	    perror "No target configuration names found."
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    set triplet [lindex $args 0]
Packit 62fe53
Packit 62fe53
    # now check against the canonical name
Packit 62fe53
    if {[info exists target_triplet]} {
Packit 62fe53
	verbose "Checking \"$triplet\" against \"$target_triplet\"" 2
Packit 62fe53
	if {[string match $triplet $target_triplet]} {
Packit 62fe53
	    return 1
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # nope, no match
Packit 62fe53
    return 0
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Check to see if we're running the tests in a native environment
Packit 62fe53
# Returns 1 if running native, 0 if on a target.
Packit 62fe53
#
Packit 62fe53
proc isnative { } {
Packit 62fe53
    global target_triplet
Packit 62fe53
    global build_triplet
Packit 62fe53
Packit 62fe53
    if {[string match $build_triplet $target_triplet]} {
Packit 62fe53
	return 1
Packit 62fe53
    }
Packit 62fe53
    return 0
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# unknown -- called by expect if a proc is called that doesn't exist
Packit 62fe53
#
Packit 62fe53
# Rename unknown to tcl_unknown so that we can wrap tcl_unknown.
Packit 62fe53
# This allows Tcl package autoloading to work in the modern age.
Packit 62fe53
Packit 62fe53
rename ::unknown ::tcl_unknown
Packit 62fe53
proc unknown args {
Packit 62fe53
    if {[catch {uplevel 1 ::tcl_unknown $args} msg]} {
Packit 62fe53
	global errorCode
Packit 62fe53
	global errorInfo
Packit 62fe53
	global exit_status
Packit 62fe53
Packit 62fe53
	clone_output "ERROR: (DejaGnu) proc \"$args\" does not exist."
Packit 62fe53
	if {[info exists errorCode]} {
Packit 62fe53
	    send_error "The error code is $errorCode\n"
Packit 62fe53
	}
Packit 62fe53
	if {[info exists errorInfo]} {
Packit 62fe53
	    send_error "The info on the error is:\n$errorInfo\n"
Packit 62fe53
	}
Packit 62fe53
	set exit_status 2
Packit 62fe53
	log_and_exit
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Print output to stdout (or stderr) and to log file
Packit 62fe53
#
Packit 62fe53
# If the --all flag (-a) option was used then all messages go the the screen.
Packit 62fe53
# Without this, all messages that start with a keyword are written only to the
Packit 62fe53
# detail log file.  All messages that go to the screen will also appear in the
Packit 62fe53
# detail log.  This should only be used by the framework itself using pass,
Packit 62fe53
# fail, xpass, xfail, kpass, kfail, warning, perror, note, untested, unresolved,
Packit 62fe53
# or unsupported procedures.
Packit 62fe53
#
Packit 62fe53
proc clone_output { message } {
Packit 62fe53
    global sum_file
Packit 62fe53
    global all_flag
Packit 62fe53
Packit 62fe53
    if { $sum_file != "" } {
Packit 62fe53
	puts $sum_file "$message"
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    regsub "^\[ \t\]*(\[^ \t\]+).*$" "$message" "\\1" firstword
Packit 62fe53
    switch -glob -- "$firstword" {
Packit 62fe53
	"PASS:" -
Packit 62fe53
	"XFAIL:" -
Packit 62fe53
	"KFAIL:" -
Packit 62fe53
	"UNRESOLVED:" -
Packit 62fe53
	"UNSUPPORTED:" -
Packit 62fe53
	"UNTESTED:" {
Packit 62fe53
	    if {$all_flag} {
Packit 62fe53
		send_user -- "$message\n"
Packit 62fe53
		return "$message"
Packit 62fe53
	    } else {
Packit 62fe53
		send_log -- "$message\n"
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	{"ERROR:" "WARNING:" "NOTE:"} {
Packit 62fe53
	    send_error -- "$message\n"
Packit 62fe53
	    return "$message"
Packit 62fe53
	}
Packit 62fe53
	default {
Packit 62fe53
	    send_user -- "$message\n"
Packit 62fe53
	    return "$message"
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Reset a few counters.
Packit 62fe53
#
Packit 62fe53
proc reset_vars {} {
Packit 62fe53
    global test_names test_counts
Packit 62fe53
    global warncnt errcnt
Packit 62fe53
Packit 62fe53
    # other miscellaneous variables
Packit 62fe53
    global prms_id
Packit 62fe53
    global bug_id
Packit 62fe53
Packit 62fe53
    # reset them all
Packit 62fe53
    set prms_id	0
Packit 62fe53
    set bug_id	0
Packit 62fe53
    set warncnt 0
Packit 62fe53
    set errcnt  0
Packit 62fe53
    foreach x $test_names {
Packit 62fe53
	set test_counts($x,count) 0
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # Variables local to this file.
Packit 62fe53
    global warning_threshold perror_threshold
Packit 62fe53
    set warning_threshold 3
Packit 62fe53
    set perror_threshold 1
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
proc log_and_exit {} {
Packit 62fe53
    global exit_status
Packit 62fe53
    global tool mail_logs outdir mailing_list
Packit 62fe53
Packit 62fe53
    log_summary total
Packit 62fe53
    # extract version number
Packit 62fe53
    if {[info procs ${tool}_version] != ""} {
Packit 62fe53
	if {[catch "${tool}_version" output]} {
Packit 62fe53
	    warning "${tool}_version failed:\n$output"
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
    close_logs
Packit 62fe53
    verbose -log "runtest completed at [timestamp -format %c]"
Packit 62fe53
    if {$mail_logs} {
Packit 62fe53
	if { ${tool} ==  "" } {
Packit 62fe53
	    set tool testrun
Packit 62fe53
	}
Packit 62fe53
	mail_file $outdir/$tool.sum $mailing_list "Dejagnu Summary Log"
Packit 62fe53
    }
Packit 62fe53
    remote_close host
Packit 62fe53
    remote_close target
Packit 62fe53
    exit $exit_status
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Emit an XML tag, but escape XML special characters in the body.
Packit 62fe53
proc xml_tag { tag body } {
Packit 62fe53
    set escapes { < < > > & & \" " ' ' }
Packit 62fe53
    for {set i 1} {$i < 32} {incr i} {
Packit 62fe53
	if {[lsearch [list 9 10 13] $i] >= 0} {
Packit 62fe53
	    # skip valid XML whitespace chars
Packit 62fe53
	    continue
Packit 62fe53
	}
Packit 62fe53
	# Append non-printable character
Packit 62fe53
	lappend escapes [format %c $i]
Packit 62fe53
	# .. and then the corresponding XML escape
Packit 62fe53
	lappend escapes &#x[format %x $i]\;
Packit 62fe53
    }
Packit 62fe53
    return <$tag>[string map $escapes $body]</$tag>
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
proc xml_output { message } {
Packit 62fe53
    global xml_file
Packit 62fe53
    if { $xml_file != "" } {
Packit 62fe53
	puts $xml_file $message
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Print summary of all pass/fail counts.
Packit 62fe53
#
Packit 62fe53
proc log_summary { args } {
Packit 62fe53
    global tool
Packit 62fe53
    global sum_file
Packit 62fe53
    global xml_file
Packit 62fe53
    global xml
Packit 62fe53
    global exit_status
Packit 62fe53
    global mail_logs
Packit 62fe53
    global outdir
Packit 62fe53
    global mailing_list
Packit 62fe53
    global current_target_name
Packit 62fe53
    global test_counts
Packit 62fe53
    global testcnt
Packit 62fe53
Packit 62fe53
    if { [llength $args] == 0 } {
Packit 62fe53
	set which "count"
Packit 62fe53
    } else {
Packit 62fe53
	set which [lindex $args 0]
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if { [llength $args] == 0 } {
Packit 62fe53
	clone_output "\n\t\t=== $tool Summary for $current_target_name ===\n"
Packit 62fe53
    } else {
Packit 62fe53
	clone_output "\n\t\t=== $tool Summary ===\n"
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # If the tool set `testcnt', it wants us to do a sanity check on the
Packit 62fe53
    # total count, so compare the reported number of testcases with the
Packit 62fe53
    # expected number.  Maintaining an accurate count in `testcnt' isn't easy
Packit 62fe53
    # so it's not clear how often this will be used.
Packit 62fe53
    if {[info exists testcnt]} {
Packit 62fe53
	if { $testcnt > 0 } {
Packit 62fe53
	    set totlcnt 0
Packit 62fe53
	    # total all the testcases reported
Packit 62fe53
	    foreach x { FAIL PASS XFAIL KFAIL XPASS KPASS UNTESTED UNRESOLVED UNSUPPORTED } {
Packit 62fe53
		incr totlcnt test_counts($x,$which)
Packit 62fe53
	    }
Packit 62fe53
	    set testcnt test_counts(total,$which)
Packit 62fe53
Packit 62fe53
	    if { $testcnt>$totlcnt || $testcnt<$totlcnt } {
Packit 62fe53
		if { $testcnt > $totlcnt } {
Packit 62fe53
		    set mismatch "unreported  [expr {$testcnt - $totlcnt}]"
Packit 62fe53
		}
Packit 62fe53
		if { $testcnt < $totlcnt } {
Packit 62fe53
		    set mismatch "misreported [expr {$totlcnt - $testcnt}]"
Packit 62fe53
		}
Packit 62fe53
	    } else {
Packit 62fe53
		verbose "# of testcases run         $testcnt"
Packit 62fe53
	    }
Packit 62fe53
Packit 62fe53
	    if {[info exists mismatch]} {
Packit 62fe53
		clone_output "### ERROR: totals do not equal number of testcases run"
Packit 62fe53
		clone_output "### ERROR: # of testcases expected    $testcnt"
Packit 62fe53
		clone_output "### ERROR: # of testcases reported    $totlcnt"
Packit 62fe53
		clone_output "### ERROR: # of testcases $mismatch\n"
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
    foreach x { PASS FAIL XPASS XFAIL KPASS KFAIL UNRESOLVED UNTESTED UNSUPPORTED } {
Packit 62fe53
	set val $test_counts($x,$which)
Packit 62fe53
	if { $val > 0 } {
Packit 62fe53
	    set mess "# of $test_counts($x,name)"
Packit 62fe53
	    if { $xml } {
Packit 62fe53
		xml_output "  <summary>"
Packit 62fe53
		xml_output "    [xml_tag result $x]"
Packit 62fe53
		xml_output "    [xml_tag description $mess]"
Packit 62fe53
		xml_output "    [xml_tag total $val]"
Packit 62fe53
		xml_output "  </summary>"
Packit 62fe53
	    }
Packit 62fe53
	    if { [string length $mess] < 24 } {
Packit 62fe53
		append mess "\t"
Packit 62fe53
	    }
Packit 62fe53
	    clone_output "$mess\t$val"
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Setup a flag to control whether a failure is expected or not
Packit 62fe53
#
Packit 62fe53
# Multiple target triplet patterns can be specified for targets
Packit 62fe53
# for which the test fails.  A bug report ID can be specified,
Packit 62fe53
# which is a string without '-'.
Packit 62fe53
#
Packit 62fe53
proc setup_xfail { args } {
Packit 62fe53
    global xfail_flag
Packit 62fe53
    global xfail_prms
Packit 62fe53
Packit 62fe53
    set xfail_prms 0
Packit 62fe53
    set argc [ llength $args ]
Packit 62fe53
    for { set i 0 } { $i < $argc } { incr i } {
Packit 62fe53
	set sub_arg [ lindex $args $i ]
Packit 62fe53
	# is a prms number. we assume this is a string with no '-' characters
Packit 62fe53
	if {[regexp "^\[^\-\]+$" $sub_arg]} {
Packit 62fe53
	    set xfail_prms $sub_arg
Packit 62fe53
	    continue
Packit 62fe53
	}
Packit 62fe53
	if {[istarget $sub_arg]} {
Packit 62fe53
	    set xfail_flag 1
Packit 62fe53
	    continue
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Setup a flag to control whether it is a known failure.
Packit 62fe53
#
Packit 62fe53
# A bug report ID _MUST_ be specified, and is the first argument.
Packit 62fe53
# It still must be a string without '-' so we can be sure someone
Packit 62fe53
# did not just forget it and we end-up using a target triple as
Packit 62fe53
# bug id.
Packit 62fe53
#
Packit 62fe53
# Multiple target triplet patterns can be specified for targets
Packit 62fe53
# for which the test is known to fail.
Packit 62fe53
#
Packit 62fe53
proc setup_kfail { args } {
Packit 62fe53
    global kfail_flag
Packit 62fe53
    global kfail_prms
Packit 62fe53
Packit 62fe53
    set kfail_prms 0
Packit 62fe53
    set argc [ llength $args ]
Packit 62fe53
    for { set i 0 } { $i < $argc } { incr i } {
Packit 62fe53
	set sub_arg [ lindex $args $i ]
Packit 62fe53
	# is a prms number. we assume this is a string with no '-' characters
Packit 62fe53
	if {[regexp "^\[^\-\]+$" $sub_arg]} {
Packit 62fe53
	    set kfail_prms $sub_arg
Packit 62fe53
	    continue
Packit 62fe53
	}
Packit 62fe53
	if {[istarget $sub_arg]} {
Packit 62fe53
	    set kfail_flag 1
Packit 62fe53
	    continue
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if {$kfail_prms == 0} {
Packit 62fe53
	perror "Attempt to set a kfail without specifying bug tracking id"
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Check to see if a conditional xfail is triggered.
Packit 62fe53
#	message {targets} {include} {exclude}
Packit 62fe53
#
Packit 62fe53
proc check_conditional_xfail { args } {
Packit 62fe53
    global compiler_flags
Packit 62fe53
Packit 62fe53
    set all_args [lindex $args 0]
Packit 62fe53
Packit 62fe53
    set message [lindex $all_args 0]
Packit 62fe53
Packit 62fe53
    set target_list [lindex $all_args 1]
Packit 62fe53
    verbose "Limited to targets: $target_list" 3
Packit 62fe53
Packit 62fe53
    # get the list of flags to look for
Packit 62fe53
    set includes [lindex $all_args 2]
Packit 62fe53
    verbose "Will search for options $includes" 3
Packit 62fe53
Packit 62fe53
    # get the list of flags to exclude
Packit 62fe53
    if { [llength $all_args] > 3 } {
Packit 62fe53
	set excludes [lindex $all_args 3]
Packit 62fe53
	verbose "Will exclude for options $excludes" 3
Packit 62fe53
    } else {
Packit 62fe53
	set excludes ""
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # loop through all the targets, checking the options for each one
Packit 62fe53
    verbose "Compiler flags are: $compiler_flags" 2
Packit 62fe53
Packit 62fe53
    set incl_hit 0
Packit 62fe53
    set excl_hit 0
Packit 62fe53
    foreach targ $target_list {
Packit 62fe53
	if {[istarget $targ]} {
Packit 62fe53
	    # look through the compiler options for flags we want to see
Packit 62fe53
	    # this is really messy cause each set of options to look for
Packit 62fe53
	    # may also be a list. We also want to find each element of the
Packit 62fe53
	    # list, regardless of order to make sure they're found.
Packit 62fe53
	    # So we look for lists in side of lists, and make sure all
Packit 62fe53
	    # the elements match before we decide this is legit.
Packit 62fe53
	    # Se we 'incl_hit' to 1 before the loop so that if the 'includes'
Packit 62fe53
	    # list is empty, this test will report a hit.  (This can be
Packit 62fe53
	    # useful if a target will always fail unless certain flags,
Packit 62fe53
	    # specified in the 'excludes' list, are used.)
Packit 62fe53
	    set incl_hit 1
Packit 62fe53
	    for { set i 0 } { $i < [llength $includes] } { incr i } {
Packit 62fe53
		set incl_hit 0
Packit 62fe53
		set opt [lindex $includes $i]
Packit 62fe53
		verbose "Looking for $opt to include in the compiler flags" 2
Packit 62fe53
		foreach j "$opt" {
Packit 62fe53
		    if {[string match "* $j *" $compiler_flags]} {
Packit 62fe53
			verbose "Found $j to include in the compiler flags" 2
Packit 62fe53
			incr incl_hit
Packit 62fe53
		    }
Packit 62fe53
		}
Packit 62fe53
		# if the number of hits we get is the same as the number of
Packit 62fe53
		# specified options, then we got a match
Packit 62fe53
		if {$incl_hit == [llength $opt]} {
Packit 62fe53
		    break
Packit 62fe53
		} else {
Packit 62fe53
		    set incl_hit 0
Packit 62fe53
		}
Packit 62fe53
	    }
Packit 62fe53
	    # look through the compiler options for flags we don't
Packit 62fe53
	    # want to see
Packit 62fe53
	    for { set i 0 } { $i < [llength $excludes] } { incr i } {
Packit 62fe53
		set excl_hit 0
Packit 62fe53
		set opt [lindex $excludes $i]
Packit 62fe53
		verbose "Looking for $opt to exclude in the compiler flags" 2
Packit 62fe53
		foreach j "$opt" {
Packit 62fe53
		    if {[string match "* $j *" $compiler_flags]} {
Packit 62fe53
			verbose "Found $j to exclude in the compiler flags" 2
Packit 62fe53
			incr excl_hit
Packit 62fe53
		    }
Packit 62fe53
		}
Packit 62fe53
		# if the number of hits we get is the same as the number of
Packit 62fe53
		# specified options, then we got a match
Packit 62fe53
		if {$excl_hit == [llength $opt]} {
Packit 62fe53
		    break
Packit 62fe53
		} else {
Packit 62fe53
		    set excl_hit 0
Packit 62fe53
		}
Packit 62fe53
	    }
Packit 62fe53
Packit 62fe53
	    # if we got a match for what to include, but didn't find any reasons
Packit 62fe53
	    # to exclude this, then we got a match! So return one to turn this into
Packit 62fe53
	    # an expected failure.
Packit 62fe53
	    if {$incl_hit && ! $excl_hit } {
Packit 62fe53
		verbose "This is a conditional match" 2
Packit 62fe53
		return 1
Packit 62fe53
	    } else {
Packit 62fe53
		verbose "This is not a conditional match" 2
Packit 62fe53
		return 0
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
    return 0
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Clear the xfail flag for a particular target.
Packit 62fe53
#
Packit 62fe53
proc clear_xfail { args } {
Packit 62fe53
    global xfail_flag
Packit 62fe53
    global xfail_prms
Packit 62fe53
Packit 62fe53
    set argc [ llength $args ]
Packit 62fe53
    for { set i 0 } { $i < $argc } { incr i } {
Packit 62fe53
	set sub_arg [ lindex $args $i ]
Packit 62fe53
	switch -glob -- $sub_arg {
Packit 62fe53
	    "*-*-*" {			# is a configuration triplet
Packit 62fe53
		if {[istarget $sub_arg]} {
Packit 62fe53
		    set xfail_flag 0
Packit 62fe53
		    set xfail_prms 0
Packit 62fe53
		}
Packit 62fe53
		continue
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Clear the kfail flag for a particular target.
Packit 62fe53
#
Packit 62fe53
proc clear_kfail { args } {
Packit 62fe53
    global kfail_flag
Packit 62fe53
    global kfail_prms
Packit 62fe53
Packit 62fe53
    set argc [ llength $args ]
Packit 62fe53
    for { set i 0 } { $i < $argc } { incr i } {
Packit 62fe53
	set sub_arg [ lindex $args $i ]
Packit 62fe53
	switch -glob -- $sub_arg {
Packit 62fe53
	    "*-*-*" {			# is a configuration triplet
Packit 62fe53
		if {[istarget $sub_arg]} {
Packit 62fe53
		    set kfail_flag 0
Packit 62fe53
		    set kfail_prms 0
Packit 62fe53
		}
Packit 62fe53
		continue
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test has passed or failed (perhaps unexpectedly).
Packit 62fe53
# This is an internal procedure, only used in this file.
Packit 62fe53
#
Packit 62fe53
proc record_test { type message args } {
Packit 62fe53
    global exit_status
Packit 62fe53
    global xml
Packit 62fe53
    global prms_id bug_id
Packit 62fe53
    global xfail_flag xfail_prms
Packit 62fe53
    global kfail_flag kfail_prms
Packit 62fe53
    global errcnt warncnt
Packit 62fe53
    global warning_threshold perror_threshold
Packit 62fe53
    global pf_prefix
Packit 62fe53
Packit 62fe53
    if { [llength $args] > 0 } {
Packit 62fe53
	set count [lindex $args 0]
Packit 62fe53
    } else {
Packit 62fe53
	set count 1
Packit 62fe53
    }
Packit 62fe53
    if {[info exists pf_prefix]} {
Packit 62fe53
	set message [concat $pf_prefix " " $message]
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # If we have too many warnings or errors,
Packit 62fe53
    # the output of the test can't be considered correct.
Packit 62fe53
    if { $warning_threshold > 0 && $warncnt >= $warning_threshold
Packit 62fe53
	 || $perror_threshold > 0 && $errcnt >= $perror_threshold } {
Packit 62fe53
        verbose "Error/Warning threshold exceeded: \
Packit 62fe53
                 $errcnt $warncnt (max. $perror_threshold $warning_threshold)"
Packit 62fe53
        set type UNRESOLVED
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    incr_count $type
Packit 62fe53
Packit 62fe53
    if { $xml } {
Packit 62fe53
	global errorInfo
Packit 62fe53
	set error ""
Packit 62fe53
	if {[info exists errorInfo]} {
Packit 62fe53
	    set error $errorInfo
Packit 62fe53
	}
Packit 62fe53
	global expect_out
Packit 62fe53
	set rio { "" "" }
Packit 62fe53
	if { [catch { set rio [split $expect_out(buffer) "\n"] } result]} {
Packit 62fe53
	    #do nothing - leave as { "" "" }
Packit 62fe53
	}
Packit 62fe53
Packit 62fe53
	set output ""
Packit 62fe53
	set output "expect_out(buffer)"
Packit 62fe53
	xml_output "  <test>"
Packit 62fe53
	xml_output "    [xml_tag input [string trimright [lindex $rio 0]]]"
Packit 62fe53
	xml_output "    [xml_tag output [string trimright [lindex $rio 1]]]"
Packit 62fe53
	xml_output "    [xml_tag result $type]"
Packit 62fe53
	xml_output "    [xml_tag name $message]"
Packit 62fe53
	xml_output "    [xml_tag prms_id $prms_id]"
Packit 62fe53
	xml_output "  </test>"
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    switch -- $type {
Packit 62fe53
	PASS {
Packit 62fe53
	    if {$prms_id} {
Packit 62fe53
		set message [concat $message "\t(PRMS $prms_id)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	FAIL {
Packit 62fe53
	    set exit_status 1
Packit 62fe53
	    if {$prms_id} {
Packit 62fe53
		set message [concat $message "\t(PRMS $prms_id)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	XPASS {
Packit 62fe53
	    set exit_status 1
Packit 62fe53
	    if { $xfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $xfail_prms)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	XFAIL {
Packit 62fe53
	    if { $xfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $xfail_prms)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	KPASS {
Packit 62fe53
	    set exit_status 1
Packit 62fe53
	    if { $kfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $kfail_prms)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	KFAIL {
Packit 62fe53
	    if { $kfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS: $kfail_prms)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	UNTESTED {
Packit 62fe53
	    # The only reason we look at the xfail/kfail stuff is to pick up
Packit 62fe53
	    # `xfail_prms'.
Packit 62fe53
	    if { $kfail_flag && $kfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $kfail_prms)"]
Packit 62fe53
	    } elseif { $xfail_flag && $xfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $xfail_prms)"]
Packit 62fe53
	    } elseif { $prms_id } {
Packit 62fe53
		set message [concat $message "\t(PRMS $prms_id)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	UNRESOLVED {
Packit 62fe53
	    set exit_status 1
Packit 62fe53
	    # The only reason we look at the xfail/kfail stuff is to pick up
Packit 62fe53
	    # `xfail_prms'.
Packit 62fe53
	    if { $kfail_flag && $kfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $kfail_prms)"]
Packit 62fe53
	    } elseif { $xfail_flag && $xfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $xfail_prms)"]
Packit 62fe53
	    } elseif { $prms_id } {
Packit 62fe53
		set message [concat $message "\t(PRMS $prms_id)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	UNSUPPORTED {
Packit 62fe53
	    # The only reason we look at the xfail/kfail stuff is to pick up
Packit 62fe53
	    # `xfail_prms'.
Packit 62fe53
	    if { $kfail_flag && $kfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $kfail_prms)"]
Packit 62fe53
	    } elseif { $xfail_flag && $xfail_prms != 0 } {
Packit 62fe53
		set message [concat $message "\t(PRMS $xfail_prms)"]
Packit 62fe53
	    } elseif { $prms_id } {
Packit 62fe53
		set message [concat $message "\t(PRMS $prms_id)"]
Packit 62fe53
	    }
Packit 62fe53
	}
Packit 62fe53
	default {
Packit 62fe53
	    perror "record_test called with bad type `$type'"
Packit 62fe53
	    set errcnt 0
Packit 62fe53
	    return
Packit 62fe53
	}
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if { $bug_id } {
Packit 62fe53
	set message [concat $message "\t(BUG $bug_id)"]
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    global multipass_name
Packit 62fe53
    if { $multipass_name != "" } {
Packit 62fe53
	set message [format "$type: %s: $message" "$multipass_name"]
Packit 62fe53
    } else {
Packit 62fe53
	set message "$type: $message"
Packit 62fe53
    }
Packit 62fe53
    clone_output "$message"
Packit 62fe53
Packit 62fe53
    # If a command name exists in the $local_record_procs associative
Packit 62fe53
    # array for this type of result, then invoke it.
Packit 62fe53
Packit 62fe53
    set lowcase_type [string tolower $type]
Packit 62fe53
    global local_record_procs
Packit 62fe53
    if {[info exists local_record_procs($lowcase_type)]} {
Packit 62fe53
	$local_record_procs($lowcase_type) "$message"
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    # Reset these so they're ready for the next test case.  We don't reset
Packit 62fe53
    # prms_id or bug_id here.  There may be multiple tests for them.  Instead
Packit 62fe53
    # they are reset in the main loop after each test.  It is also the
Packit 62fe53
    # testsuite driver's responsibility to reset them after each testcase.
Packit 62fe53
    set warncnt 0
Packit 62fe53
    set errcnt 0
Packit 62fe53
    set xfail_flag 0
Packit 62fe53
    set kfail_flag 0
Packit 62fe53
    set xfail_prms 0
Packit 62fe53
    set kfail_prms 0
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test has passed.
Packit 62fe53
#
Packit 62fe53
proc pass { message } {
Packit 62fe53
    global xfail_flag kfail_flag compiler_conditional_xfail_data
Packit 62fe53
Packit 62fe53
    # if we have a conditional xfail setup, then see if our compiler flags match
Packit 62fe53
    if {[ info exists compiler_conditional_xfail_data ]} {
Packit 62fe53
	if {[check_conditional_xfail $compiler_conditional_xfail_data]} {
Packit 62fe53
	    set xfail_flag 1
Packit 62fe53
	}
Packit 62fe53
	unset compiler_conditional_xfail_data
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if { $kfail_flag } {
Packit 62fe53
	record_test KPASS $message
Packit 62fe53
    } elseif { $xfail_flag } {
Packit 62fe53
	record_test XPASS $message
Packit 62fe53
    } else {
Packit 62fe53
	record_test PASS $message
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test has failed.
Packit 62fe53
#
Packit 62fe53
proc fail { message } {
Packit 62fe53
    global xfail_flag kfail_flag compiler_conditional_xfail_data
Packit 62fe53
Packit 62fe53
    # if we have a conditional xfail setup, then see if our compiler flags match
Packit 62fe53
    if {[ info exists compiler_conditional_xfail_data ]} {
Packit 62fe53
	if {[check_conditional_xfail $compiler_conditional_xfail_data]} {
Packit 62fe53
	    set xfail_flag 1
Packit 62fe53
	}
Packit 62fe53
	unset compiler_conditional_xfail_data
Packit 62fe53
    }
Packit 62fe53
Packit 62fe53
    if { $kfail_flag } {
Packit 62fe53
	record_test KFAIL $message
Packit 62fe53
    } elseif { $xfail_flag } {
Packit 62fe53
	record_test XFAIL $message
Packit 62fe53
    } else {
Packit 62fe53
	record_test FAIL $message
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test that was expected to fail has passed unexpectedly.
Packit 62fe53
#
Packit 62fe53
proc xpass { message } {
Packit 62fe53
    record_test XPASS $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test that was expected to fail did indeed fail.
Packit 62fe53
#
Packit 62fe53
proc xfail { message } {
Packit 62fe53
    record_test XFAIL $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test for a known bug has passed unexpectedly.
Packit 62fe53
#
Packit 62fe53
proc kpass { bugid message } {
Packit 62fe53
    global kfail_flag kfail_prms
Packit 62fe53
    set kfail_flag 1
Packit 62fe53
    set kfail_prms $bugid
Packit 62fe53
    record_test KPASS $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Record that a test has failed due to a known bug.
Packit 62fe53
#
Packit 62fe53
proc kfail { bugid message } {
Packit 62fe53
    global kfail_flag kfail_prms
Packit 62fe53
    set kfail_flag 1
Packit 62fe53
    set kfail_prms $bugid
Packit 62fe53
    record_test KFAIL $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Set warning threshold.
Packit 62fe53
#
Packit 62fe53
proc set_warning_threshold { threshold } {
Packit 62fe53
    global warning_threshold
Packit 62fe53
    set warning_threshold $threshold
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Get warning threshold.
Packit 62fe53
#
Packit 62fe53
proc get_warning_threshold { } {
Packit 62fe53
    global warning_threshold
Packit 62fe53
    return $warning_threshold
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Prints warning messages.
Packit 62fe53
# These are warnings from the framework, not from the tools being
Packit 62fe53
# tested.  It takes a string, and an optional number and returns
Packit 62fe53
# nothing.
Packit 62fe53
#
Packit 62fe53
proc warning { args } {
Packit 62fe53
    global warncnt
Packit 62fe53
Packit 62fe53
    if { [llength $args] > 1 } {
Packit 62fe53
	set warncnt [lindex $args 1]
Packit 62fe53
    } else {
Packit 62fe53
	incr warncnt
Packit 62fe53
    }
Packit 62fe53
    set message [lindex $args 0]
Packit 62fe53
Packit 62fe53
    clone_output "WARNING: $message"
Packit 62fe53
Packit 62fe53
    global errorInfo
Packit 62fe53
    if {[info exists errorInfo]} {
Packit 62fe53
	unset errorInfo
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Prints error messages.
Packit 62fe53
# These are errors from the framework, not from the tools being
Packit 62fe53
# tested.  It takes a string, and an optional number and returns
Packit 62fe53
# nothing.
Packit 62fe53
#
Packit 62fe53
proc perror { args } {
Packit 62fe53
    global errcnt
Packit 62fe53
Packit 62fe53
    if { [llength $args] > 1 } {
Packit 62fe53
	set errcnt [lindex $args 1]
Packit 62fe53
    } else {
Packit 62fe53
	incr errcnt
Packit 62fe53
    }
Packit 62fe53
    set message [lindex $args 0]
Packit 62fe53
Packit 62fe53
    clone_output "ERROR: $message"
Packit 62fe53
Packit 62fe53
    global errorInfo
Packit 62fe53
    if {[info exists errorInfo]} {
Packit 62fe53
	unset errorInfo
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Prints informational messages.
Packit 62fe53
#
Packit 62fe53
# These are messages from the framework, not from the tools being
Packit 62fe53
# tested.  This means that it is currently illegal to call this proc
Packit 62fe53
# outside of dejagnu proper.
Packit 62fe53
#
Packit 62fe53
proc note { message } {
Packit 62fe53
    clone_output "NOTE: $message"
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# untested -- mark the test case as untested.
Packit 62fe53
#
Packit 62fe53
proc untested { message } {
Packit 62fe53
    record_test UNTESTED $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Mark the test case as unresolved.
Packit 62fe53
#
Packit 62fe53
proc unresolved { message } {
Packit 62fe53
    record_test UNRESOLVED $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Mark the test case as unsupported.
Packit 62fe53
# Usually this is used for a test that is missing OS support.
Packit 62fe53
#
Packit 62fe53
proc unsupported { message } {
Packit 62fe53
    record_test UNSUPPORTED $message
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Set up the values in the test_counts array (name and initial
Packit 62fe53
# totals).
Packit 62fe53
#
Packit 62fe53
proc init_testcounts { } {
Packit 62fe53
    global test_counts test_names
Packit 62fe53
    set test_counts(TOTAL,name) "testcases run"
Packit 62fe53
    set test_counts(PASS,name) "expected passes"
Packit 62fe53
    set test_counts(FAIL,name) "unexpected failures"
Packit 62fe53
    set test_counts(XFAIL,name) "expected failures"
Packit 62fe53
    set test_counts(XPASS,name) "unexpected successes"
Packit 62fe53
    set test_counts(KFAIL,name) "known failures"
Packit 62fe53
    set test_counts(KPASS,name) "unknown successes"
Packit 62fe53
    set test_counts(WARNING,name) "warnings"
Packit 62fe53
    set test_counts(ERROR,name) "errors"
Packit 62fe53
    set test_counts(UNSUPPORTED,name) "unsupported tests"
Packit 62fe53
    set test_counts(UNRESOLVED,name) "unresolved testcases"
Packit 62fe53
    set test_counts(UNTESTED,name) "untested testcases"
Packit 62fe53
    set j ""
Packit 62fe53
Packit 62fe53
    foreach i [lsort [array names test_counts]] {
Packit 62fe53
	regsub ",.*$" "$i" "" i
Packit 62fe53
	if { $i == $j } {
Packit 62fe53
	    continue
Packit 62fe53
	}
Packit 62fe53
	set test_counts($i,total) 0
Packit 62fe53
	lappend test_names $i
Packit 62fe53
	set j $i
Packit 62fe53
    }
Packit 62fe53
}
Packit 62fe53
Packit 62fe53
# Increment NAME in the test_counts array; the amount to increment can
Packit 62fe53
# be is optional (defaults to 1).
Packit 62fe53
#
Packit 62fe53
proc incr_count { name args } {
Packit 62fe53
    global test_counts
Packit 62fe53
Packit 62fe53
    if { [llength $args] == 0 } {
Packit 62fe53
	set count 1
Packit 62fe53
    } else {
Packit 62fe53
	set count [lindex $args 0]
Packit 62fe53
    }
Packit 62fe53
    if {[info exists test_counts($name,count)]} {
Packit 62fe53
	incr test_counts($name,count) $count
Packit 62fe53
	incr test_counts($name,total) $count
Packit 62fe53
    } else {
Packit 62fe53
	perror "$name doesn't exist in incr_count"
Packit 62fe53
    }
Packit 62fe53
}