@rem = '--*-Perl-*--';
@rem = '
@echo off
set NAME=%~n0.bat
if "%CTCHOME%"=="" goto NoCTCHOME
if not exist "%CTCHOME%\%NAME%" goto Nosetup
if not exist "%CTCHOME%\perl\perl.exe" goto NoPerl
"%CTCHOME%\perl\perl.exe" "%CTCHOME%\%NAME%" %*
if errorlevel 1 goto End
exit /b 0
goto End
@rem ';
########################################################################
#
#                  CTC++ System, dmp2txt (v1.5)
#
# RCSfile     : $RCSfile: dmp2txt.pl $
# Version     : $Revision:$ $Date:$
# Last Edited : 7.9.2015
# Author      : $Author: roland$
#
#                  Copyright (c) 1997-2013 Testwell Oy
#                  Copyright (c) 2005-2015 Verifysoft Technology GmbH
##########################################################################
# Additional notice to users:
# You may use this Perl script as part of your authorized use of the
# CTC++ System. You/your organization is supposed to acquire the actual
# Perl system independently (start for example from http://www.perl.org).
#
# Testwell provides support for this ctc2html component of the CTC++ System
# in the same way as Testwell provides support for the other components of
# the CTC++ System. Because this component is provided in a source file
# form, you are able to modify this file. However, if you do any such
# modifications, other than those explicitly marked below, Testwell may
# not be capable of providing you support, and Testwell reserves the right
# not to support you with this component, if you have done your own other
# modifications to this file.
#
# Testwell would however be pleased to receive your bug corrections/reports
# and enhancement suggestions and will consider them in future versions of
# this tool.
#
# You can do the following modification(s) to this file:
# - currently nothing
##########################################################################

##########################################################################
# subroutines
##########################################################################
sub parse_cmdline;
sub module_data_prepare;
sub make_ctc_module_info;
sub copyarray;
sub usage;
sub version;
sub ctc_send_data;
sub ctc_prepare_upload;
sub fill_buffer;
sub module_data_get;
sub number_to_string;
sub module_is_all_zero;
sub ctc_get_character;
sub determine_intel;
sub determine_intel16;
sub determine_motorola;
sub determine_tekhex;
sub determine_tekhex_extended;
sub determine_startseq;
sub longhex2num;
sub hex2num;
sub nibble2num;
sub read_content;
sub basename;
sub myname;
sub uppercase;
sub receive_number;
sub receive_data;
sub ctc_receive_data;

##########################################################################
# global "constants"
##########################################################################
$version        = "1.5";

$NUMBER_MAP="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$NUMBER_BASE=62;

$t_start = 0;
$t_prepare_module = 1;
$t_module_data = 2;
$t_end = 3;
$t_finished = 4;

$CTC_FALSE = 0;
$CTC_TRUE = 1;
$START_SEQ = "<START:";
$END_SEQ   =  ">";
# $MODULE_MARKER = "MODUL"; #hardcoded below

$a_string = 0;
$a_stamp = 1;
$a_counter = 2;
$a_timer = 3;

