#!perl -w
use strict;
no strict "vars";
use Bit::Vector;
# ======================================================================
# parameter checks
# ======================================================================
$prefix = 'Bit::Vector';
print "1..964\n";
$n = 1;
# parameter types:
# 0 = object reference
# 1 = number of bits
# 2 = index ( 0 <= index < bits )
# 3 = offset ( 0 <= offset <= bits )
# 4 = word index ( 0 <= index < size )
# 5 = length ( 0 <= offset+length <= bits )
# 6 = arbitrary (non-negative) number
# 7 = boolean
# 8 = string
# 9 = chunksize
# 10 = anything
# 11 = rows
# 12 = columns
# 16 = any number of object references
# 18 = any number of indices
# 22 = any number of arbitrary numbers
$method_list{'Version'} = [ ];
$method_list{'Word_Bits'} = [ ];
$method_list{'Long_Bits'} = [ ];
$method_list{'Create'} = [ 10, 1 ];
$method_list{'Shadow'} = [ 0 ];
$method_list{'Clone'} = [ 0 ];
$method_list{'Concat'} = [ 0, 0 ];
$method_list{'Concat_List'} = [ 16, 16, 16, 16, 16 ];
$method_list{'Size'} = [ 0 ];
$method_list{'Resize'} = [ 0, 1 ];
$method_list{'Copy'} = [ 0, 0 ];
$method_list{'Empty'} = [ 0 ];
$method_list{'Fill'} = [ 0 ];
$method_list{'Flip'} = [ 0 ];
$method_list{'Primes'} = [ 0 ];
$method_list{'Reverse'} = [ 0, 0 ];
$method_list{'Interval_Empty'} = [ 0, 2, 2 ];
$method_list{'Interval_Fill'} = [ 0, 2, 2 ];
$method_list{'Interval_Flip'} = [ 0, 2, 2 ];
$method_list{'Interval_Reverse'} = [ 0, 2, 2 ];
$method_list{'Interval_Scan_inc'} = [ 0, 2 ];
$method_list{'Interval_Scan_dec'} = [ 0, 2 ];
$method_list{'Interval_Copy'} = [ 0, 0, 2, 2, 5 ];
$method_list{'Interval_Substitute'} = [ 0, 0, 3, 5, 3, 5 ];
$method_list{'is_empty'} = [ 0 ];
$method_list{'is_full'} = [ 0 ];
$method_list{'equal'} = [ 0, 0 ];
$method_list{'Lexicompare'} = [ 0, 0 ];
$method_list{'Compare'} = [ 0, 0 ];
$method_list{'to_Hex'} = [ 0 ];
$method_list{'from_Hex'} = [ 0, 8 ];
$method_list{'to_Bin'} = [ 0 ];
$method_list{'from_Bin'} = [ 0, 8 ];
$method_list{'to_Dec'} = [ 0 ];
$method_list{'from_Dec'} = [ 0, 8 ];
$method_list{'to_Enum'} = [ 0 ];
$method_list{'from_Enum'} = [ 0, 8 ];
$method_list{'new_Hex'} = [ 10, 1, 8 ];
$method_list{'new_Bin'} = [ 10, 1, 8 ];
$method_list{'new_Dec'} = [ 10, 1, 8 ];
$method_list{'new_Enum'} = [ 10, 1, 8 ];
$method_list{'Bit_Off'} = [ 0, 2 ];
$method_list{'Bit_On'} = [ 0, 2 ];
$method_list{'bit_flip'} = [ 0, 2 ];
$method_list{'bit_test'} = [ 0, 2 ];
$method_list{'Bit_Copy'} = [ 0, 2, 7 ];
$method_list{'LSB'} = [ 0, 7 ];
$method_list{'MSB'} = [ 0, 7 ];
$method_list{'lsb'} = [ 0 ];
$method_list{'msb'} = [ 0 ];
$method_list{'rotate_left'} = [ 0 ];
$method_list{'rotate_right'} = [ 0 ];
$method_list{'shift_left'} = [ 0, 7 ];
$method_list{'shift_right'} = [ 0, 7 ];
$method_list{'Move_Left'} = [ 0, 6 ];
$method_list{'Move_Right'} = [ 0, 6 ];
$method_list{'Insert'} = [ 0, 2, 6 ];
$method_list{'Delete'} = [ 0, 2, 6 ];
$method_list{'increment'} = [ 0 ];
$method_list{'decrement'} = [ 0 ];
$method_list{'add'} = [ 0, 0, 0, 7 ];
$method_list{'subtract'} = [ 0, 0, 0, 7 ];
$method_list{'Negate'} = [ 0, 0 ];
$method_list{'Absolute'} = [ 0, 0 ];
$method_list{'Sign'} = [ 0 ];
$method_list{'Multiply'} = [ 0, 0, 0 ];
$method_list{'Divide'} = [ 0, 0, 0, 0 ];
$method_list{'GCD'} = [ 0, 0, 0 ];
$method_list{'Power'} = [ 0, 0, 0 ];
$method_list{'Block_Store'} = [ 0, 8 ];
$method_list{'Block_Read'} = [ 0 ];
$method_list{'Word_Size'} = [ 0 ];
$method_list{'Word_Store'} = [ 0, 4, 6 ];
$method_list{'Word_Read'} = [ 0, 4 ];
$method_list{'Word_List_Store'} = [ 0, 22, 22, 22, 22, 22 ];
$method_list{'Word_List_Read'} = [ 0 ];
$method_list{'Word_Insert'} = [ 0, 4, 6 ];
$method_list{'Word_Delete'} = [ 0, 4, 6 ];
$method_list{'Chunk_Store'} = [ 0, 9, 2, 6 ];
$method_list{'Chunk_Read'} = [ 0, 9, 2 ];
$method_list{'Chunk_List_Store'} = [ 0, 9, 22, 22, 22, 22, 22 ];
$method_list{'Chunk_List_Read'} = [ 0, 9 ];
$method_list{'Index_List_Remove'} = [ 0, 18, 18, 18, 18, 18 ];
$method_list{'Index_List_Store'} = [ 0, 18, 18, 18, 18, 18 ];
$method_list{'Index_List_Read'} = [ 0 ];
$method_list{'Union'} = [ 0, 0, 0 ];
$method_list{'Intersection'} = [ 0, 0, 0 ];
$method_list{'Difference'} = [ 0, 0, 0 ];
$method_list{'ExclusiveOr'} = [ 0, 0, 0 ];
$method_list{'Complement'} = [ 0, 0 ];
$method_list{'subset'} = [ 0, 0 ];
$method_list{'Norm'} = [ 0 ];
$method_list{'Min'} = [ 0 ];
$method_list{'Max'} = [ 0 ];
$method_list{'Multiplication'} = [ 0, 11, 12, 0, 11, 12, 0, 11, 12 ];
$method_list{'Product'} = [ 0, 11, 12, 0, 11, 12, 0, 11, 12 ];
$method_list{'Closure'} = [ 0, 11, 12 ];
$method_list{'Transpose'} = [ 0, 11, 12, 0, 11, 12 ];
foreach $method (sort keys(%method_list))
{
$definition = $method_list{$method};
$count = @{$definition};
if ($count == 0)
{
$action = "\$dummy = ${prefix}::${method}();";
eval "$action";
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
$action = "\$dummy = ${prefix}::${method}(\$dummy);";
eval "$action";
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
$action = "\$dummy = ${prefix}::${method}(\$dummy,\$dummy);";
$message = "Usage: ${prefix}->${method}\\(\\)";
eval "$action";
if ($@ =~ /$message/)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
}
else
{
$action = "${prefix}::${method}(\@parameter_list);";
$leadin = "${prefix}::${method}\\(\\): ";
foreach $bits (1024)
{
&init_objects();
&correct_values(0);
undef @parameters;
@parameters = @parameter_list;
eval "$action";
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if ($objects > 1)
{
&init_objects();
&correct_values(1);
eval "$action";
if (($method eq "Divide") or ($method eq "Power"))
{
if ($@ =~ /result vector\(s\) must be distinct/)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
}
else
{
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
}
}
if ($limited)
{
$message = "Usage: (?:${prefix}::)?${method}\\([a-zA-Z\\[\\]_, ]+\\)";
&refresh();
pop(@parameter_list);
eval "$action";
if ($@ =~ /$message/)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
&refresh();
push(@parameter_list,0);
push(@parameter_list,0) if ($method eq "Create");
eval "$action";
if ($@ =~ /$message/)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
}
&init_values();
for ( $i = 0; $i < $count; $i++ )
{
$type = $definition->[$i];
$type &= 0x0F;
$values = @{$wrong_values[$type]};
for ( $j = 0; $j < $values; $j++ )
{
&refresh();
$parameter_list[$i] = $wrong_values[$type]->[$j];
$message = $leadin . $error_message[$type]->[$j];
eval "$action";
# Special cases "Copy()" and "Power()":
if (($n == 170) or ($n == 174) or ($n == 574) or ($n == 578))
{
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
}
else
{
if ($@ =~ /$message/)
{print "ok $n\n";} else {print "not ok $n\n";}
}
$n++;
}
}
}
}
}
sub refresh
{
if ($method eq "Resize")
{
&init_objects();
&correct_values(0);
}
else
{
undef @parameter_list;
@parameter_list = @parameters;
}
}
sub init_objects
{
undef @vector;
$vector[0] = Bit::Vector->new($bits);
$vector[1] = Bit::Vector->new($bits);
$vector[2] = Bit::Vector->new($bits);
$vector[3] = Bit::Vector->new($bits);
$vector[4] = Bit::Vector->new($bits);
$vector[5] = Bit::Vector->new($bits);
$vector[6] = Bit::Vector->new($bits);
if ($bits > 0)
{
$vector[0]->Bit_On(0);
$vector[1]->Bit_On(0);
$vector[2]->Bit_On(0);
$vector[3]->Bit_On(0);
$vector[4]->Bit_On(0);
$vector[5]->Bit_On(0);
$vector[6]->Bit_On(0);
}
}
sub correct_values
{
my($flag) = @_;
my($i,$type);
# 0 = object reference
# 1 = number of bits
# 2 = index ( 0 <= index < bits )
# 3 = offset ( 0 <= offset <= bits )
# 4 = word index ( 0 <= index < size )
# 5 = length ( 0 <= offset+length <= bits )
# 6 = arbitrary (non-negative) number
# 7 = boolean
# 8 = string
# 9 = chunksize
# 10 = anything
# 11 = rows
# 12 = columns
$objects = 0;
$limited = 1;
undef @parameter_list;
for ( $i = 0; $i < $count; $i++ )
{
$type = $definition->[$i];
if ($type >= 16) { $limited = 0; }
$type &= 0x0F;
if ($type == 0)
{
$objects++;
if ($flag)
{
$parameter_list[$i] = $vector[0];
}
else
{
$parameter_list[$i] = $vector[$i];
}
}
elsif ($type == 1)
{
$parameter_list[$i] = ($bits << 1) | 1;
}
elsif ($type == 2)
{
$parameter_list[$i] = $bits - 1;
}
elsif ($type == 3)
{
$parameter_list[$i] = $bits;
}
elsif ($type == 4)
{
$parameter_list[$i] = $vector[0]->Word_Size() - 1;
}
elsif ($type == 5)
{
$parameter_list[$i] = $bits + 1;
}
elsif ($type == 6)
{
$parameter_list[$i] = (1 << (Bit::Vector->Word_Bits()-1)) - 1;
}
elsif ($type == 7)
{
$parameter_list[$i] = 1;
}
elsif ($type == 8)
{
$parameter_list[$i] = '1011';
}
elsif ($type == 9)
{
$parameter_list[$i] = Bit::Vector->Long_Bits();
}
elsif ($type == 10)
{
$parameter_list[$i] = 'anything';
}
elsif ($type == 11)
{
$parameter_list[$i] = int(sqrt($bits) + 0.5);
}
elsif ($type == 12)
{
$parameter_list[$i] = int(sqrt($bits) + 0.5);
}
else
{
die "internal error";
}
}
}
sub init_values
{
undef @fake;
undef @wrong_values;
undef @error_message;
$wrong_values[0] = [ ];
$error_message[0] = [ ];
$wrong_values[1] = [ ];
$error_message[1] = [ ];
$wrong_values[2] = [ ];
$error_message[2] = [ ];
$wrong_values[3] = [ ];
$error_message[3] = [ ];
$wrong_values[4] = [ ];
$error_message[4] = [ ];
$wrong_values[5] = [ ];
$error_message[5] = [ ];
$wrong_values[6] = [ ];
$error_message[6] = [ ];
$wrong_values[7] = [ ];
$error_message[7] = [ ];
$wrong_values[8] = [ ];
$error_message[8] = [ ];
$wrong_values[9] = [ ];
$error_message[9] = [ ];
$wrong_values[10] = [ ];
$error_message[10] = [ ];
$wrong_values[11] = [ ];
$error_message[11] = [ ];
$wrong_values[12] = [ ];
$error_message[12] = [ ];
# 0 = object reference
# 1 = number of bits
# 2 = index ( 0 <= index < bits )
# 3 = offset ( 0 <= offset <= bits )
# 4 = word index ( 0 <= index < size )
# 5 = length ( 0 <= offset+length <= bits )
# 6 = arbitrary (non-negative) number
# 7 = boolean
# 8 = string
# 9 = chunksize
# 10 = anything
# 11 = rows
# 12 = columns
if ($objects > 1)
{
if ($method !~ /^(?:Concat(?:_List)?|Interval_(?:Copy|Substitute))$/)
{
push(@{$wrong_values[0]}, Bit::Vector->new($bits-1));
push(@{$error_message[0]}, "(?:bit vector|set|matrix) size mismatch");
}
}
$global = 0x000E9CE0;
if ($method ne "Concat_List")
{
push(@{$wrong_values[0]}, $global);
push(@{$error_message[0]}, "item is not a \"$prefix\" object");
}
$fake[0] = Bit::Vector->new($bits);
$fake[0]->DESTROY();
push(@{$wrong_values[0]}, $fake[0]);
push(@{$error_message[0]}, "item is not a \"$prefix\" object");
$fake[1] = \$global;
bless($fake[1], $prefix);
push(@{$wrong_values[0]}, $fake[1]);
push(@{$error_message[0]}, "item is not a \"$prefix\" object");
# push(@{$wrong_values[1]}, -1);
# push(@{$error_message[1]}, "unable to allocate memory");
push(@{$wrong_values[2]}, $bits);
push(@{$error_message[2]}, "(?:(?:start |m(?:in|ax)imum )?index|offset) out of range");
push(@{$wrong_values[2]}, -1);
push(@{$error_message[2]}, "(?:(?:start |m(?:in|ax)imum )?index|offset) out of range");
push(@{$wrong_values[3]}, $bits+1);
push(@{$error_message[3]}, "offset out of range");
push(@{$wrong_values[3]}, -1);
push(@{$error_message[3]}, "offset out of range");
push(@{$wrong_values[4]}, $vector[0]->Word_Size());
push(@{$error_message[4]}, "offset out of range");
push(@{$wrong_values[4]}, -1);
push(@{$error_message[4]}, "offset out of range");
push(@{$wrong_values[9]}, 0);
push(@{$error_message[9]}, "chunk size out of range");
push(@{$wrong_values[9]}, Bit::Vector->Long_Bits()+1);
push(@{$error_message[9]}, "chunk size out of range");
push(@{$wrong_values[9]}, -1);
push(@{$error_message[9]}, "chunk size out of range");
push(@{$wrong_values[11]}, 0);
push(@{$error_message[11]}, "matrix size mismatch");
push(@{$wrong_values[12]}, 0);
push(@{$error_message[12]}, "matrix size mismatch");
push(@{$wrong_values[1]}, \$global);
push(@{$error_message[1]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[2]}, \$global);
push(@{$error_message[2]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[3]}, \$global);
push(@{$error_message[3]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[4]}, \$global);
push(@{$error_message[4]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[5]}, \$global);
push(@{$error_message[5]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[6]}, \$global);
push(@{$error_message[6]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[7]}, \$global);
push(@{$error_message[7]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[8]}, \$global);
push(@{$error_message[8]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[9]}, \$global);
push(@{$error_message[9]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[11]}, \$global);
push(@{$error_message[11]}, "item is not a (?:string|scalar)");
push(@{$wrong_values[12]}, \$global);
push(@{$error_message[12]}, "item is not a (?:string|scalar)");
}
__END__