$SIZE_ARRAY_SIZE = 7;
$MODULE_DATA_ARRAYS = 12;
$NUMBER_BASE = 62;
@NUMBER_MAP = split(//, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");

$MAX_CHARS = 20;
$END_NUMBER = ',';
$ARRAY_SIZE = 8;

$format = "binary";

$endian = -1; 
$bits = 1;

##########################################################################
# global variables
##########################################################################
$start = 0;
$gcount = 0;
$read_array_size=undef;

$transfer_state=$t_start;
@transfer_buffer=();
$transfer_index=0;

@module_data=();
$module_data_current_array=0;
$module_data_current_array_index=0;
@array_sizes=();
for (0..($ARRAY_SIZE-1)) {
    push (@array_sizes, 0);
}

$module=undef;
$mon_dmp=undef;
$mon_aux=undef;
$mon_txt=undef;

$verbose=0;

$pad=255;

$sanity = "";
$endian_str="";

$misused = 0;  # Gap Bits
$mistrail= 0;  # Trailing bits in a byte

##########################################################################
# execution starts here !
##########################################################################
binmode STDIN;

parse_cmdline();

if (!defined $mon_dmp) {
    usage();
    exit 1;
}

$content =read_content($mon_dmp);

if (determine_intel()) {
    @content=@newcontent;
    $format = "Intel Hexdump/Intel MCS-86";
} else {
    if (determine_intel16()) {
	@content=@newcontent;
	$format = "Intel 16-bit Hexdump/Intel INHX16";
    } else {
	if (determine_motorola()) {
	    @content=@newcontent;
	    $format = "Motorola S-Record/Exorciser/Exormacs/Exormax";
	} else {
	    if (determine_tekhex()) {
		@content = @newcontent;
		$format = "Tektronix";
	    } else {
		if  (determine_tekhex_extended()) {
		    @content = @newcontent;
		    $format = "Texktronix Extended";
		} else {
		    if  (0 && determine_tekhex_gnu()) {
			#merged with above
			@content = @newcontent;
		    } else {
			if (determine_startseq()) {
			    @content = @iary;
			    $format = "bitcov";
			} else {
			    foreach (split(//,$content)) {
				push (@content, ord $_);
			    }
			}
		    }
		}
	    }
	}
    }
}

if (defined $dumpfile)  {
    open OUT, ">$dumpfile";
    binmode OUT;
    foreach (@content) {
	print OUT chr($_);
    }
    close OUT;
}

if ($endian==-1) {
    while(defined ($char=shift @content)) {
	my $j = 0;
	my $c = $char;
	while ($j<8) {
	    $array[$start+$j]=($c&(1<<$j))?1:0;
	    $j++;
	}
	$start+=8;
    }
} else {
    if ($endian==2) {
	@array = @content;
    } else {
    # Non bit CTC_COUNTER
	while ($#content>=0) {
	    my $cnt = $bits>>3;
	    my $e = 0;
	    
	    if ($endian==1) {
		# Big endian
		while ($cnt--) {
		    $e+=(shift(@content)<<($cnt*8));
		}
	    } else {
		# Little endian
		my $i=0;
		while ($i<$cnt) {
		    $e+=(shift(@content)<<($i*8));
		    $i++;
		}
	    }
	    $array[$start++]=$e;
	}
    }
}

exit 0 if $mon_aux eq "-test" && ! -f $mon_aux;

$read_array_size = $#array;

@module_list = make_ctc_module_info($mon_aux);

$needed = $read_array_size;

if (($gcount-1) > $needed) {
    if ($bits==1) {
        die myname().": Dumped file $mon_dmp too small, has only ". $needed/8 . " bytes, but should have ". ($gcount/8+($gcount%1?1:0)). " bytes";
    } else {
        die myname().": Dumped file $mon_dmp too small, has only ". $needed*($bits>>3) . " bytes, but should have ". ($bits>>3)*($gcount). " bytes";
    }
}

if ($misused || $mistrail) {
    my $text = "";
    $text .=  "Sanity check on ".$misused." gap-bits failed, must be 0, but are 1, a can't be\n" if $misused;
    $text .=  "Sanity check on ".$mistrail." unused bits in last CTC_array[] byte failed, must be 0, but are 1, a can't be\n" if $mistrail;
    print STDERR "\n".$text;
    $sanity.=$text;
    if ($force) {
	ctc_send_data(); 
    } else {
	die "Your dumped file $mon_dmp is corrupted! Exiting...\n";
    }
} else {
ctc_send_data();
}

1;
# The program execution ends here. The definitions of the subroutines
# follow.

##########################################################################
# SUBROUTINES
##########################################################################

##########################################################################
# SUBROUTINE: parse_cmdline
# PURPOSE   : This subroutine parses the command line.
#
##########################################################################
sub parse_cmdline 
{
    my $i=0;
    for (;$i <=$#ARGV; $i++) {
	my $switch = $ARGV[$i];
	if ($switch eq "-h" || 
	    $switch eq "-?" || 
	    $switch eq "--help" || 
	    $switch eq "-usage" || 
	    $switch eq "--usage") {
	    usage();
	    exit 0;
	} elsif ($switch eq "--version") {
	    version();
	    exit 0;
	} elsif ($switch eq "-v" ||
		 $switch eq "--verbose") {
	    $verbose++;
	} elsif ($switch eq "--force") {
	    $force++;
	} elsif ($switch =~ /^-([bl])(8|16|32|64|128|256|512|1024)$/i) {
	    if (lc ($1) eq "l") {
		$endian = 0;
		$endian_str="Little Endian";
	    } else {
		$endian = 1;
		$endian_str="Big Endian";
	    }
	    $bits=$2;
	    $endian_str.=", based on $bits Bits per CTC_COUNTER";
	} elsif ($switch =~ /^-(8|16|32|64|128|256|512|1024)$/i) {
	    my $is_big_endian = unpack("h*", pack("s", 1)) =~ /01/;
	    $is_big_endian = 0 unless defined $is_big_endian;   

	    if (!$is_big_endian) {
		$endian = 0;
		$endian_str="Little Endian";
	    } else {
		$endian = 1;
		$endian_str="Big Endian";
	    }
	    $bits=$1;
	    $endian_str.=", based on $bits Bits per CTC_COUNTER";
	} elsif ($switch eq "--pad") {
	    $pad = hex2num($ARGV[++$i]);
	} elsif ($switch eq "--start") {
	    #currently unused
	    #$start_address = longhex2num($ARGV[++$i]);
	} elsif ($switch eq "--dump2") {
	    $dumpfile = $ARGV[++$i];
	} elsif ($switch eq "-o") {
	    $mon_txt = $ARGV[++$i];
	} elsif (!defined $mon_dmp) {
	    $mon_dmp = $switch;
	} elsif (!defined $mon_aux) {
	    $mon_aux = $switch;
	} else {
	    usage();
	    exit 1;
	}
    }
    if (defined $dumpfile &&
	defined $mon_dmp) {
	die myname().": to be dumped file $dumpfile and $mon_dmp are the same, exiting"
	    if $dumpfile eq $mon_dmp;
	die myname().": to be dumped file $dumpfile and $mon_aux are the same, exiting"
	    if $dumpfile eq $mon_aux;
    }
	
}

##########################################################################
# FUNCTION    : module_data_prepare
# PURPOSE     : Prepares the module data for array by array transfer
# ARGUMENTS   : - info: module information struct
# RETURNS     : nothing
# DESCRIPTION :
##########################################################################
sub module_data_prepare
{
    my ($info) = @_;
    my $index = 0;


    # Marker
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = 1;
    $module_data[$index]->{array}->{counter} =[ 0x13B8632D ];
    
    $index++;

    # First is the array of sizes
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = $SIZE_ARRAY_SIZE;
    $module_data[$index]->{array}->{counter} = [
	length $info->{source_path},
	length $info->{dat_file},
	$info->{num_s},
	$info->{num_j},
	$info->{num_tf},
	$info->{num_c},
	$info->{num_time}
	];
    $index++;

    $module_data[$index]->{array_type} = $a_stamp;
    $module_data[$index]->{array_size} = 1;
    $module_data[$index]->{array}->{counter} = [$info->{time_stamp}];
    $index++;

    $module_data[$index]->{array_type} = $a_string;
    $module_data[$index]->{array_size} = length $info->{source_path};
    $module_data[$index]->{array}->{string} = $info->{source_path};

    $index++;
    $module_data[$index]->{array_type} = $a_string;
    $module_data[$index]->{array_size} = length $info->{dat_file};
    $module_data[$index]->{array}->{string} = $info->{dat_file};

    $index++;
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = $info->{num_s};
    $module_data[$index]->{array}->{counter} = $info->{ctc_s};

    $index++;
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = $info->{num_j};
    $module_data[$index]->{array}->{counter} = $info->{ctc_j};

    $index++;
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = $info->{num_tf};
    $module_data[$index]->{array}->{counter} = $info->{ctc_t};

    $index++;
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = $info->{num_tf};
    $module_data[$index]->{array}->{counter} = $info->{ctc_f};

    $index++;
    $module_data[$index]->{array_type} = $a_counter;
    $module_data[$index]->{array_size} = $info->{num_c};
    $module_data[$index]->{array}->{counter} = $info->{ctc_c};

    $index++;
    $module_data[$index]->{array_type} = $a_timer;
    $module_data[$index]->{array_size} = $info->{num_time};
    $module_data[$index]->{array}->{timer} = $info->{ctc_time};

    $index++;
    $module_data[$index]->{array_type} = $a_timer;
    $module_data[$index]->{array_size} = $info->{num_time};
    $module_data[$index]->{array}->{timer} = $info->{ctc_maxtime};

    $module_data_current_array = 0;
    $module_data_current_array_index = 0;
}



##########################################################################
# FUNCTION  : make_ctc_module_info 
# PURPOSE   : creates CTC_MODULE_INFO out of memory dump + "MON.aux"
# ARGUMENTS : none
# RETURNS   : CTC_MODULE_INFO* 
##########################################################################
sub make_ctc_module_info
{
    my ($filename) = @_;
    my $info = undef;
    my @retinfo = ();
    my ($liste, $line, $tmp, $source_path, $dat_file);
    my ($start, $i);

    my $time_stamp;
    my ($num_s, $num_j, $num_tf, $num_c, $num_time);
    
    open LISTE, $filename or die myname().": Could not open file $filename: $!";
    
    while (<LISTE>) {
	chomp;
	$line = $_;

	($source_path, $dat_file, $time_stamp, $num_s, $num_j, $num_tf,
	 $num_c, $num_time,$start) = split(/\t/, $line);
  
	my $info = {
	    source_path=>$source_path,
	    dat_file => $dat_file,
	    time_stamp => $time_stamp,
	    rewrite_count => 0,
	    update_count => 0,
	    num_s => $num_s,
	    num_j => $num_j,
	    num_tf => $num_tf,
	    num_c => $num_c,
	    num_time => $num_time,
	    ctc_s => [],
	    ctc_j => [],
	    ctc_t => [],
	    ctc_f => [],
	    ctc_c => [],
	    ctc_time => [],
	    ctc_maxtime => [],
	    gap => []
	};
	$info->{ctc_s} = [copyarray($info->{num_s})];
	$start+=$info->{num_s};
	
	# for ($i=0; $i<$info->{num_s};$i++) {
	#     if (($info->{ctc_e}[$i]) &&
	# 	!($info->{ctc_s}[$i])) { 
	# 	$misused++;
	#     }
	# }
    
        $info->{ctc_j} = [copyarray($info->{num_j})];
	$start+=$info->{num_j};

        $info->{ctc_t} = [copyarray($info->{num_tf})];
	$start+=$info->{num_tf};

        $info->{ctc_f} = [copyarray($info->{num_tf})];
	$start+=$info->{num_tf};

        $info->{ctc_c} = [copyarray($info->{num_c})];
	$start+=$info->{num_c};
	
	$info->{ctc_time} = [copyarray($info->{num_time})];;
	$start+=$info->{num_time};

	$info->{ctc_maxtime} = [copyarray($info->{num_time})];;
	$start+=$info->{num_time};

	$info->{gap} = [copyarray(1)];;
	if ($info->{gap}[0]) {
	    $misused++;
	}
	$start++;

	push @retinfo, $info;
    }

    close LISTE;
    if ($endian==-1) {
	my $i=$start;
	while ((($i % 8)!=0) && $#array>=0 ) {
	    my $tt = shift(@array);
	    if ($tt) {
		$mistrail++;
	    }
	    $i++;
	}
    }

    $gcount = $start;

    return @retinfo;
}


##########################################################################
# FUNCTION  : copy_array
# PURPOSE   : copies the dumped array to real array
# ARGUMENTS : count - number of elements to copy
#             dest  - destination
#             src   - source 
# RETURNS   : Nothing 
##########################################################################
sub copyarray
{
    my ($count) = @_;
    my $i = 0;
    my @dest = ();

    while ($i++<$count) {
	push (@dest, (shift @array));
    }

    return @dest;
}




##########################################################################
# SUBROUTINE    : usage
# PURPOSE     : Prints usage information
# ARGUMENT    : name -- The name of this program, as invoked
# DESCRIPTION : Prints usage information out
##########################################################################
sub usage
{
    my ($name) =  @_;
    $name = "dmp2txt" unless defined $name && length $name;
    print "Usage: $name [options] MON.dmp MON.aux\n";
    print "\nRead more from ";
    if ($^O eq "MSWin32") {
	print "\%CTCHOME\%\\doc\\bitcov\\$name.txt";
    } else {
	print "\'man $name\'";
    }
    print "\n\n";
    
}

##########################################################################
# FUNCTION    : version
# PURPOSE     : Prints version information
# DESCRIPTION : Prists version information out
##########################################################################
sub version
{
    print myname()." $version\n";
}

##########################################################################
# FUNCTION  : ctc_send_data
# PURPOSE   : This is the function, which is called to transmit the
#             collected coverage data from the target main memory to
#             "somewhere". That "somewhere" can be e.g. a communication
#             line to the host computer (which has a program running to
#             receive the data), or it can be a local text file at the target.
#
#             The real implementation of this function needs to be written
#             by the user.
#
#             Here is a model implementation which writes the data as a text
#             file to the target machine disk. Possibly you can use this...
#
# ARGUMENTS : None
# RETURNS   : Nothing
##########################################################################
sub ctc_send_data
{
    my $ch;
    my $charcount=0;
    my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
    my @days = qw( Monday Tuesday Wednesday Thursday Friday Saturday Sunday );
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $year+=1900;
    $min = "0".$min if (length $min) ==1;
    $sec = "0".$sec if (length $sec) ==1;
    my $asc_time = $days[$wday]. ", ". $mday .". " . $months[$mon] . " $year $hour:"."$min:$sec";

    if (defined $mon_txt) {
	open OUT, ">>".$mon_txt;
	select OUT;
    }

    print "\nDump of CTC++ coverage data from target memory at $asc_time:\n\n";
    print "Commandline: $0 ";
    foreach (@ARGV) {
	print $_." ";
    }
    print "\n";
    print "CTC_COUNTER: ".$endian_str."\n" if length $endian_str;
    print "CTC_COUNTER: bits\n" unless length $endian_str;

    print "Dump file used: $mon_dmp\n";
    print "Dump file type: $format\n";
    if (!length $sanity) {
	if ($endian==-1) {
	    $sanity = "passed\n";
	} else {
	    $sanity = "(not applicable)\n";
	}
	
    }
    print "Sanity checks: $sanity\n";

    ctc_prepare_upload();
   
    while (defined ($ch=ctc_get_character())) {
	print $ch;
	if (((++$charcount) % 78)==0) {
	    print "\n";
	}
    }
    print "\n";

    if (defined $mon_txt) {
	close OUT;
	select STDOUT;
    }
}

##########################################################################
# FUNCTION  : ctc_prepare_upload
# PURPOSE   : Prepares the coverage data for transfer
# ARGUMENTS : None
# RETURNS   : Nothing
##########################################################################
sub ctc_prepare_upload
{
    # Initialize transfer state
    $transfer_state = $t_start;
    @transfer_buffer = ();
    $transfer_index = 0;
}

##########################################################################
# FUNCTION    : fill_buffer
# PURPOSE     : Fills the output buffer with characters
# ARGUMENTS   : - buffer: the output buffer
# RETURNS     : 1 on end of data
#               0 on more data
##########################################################################
sub fill_buffer
{
    my $finished = $CTC_FALSE;
    my $result = 0;

    $transfer_index = 0;
    while ($finished==$CTC_FALSE) {
        if ($transfer_state==$t_start) {
            # at the very beginning of "write-out burst", start sequence now 
	    foreach (split(//,$START_SEQ)) {
		push @transfer_buffer, $_;
	    }
            $finished = $CTC_TRUE;
            # and then, later, consider the first module 
            $module = shift @module_list;
            $transfer_state = $t_prepare_module;
	} elsif ($transfer_state == $t_prepare_module) {
            if (defined $module) {
                # prepare next module 
                if (module_is_all_zero($module)) {
                    # But skip it if it has zeros in all counters!
                    $module = shift @module_list;
                    $transfer_state = $t_prepare_module;
                } else {
                    # ok, there was some non-zero counters, output this... 
                    module_data_prepare($module);
                    $module = shift @module_list;
                    $transfer_state = $t_module_data;
                }
            } else {
                $transfer_state = $t_end;
            }
	} elsif ($transfer_state == $t_module_data) {
            if (!module_data_get()) {
                $finished = $CTC_TRUE;
            } else {
                $transfer_state = $t_prepare_module;
            }
        } elsif ($transfer_state == $t_end) {
	    foreach (split(//,$END_SEQ)) {
		push @transfer_buffer, $_;
	    }

            $transfer_state = $t_finished;
            $finished = $CTC_TRUE;

	} elsif ($transfer_state == $t_finished) {
            $result = 1;
            $finished = $CTC_TRUE;
	}
    }
    return $result;
}

##########################################################################
# FUNCTION    : module_data_get
# PURPOSE     : Gets the next number in the module data arrays into the
#               output buffer.
# ARGUMENTS   : - buffer: output buffer
# RETURNS     : 0 on success
#               1 on end of data
##########################################################################
sub module_data_get
{
    my $current_array_ptr;
    my $number = 0;

    # If the current array is finished, and there are more arrays, get the
    #   next array. A loop is used so that empty arrays (== array which is
    #   "already finished") are skipped. 
    while ($module_data_current_array < $MODULE_DATA_ARRAYS &&
           $module_data_current_array_index ==
           $module_data[$module_data_current_array]->{array_size})
    {
        # next data array
        $module_data_current_array++;
        $module_data_current_array_index = 0;
    }

    if ($module_data_current_array == $MODULE_DATA_ARRAYS) {
        # end of arrays 
        return 1;
    }
    $current_array_ptr = $module_data[$module_data_current_array];

    if ($current_array_ptr->{array_type} == $a_string) {
        $number = ord(substr($current_array_ptr->{array}->{string},
			     $module_data_current_array_index));
    } elsif ($current_array_ptr->{array_type} == $a_stamp) {
        $number = $current_array_ptr->{array}->{counter}
            [$module_data_current_array_index];
    } elsif ($current_array_ptr->{array_type} == $a_counter) {
        $number = $current_array_ptr->{array}->{counter}
            [$module_data_current_array_index];
    } elsif ($current_array_ptr->{array_type} == $a_timer) {
        $number = $current_array_ptr->{array}->{timer}
            [$module_data_current_array_index];
    } else {
	print "";
    }
    unless (defined $number) {
	print "";
    }
    number_to_string($number);
    $module_data_current_array_index++;

    return 0;
}

##########################################################################
# FUNCTION    : number_to_string
# PURPOSE     : Prints the given number as a string, ends the string with
#               the END_NUMBER delimiter.
# ARGUMENTS   : - i: the number to print
# RETURNS     : $buffer
# DESCRIPTION :
##########################################################################
sub number_to_string
{
    my ($i) = @_;
    my $end   = 0;
    my $start = 0;
    my $start_c;

    # Map into number_base (results in a reversed string)
    do {
        $transfer_buffer[$end++] = $NUMBER_MAP[$i % $NUMBER_BASE];
        $i = ($i-($i% $NUMBER_BASE)) / $NUMBER_BASE;
    } while ($i && $end < ($MAX_CHARS - 1));

    # Add number separator to end 
    $transfer_buffer[$end] = $END_NUMBER;
#    $transfer_buffer[$end + 1] = '\0';

    # Reverse number portion to correct order 
    $end--;
    while ($start < $end) {
        $start_c = $transfer_buffer[$start];
        $transfer_buffer[$start] = $transfer_buffer[$end];
        $transfer_buffer[$end] = $start_c;
        $start++;
        $end--;
    }

    return @transfer_buffer;
}



##########################################################################
# FUNCTION    : module_is_all_zero
# PURPOSE     : Check if module's counters are all zero
# ARGUMENTS   : - module: pointer to the module's counter (and timer) data
# RETURNS     : 1 (true) the module has all zero counters
#               0 (false) otherwise
##########################################################################
sub module_is_all_zero
{
    my ($module) = @_;
    my $i = 0;
    # each vector... first non-zero decides...
    for ($i = 0; $i < $module->{num_s}; $i++) {
        if ($module->{ctc_s}[$i] != 0) {return 0; }
    }
    for ($i = 0; $i < $module->{num_s}; $i++) {
        if ($module->{ctc_e}[$i] != 0) {return 0; }
    }
    for ($i = 0; $i < $module->{num_j}; $i++) {
        if ($module->{ctc_j}[$i] != 0) {return 0; }
    }
    for ($i = 0; $i < $module->{num_tf}; $i++) {
        if ($module->{ctc_t}[$i] != 0) {return 0; }
    }
    for ($i = 0; $i < $module->{num_tf}; $i++) {
        if ($module->{ctc_f}[$i] != 0) {return 0; }
    }
    for ($i = 0; $i < $module->{num_c}; $i++) {
        if ($module->{ctc_c}[$i] != 0) {return 0; }
    }
    # timings not considered...! 
    
    # when got this far, all was zero!
    return 1;
}


##########################################################################
# FUNCTION  : ctc_get_character
# PURPOSE   : Serializes the coverage data into a character
#             stream. After the last character is read, the
#             accumulated coverage data is cleared.
# ARGUMENTS : None
# RETURNS   : unsigned character or undef when there is no more data
##########################################################################

sub ctc_get_character
{
    # If buffer is empty, get next item 
    if ($#transfer_buffer == -1) {

        if (fill_buffer(@transfer_buffer)) {
            # Out of items, return end marker 
            return undef;
        }
    }
    # Return next character 
    return shift @transfer_buffer;
}

##########################################################################
# FUNCTION  : determine_intel
# PURPOSE   : Checks if dumped file is Intel HEX
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is Intel
##########################################################################
sub determine_intel
{
    my @lines = split(/\r?\n/, $content);
    (@newcontent) = ();
    my $cnt=0;
    my $smem = undef;
    my $lba = 0;

    foreach (@lines) {
	s/\cZ//;
	unless (/^\s*$/) {
	    $_=uppercase($_);
	    return 0 unless (/^:[\dABCDEF]+$/);
	    if (/^:(..)(....)(..)(.*)(..)$/) {
		my $reclen = hex2num($1);
		$offset = longhex2num($2);
		my $rectyp = $3;
		my $data = $4;
		my $chksum = hex2num($5);
		{
		    my $c = $1.$2.$3.$4.$5;
		    my $val = 0;
		    while (length $c) {
			$val+=hex2num($c);
			$c=substr($c,2);
		    }
		    return 0 if $val&0xff;
		    
		    return 0 if $reclen*2 != length $data; 
		}

		if (!defined($smem)&&$rectyp eq "00") {
		    $smem=$offset+$lba;
		} 

		if ($rectyp eq "00") {
		    my $i = 0;
		    my $gap=0;
		    if ($offset+$lba<$smem) {
			my $delta = $smem-($offset+$lba);
			while ($delta--) {
			    unshift @newcontent, undef;
			}
			$smem=$offset+$lba;
		    }
		    if ($lba && ($j=(($reclen-1+$offset)%0x10000) - $smem + $lba) <0) {
			my $delta=-(-$smem+$lba);
			$gap=$delta;
			while ($delta--) {
			    unshift @newcontent, undef;
			}

		    }
		    for ($i=0;$i<$reclen;$i++) {
			my $d = hex2num($data);
			$data=substr($data,2);
			$newcontent[(($i+$offset)%0x10000)-$smem+$lba+$gap] = $d;
		    }
		    $lba-=$gap;
		} elsif ($rectyp eq "02") {
		    $lba = (hex $data) << 4; # 20 bit segmented
		} elsif ($rectyp eq "04") {
		    $lba = (hex $data) << 16; # 32 bit linear
		} else {
		}
	    } else {
		return 0;
	    }
	}
    }
    foreach $j (0.. $#newcontent) {
	$newcontent[$j] = 0 unless defined $newcontent[$j];
    }
    print STDERR "$mon_dmp guessed as Intel MCS-86 format\n" if $verbose;
    return 1;
}


##########################################################################
# FUNCTION  : determine_intel16
# PURPOSE   : Checks if dumped file is Intel INHX16
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is Intel
##########################################################################
sub determine_intel16
{
    my @lines = split(/\r?\n/, $content);
    (@newcontent) = ();
    my $cnt=0;
    my $smem = undef;
    foreach (@lines) {
	unless (/^\s*$/) {
	    return 0 unless (/^:[\dABCDEF]+$/);
	    if (/^:(..)(....)(..)(.*)(..)$/) {
		my $reclen = hex2num($1) * 2;
		$offset = longhex2num($2)*2;
		my $rectyp = $3;
		my $data = $4;
		my $chksum = hex2num($5);
		{
		    my $c = $1.$2.$3.$4.$5;
		    my $val = 0;
		    while (length $c) {
			$val+=hex2num($c);
			$c=substr($c,2);
		    }
		    return 0 if $val&0xff;
		    
		    return 0 if $reclen*2 != length $data; 
		}

		if (!defined($smem)&&$rectyp eq "00") {
		    $smem=$offset;
		} 

		if ($rectyp eq "00") {
		    my $i = 0;
		    my $gap = 0;

		    if ($offset<$smem) {
			my $delta = $smem-$offset;
			while ($delta--) {
			    unshift @newcontent, undef;
			}
			$smem=$offset;
		    }

		    if (($j=(($reclen-1+$offset)%0x10000) - $smem + $lba) <0) {
			my $delta=-(-$smem+$lba);
			$gap=$delta;
			while ($delta--) {
			    unshift @newcontent, undef;
			}

		    }

		    while (length $data) {
			my $d1 = hex2num($data);
			$data=substr($data,2);
			my $d2 = hex2num($data);
			$data=substr($data,2);
			$newcontent[(($i+$offset)%0x10000)-$smem+$lba+$gap] = $d2;
			$i++;
			$newcontent[(($i+$offset)%0x10000)-$smem+$lba+$gap] = $d1;
			$i++;
		    }
		} elsif ($rectyp eq "02") {
		    $lba = (hex $data) << 4; # 20 bit segmented
		} elsif ($rectyp eq "04") {
		    $lba = (hex $data) << 16; # 32 bit linear
		} 
	    } else {
		return 0;
	    }
	}
    }
    foreach $j (0.. $#newcontent) {
	$newcontent[$j] = 0 unless defined $newcontent[$j];
    }
    print STDERR "$mon_dmp guessed as Intel INHX16 format\n" if $verbose;
    return 1;
}

##########################################################################
# FUNCTION  : determine_motorola
# PURPOSE   : Checks if dumped file is Motorola srecord
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is Motorola srecord
##########################################################################
sub determine_motorola
{
    my @lines = split(/\r?\n/, $content);
    (@newcontent) = ();
    my $cnt=0;
    my $smem = undef;
    my $checksum =0;
    foreach (@lines) {
	unless (/^\s*$/) {
	    return 0 unless (/^S/);
	    my $tt=$_;

	    if (/^S(\d)/) {
		my $case = $1;
		my $not=0;
		if ($case eq "1") {
		    if (/^S(.)(..)(....)(.*)$/) {
			$reclen=longhex2num($2)-3;
			$offset=longhex2num($3);
			$data=$4;
			$checksum=$reclen + 3 +
			    ($offset>>8) & 0xff  + 
			    ($offset & 0xff);
		    }
		} elsif ($case eq "2") {
		    if (/^S(.)(..)(......)(.*)$/) {
			$reclen=longhex2num($2)-4;
			$offset=longhex2num($3);
			$data=$4;
			$checksum=$reclen + 4 +
			    (($offset>>16)& 0xff) + 
			    (($offset>>8) & 0xff) + 
			    ($offset & 0xff);
		    }
		} elsif ($case eq "3") {
		    if (/^S(.)(..)(........)(.*)$/) {
			$reclen=longhex2num($2)-5;
			$offset=longhex2num($3);
			$data=$4;
			$checksum=$reclen + 5 +
			    ($offset>>32)& 0xff + 
			    ($offset>>16)& 0xff + 
			    ($offset>>8)& 0xff  + 
			    ($offset & 0xff);

		    } 
		} else {
		    $not++;
		}
		unless ($not) {
		    my $i=0;
		    unless (defined $smem) {
			$smem=$offset;
		    } elsif ($offset<$smem) {
			my $delta = $smem-$offset;
			while ($delta--) {
			    unshift @newcontent, undef;
			}
			$smem=$offset;
		    }
		    for ($i=0;$i<$reclen;$i++) {
			my $d = hex2num($data);
			$checksum = ($checksum + $d) & 0xff;
			$data=substr($data,2);
			$newcontent[$i+$offset-$smem] = $d;		    
		    }
		    $checksum=(0xff - $checksum) & 0xff;
		    if ($checksum != hex2num($data)) {
			print "";
			#FIXME checksum 
		    }
		}
	    }
	}
    }    
    foreach $j (0.. $#newcontent) {
	$newcontent[$j] = $pad unless defined $newcontent[$j];
    }
    print STDERR "$mon_dmp guessed as Motorola srecord format\n" if $verbose;
    return 1;
}

##########################################################################
# FUNCTION  : determine_tekhex_extended
# PURPOSE   : Checks if dumped file is Tekhex (extended)
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is Tekhex
##########################################################################
sub determine_tekhex_extended
{
    my @lines = split(/\r?\n/, $content);
    (@newcontent) = ();
    my $cnt=0;
    my $smem = undef;
    my $gnu = "";
    foreach (@lines) {
	unless (/^\s*$/) {
	    return 0 unless (/^\%/);
	    $gnu = " (GNU/gdb)" unless (/^\%[\dABCDEF]*$/);
	    if (/^.(..)(.)(..)(.)(.*)$/) {
		my $reclen = hex($1);
		my $rectyp = $2;
		my $chk = hex($3);
		my $alen = hex($4);
		my $rest = $5;
	        $offset= hex(substr($rest,0,$alen));
		my $data = substr($rest,$alen);
		if ($rectyp eq "6")
		{
		    my $val = 0;
		    foreach (split(//,$1.$2.$4.$5)) {
			$val+=hex($_);
		    }
		    if (($val&0xff) != $chk) {
			return 0;
		    }
		    if (($reclen - 1 - $alen) != length $data) {
			return 0;
		    }
		}


		$reclen = length $data;

		if (!defined($smem)&&$rectyp eq "6") {
		    $smem=$offset;
		} else {
		}
		if ($rectyp eq "6") {
		    my $i;
		    if ($offset<$smem) {
			my $delta = $smem-$offset;
			while ($delta--) {
			    unshift @newcontent, undef;
			}
			$smem=$offset;
		    }
		    for ($i=0;$i<($reclen/2);$i++) {
			my $d = hex2num($data);
			$data=substr($data,2);
			$newcontent[$i+$offset-$smem] = $d;
		    }
		} 
	    } else {
		return 0;
	    }
	}
    }
    foreach $j (0.. $#newcontent) {
	$newcontent[$j] = 255 unless defined $newcontent[$j];
    }
    print STDERR "$mon_dmp guessed as Tektronix (extended$gnu) format\n" if $verbose;
    return 1;
}

##########################################################################
# FUNCTION  : determine_tekhex
# PURPOSE   : Checks if dumped file is Tekhex 
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is Tekhex
##########################################################################
sub determine_tekhex
{
    my @lines = split(/\r?\n/, $content);
    (@newcontent) = ();
    my $cnt=0;
    my $smem = undef;
    foreach (@lines) {
	unless (/^\s*$/) {
	    return 0 unless (/^\//);
	    my $line = $_;
	    if (/^.(....)(..)(..)(.*)(..)$/) {
		my $reclen = hex2num($2);
		my $chk1 = hex2num($3);
		my $chk2 = hex2num($5);
		$offset = longhex2num($1);
		my $data = $4;
		
		{
		    # First checksum check
		    my (@nibbles) = split(//,substr($line,1,6));
		    my $val = 0;
		    foreach (@nibbles) {
			$val+=nibble2num($_);
		    }
		    if ($val != $chk1) {
			return 0;
		    }
		    # Second checksum check
		    @nibbles = split(//, $data);
		    $val = 0;
		    foreach (@nibbles) {
			$val+=nibble2num($_);
		    }
		    if (($val&0xff) != $chk2) {
			return 0;
		    }
		    
		}

		if (!defined($smem)) {
		    $smem=$offset;
		} else {
		}

		if (1) {
		    my $i;
		    #$reclen = (length $data ) / 2;
		    if ($offset<$smem) {
			my $delta = $smem-$offset;
			while ($delta--) {
			    unshift @newcontent, undef;
			}
			$smem=$offset;
		    }
		    for ($i=0;$i<($reclen);$i++) {
			my $d = hex2num($data);
			$data=substr($data,2);
			$newcontent[$i+$offset-$smem] = $d;
		    }
		} 
	    } elsif (/^.(..)(..)(..)(.*)$/) {
		if (hex2num($2)==0) {
		    foreach $j (0.. $#newcontent) {
			$newcontent[$j] = $pad unless defined $newcontent[$j];
		    }
		    print STDERR "$mon_dmp guessed as Tektronix (old, 16bit) format\n" if $verbose;
		    return 1;
		}
	    } else {
		return 0;
	    }
	}
    }
    foreach $j (0.. $#newcontent) {
	$newcontent[$j] = $pad unless defined $newcontent[$j];
    }
    print STDERR "$mon_dmp guessed as Tektronix (old, 16bit) format\n" if $verbose;
    return 1;
}

##########################################################################
# FUNCTION  : determine_tekhex_gnu
# PURPOSE   : Checks if dumped file is Tekhex (gnu)
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is Tekhex
##########################################################################
sub determine_tekhex_gnu
{
    my @lines = split(/\r?\n/, $content);
    (@newcontent) = ();
    my $cnt=0;
    my $smem = undef;
    foreach (@lines) {
	unless (/^\s*$/) {
	    return 0 unless (/^\%/);
	    my $line=$_;
	    if (/^.(..)(.)(..)(.)(.*)$/) {
		my $reclen = hex2num($1);
		my $rectyp = $2;
		my $chk = hex2num($3);
		my $alen = hex2num("0".$4);
		my $rest = $5;
		$offset=longhex2num(($alen%2?"0":"").substr($rest,0,$alen));
		$data = substr($rest,$alen);
		if ($rectyp eq "6")
		{
		    my (@nibbles) = split(//,$1.$2.$4.$5);
		    my $val = 0;
		    foreach (@nibbles) {
			$val+=nibble2num($_);
		    }
		    if ($val != $chk)  {
			return 0;
		    }
		    if (!defined($smem)&&$rectyp eq "6") {
			$smem=$offset;
		    } else {
		    }
		}

		if ($rectyp eq "6") {
		    my $i;
		    if ($offset<$smem) {
			my $delta = $smem-$offset;
			while ($delta--) {
			    unshift @newcontent, undef;
			}
			$smem=$offset;
		    }
		    for ($i=0;$i<($reclen/2);$i++) {
			my $d = hex2num($data);
			$data=substr($data,2);
			$newcontent[$i+$offset-$smem] = $d;
		    }
		} 
	    } else {
		return 0;
	    }
	}
    }
    foreach $j (0.. $#newcontent) {
	$newcontent[$j] = $pad unless defined $newcontent[$j];
    }
    print STDERR "$mon_dmp guessed as Tektronix (GNU, gdb) format\n" if $verbose;
    return 1;
}

##########################################################################
# FUNCTION  : determine_startseq
# PURPOSE   : Checks if dumped file is from CTC_array.c output
# ARGUMENTS : None (uses $content)
# RETURNS   : 1 - if so
#             0 - Otherwise
# MODIFIES  : @content, if it is startseq
##########################################################################
sub determine_startseq 
{
    my $status = 0;
    my $bit_cnt = -1;
    my $orig = $content;

    return undef unless $content=~/<start:/m;

    $content=~s/\nCTCDATA://gm;
    $content=~s/^CTCDATA://;

    while (!$status) {
	$status = wait_for_seq("<start:", 1);
	if ($status==0) {
	    $bit_cnt=receive_number();
	    if ($bit_cnt != 1) {
		$bits=$bit_cnt;
		#$content = $orig;
		#return undef; # Something wrong, not really a <start:..> sequence
	    }
	    $expected_size=receive_number();
	    if (defined $iary) {
		my $i=0;
		while (length $iary) {
		    my $e = substr($iary, 0, $bit_cnt==1?1:4);
		    if (length ($e) == 1) {
			$iary[$i]=ord($e);
		    } elsif (length ($e) == 4) {
			my $a;
			my $b;
			my $c;
			my $d;
			$_ = $e;
			if (!$is_big_endian) {
			    ($a,$b,$c,$d)=split();
			} else {
			    ($d,$c,$b,$a)=split();
			}
			$iary[$i]=ord($a)+ord($b)<<8+ord($c)<<16+ord($d)<<24;
		    }
		    $iary=substr($iary,$bit_cnt==1?1:4);
		    $i++;
		}
	    }
	    {
		if ($#iary<0) {
		    my $i=0;
		    for ($i=0;$i<$expected_size;$i++) {
			$iary[$i]=0;
		    }
		}
		for ($i=0;$i<$expected_size;$i++) {
		    if ($bit_cnt!=1) {
			$iary[$i]+=receive_number();
		    } else {
			$iary[$i]|=receive_number();
		    }
		}
		$_ = receive_data();
		die "Inconsistent array size" unless $_ eq ">";
	    }


	}
    } 
    if ($#iary>0) {
	if ($bits>1) {
	    $endian = 2; #This already converted, 2 ok.
	}
	return 1;
    }
}


##########################################################################
# FUNCTION  : longhex2num
# PURPOSE   : converts a string with hexdigits to a decimal numer
# ARGUMENTS : $string to be converted (0-9A-F only, pairwise)
# RETURNS   : $num = the calculated number
##########################################################################
sub longhex2num
{
    my ($string) = @_;
    my $ret = 0;
    while (length $string) {
	$ret*=256;
	$ret+=hex2num($string);
	$string = substr($string,2);
    }
    return $ret;
}

##########################################################################
# FUNCTION  : hex2num
# PURPOSE   : converts a two digit hexstring  decimal numer
# ARGUMENTS : $string to be converted (0-9A-F only, only first two used)
# RETURNS   : $num = the calculated number
##########################################################################
sub hex2num 
{
    my ($string) = @_;
    my $first = ord($string);
    my $second = ord(substr($string,1));
    my $val = 0;

    if ($first >= ord("0") &&
	$first <= ord("9")) {
	$first-=ord("0");
    } else {
	$first-=ord("A");
	$first+=10;
    }

    if ($second >= ord("0") &&
	$second <= ord("9")) {
	$second-=ord("0");
    } else {
	$second-=ord("A");
	$second+=10;
    }

    return 16*$first + $second;
}


##########################################################################
# FUNCTION  : nibble2num
# PURPOSE   : converts a one digit hexstring to decimal numer
# ARGUMENTS : $string to be converted (0-9A-F only, only first one used)
# RETURNS   : $num = the calculated number
##########################################################################
sub nibble2num
{
    my ($string) = @_;
    my $first = ord($string);

    if ($first >= ord("0") &&
	$first <= ord("9")) {
	$first-=ord("0");
    } else {
	$first-=ord("A");
	$first+=10;
    }

    return $first;
    
}

##########################################################################
# FUNCTION  : read_content
# PURPOSE   : Reads a MON.dmp file into a string
# ARGUMENTS : $mon_dmp -- MON.dmp file to be read
# RETURNS   : $content -- Content of MON.dat as Perl string
##########################################################################
sub read_content
{
    my ($mon_dmp) = @_;
    my $content;

    open IN, $mon_dmp or die myname()." can't open $mon_dmp for reading: $!";
    binmode IN;
    local $/;
    $content = <IN>;
    close IN;
    return $content;
}

##########################################################################
# SUBROUTINE: basename
# PURPOSE   : Strip directory from a filename
##########################################################################
sub basename 
{
    my ($filename) = @_;
    my $base = $filename;
    my $end;

    $end = rindex $filename, '\\';
    if ((rindex $filename, '/') > $end) {
       $end = rindex $filename, '/';
    }
    if ($end >= 0) {
       $base = substr $filename, $end + 1;
    }
    return $base;
}

##########################################################################
# SUBROUTINE: myname
# PURPOSE   : Gets tool name out of $0
# RETURNS   : Toolname
##########################################################################
sub myname
{
    my $name = basename($0);
    $name=~s/.bat$//i;
    $name=~s/.pl$//i;
    return $name;
}

##########################################################################
# FUNCTION  : uppercase
# PURPOSE   : converts string to uppercase a-f only
# ARGUMENTS : $string to be converted 
# RETURNS   : $string - The uppercased string
# NOTE      : We don't do this with Perl uc / ucfirst, cause 
#             that honors UTF-8
##########################################################################
sub uppercase
{
    my ($string) = @_;
    my $result = '';
    
    while (length $string) {
	my $c = substr($string, 0, 1);
	$string=substr($string, 1);
	$c = 'A' if $c eq 'a';
	$c = 'B' if $c eq 'b';
	$c = 'C' if $c eq 'c';
	$c = 'D' if $c eq 'd';
	$c = 'E' if $c eq 'e';
	$c = 'F' if $c eq 'f';
	$result.=$c;
    }

    return $result;
}

##########################################################################
# FUNCTION  : wait_for_sequence
# PURPOSE   : Waits for a specified sequence. If other sequences are to be
#             ignored, the sequence must not contain duplicate characters.
# ARGUMENTS : - sequence: sequence to wait for
#              - ignore_other: if non-zero, other sequences are ignored and
#                information about the garbage is printed
#  RETURNS   : - host_ok 0 
#              - host_user_abort 1
#              - host_transmission_error 2
##########################################################################
sub wait_for_seq 
{
    my ($sequence, $ignore_other) = @_;
    my $ptr=$sequence;
    my $c = 0;
    while (length($ptr) && 
	   defined ($c = ctc_receive_data()) && 
	   $c != -1) 
    {
        if (substr($ptr,0,1) eq $c) {
            $ptr=substr($ptr,1);
        } else {
            if ($ignore_other) {
                $ptr=$sequence;
            } else {
                die;
            }
        }

    }
    return -1 if $c == -1; #EOF

    if (length $ptr) {
        return -2;
    }
    return 0;
}
##########################################################################
#  FUNCTION  : receive_number
#  PURPOSE   : Reads a number and NUMBER_END marker from the data sequence
#               using receive_data(). Note that a NUMBER_END by itself
#              is also accepted, as zero.
#  ARGUMENTS : (none)
#  RETURNS   : - $number
#              or
#              - undef
##########################################################################

sub receive_number
{
    my $c;
    my $number;
    my $cindex;
    while (defined ($c = receive_data()) &&
           ($cindex = index($NUMBER_MAP, $c))>=0)
    {
        $number = $number * $NUMBER_BASE + ($cindex);
    }
    $c=ord($c);
    if ($c < 0) {
	return undef;
    } elsif ($c != ord(',')) {
	return undef;
    } else {
        return $number;
    }
    return undef;
}

##########################################################################
# FUNCTION  : receive_data
# PURPOSE   : wrapper for ctc_receive_data()
##########################################################################
sub receive_data
{
    return ctc_receive_data();
}

##########################################################################
# FUNCTION  : ctc_receive_data
# PURPOSE   : This is the function, which is called from above
#             to read the coverage data. The coverage data is read from
#             from a $content. From the
#              begnning of input stream intelligently detects if there is
#              first "\nCTCDATA:" (CTC4STD use) or "<START:" (normal use).
#  ARGUMENTS : None
#  RETURNS   : one char as int, -1 at EOF, -2 at some other error than EOF.
#               ('\n' and '\r' chars are absorbed away)
##########################################################################
sub ctc_receive_data
{
    my $c;
    while (1) {
        $c=substr($content,0,1);
	$content=substr($content,1);
        if (defined $c &&
            ord($c)>=32) {
            return $c;
        } 
	return -1 unless length $content;
        return -2 unless defined $c;
    }
    
}



# EOF $RCSfile:$
__END__
:NoCTCHOME
echo.
echo The environment variable CTCHOME does not exist. Set CTCHOME
echo to point to the CTC++ installation directory! (Use short name
echo for it so that the value does not contain spaces!)
echo.
goto End

:Nosetup
echo.
echo Cannot find '%%CTCHOME%%\%%NAME%%'. Set CTCHOME
echo to point to the CTC++ installation directory! (Use short name
echo for it so that the value does not contain spaces!)
echo.
goto End

:NoPerl
echo.
echo Cannot find the '%%CTCHOME%%\perl\perl.exe' program. Set CTCHOME
echo to point to the CTC++ installation directory! (Use short name
echo for it so that the value does not contain spaces!)
echo.
goto End

:End
exit /b 1

