|
Packit |
0b5880 |
#!/usr/bin/perl
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
# Purpose:
|
|
Packit |
0b5880 |
# Generates Assert/Fail macros for use with check.
|
|
Packit |
0b5880 |
#
|
|
Packit |
0b5880 |
# Usage:
|
|
Packit |
0b5880 |
# make_macros macros.in > macros.h
|
|
Packit |
0b5880 |
#
|
|
Packit |
0b5880 |
# macros.in: one or more lines containing...
|
|
Packit |
0b5880 |
# Assert
|
|
Packit |
0b5880 |
# Assert_(|not)(Success|Error|Failure|NULL|True|False|Same)
|
|
Packit |
0b5880 |
# Fail_(if|unless)(Success|Error|Failure|NULL|True|False|Same)
|
|
Packit |
0b5880 |
# Assert_(|not)(0[0-7]+|0x[0-9A-Fa-f]+|0b[01]+|[1-9][0-9]+)
|
|
Packit |
0b5880 |
# Fail_(if|unless)(0[0-7]+|0x[0-9A-Fa-f]+|0b[01]+|[1-9][0-9]+)
|
|
Packit |
0b5880 |
# Assert_(|not)(LT|LE|EQ|GE|GT|NE)
|
|
Packit |
0b5880 |
# Fail_(if|unless)(LT|LE|EQ|GE|GT|NE)
|
|
Packit |
0b5880 |
# Assert_(|not){Type}(LT|LE|EQ|GE|GT|NE)
|
|
Packit |
0b5880 |
# Fail_(if|unless){Type}(LT|LE|EQ|GE|GT|NE)
|
|
Packit |
0b5880 |
# {Type}_compare
|
|
Packit |
0b5880 |
#
|
|
Packit |
0b5880 |
# Example:
|
|
Packit |
0b5880 |
# echo -e 'Assert_notNULL\nAssertStringEQ' | make_macros > macros.h
|
|
Packit |
0b5880 |
#
|
|
Packit |
0b5880 |
# #include "macros.h"
|
|
Packit |
0b5880 |
# ...
|
|
Packit |
0b5880 |
# char *foo;
|
|
Packit |
0b5880 |
# Assert_notNULL( foo = strdup( "foo" ) , NULL );
|
|
Packit |
0b5880 |
# Assert_StringEQ( foo, "foo", NULL );
|
|
Packit |
0b5880 |
#
|
|
Packit |
0b5880 |
# author: unknown... if you know, please correct or email check-devel
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
use warnings;
|
|
Packit |
0b5880 |
use strict;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
use Switch 'Perl6';
|
|
Packit |
0b5880 |
use Text::Wrap;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
our %need;
|
|
Packit |
0b5880 |
our %include;
|
|
Packit |
0b5880 |
our %macros;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
sub make_macro {
|
|
Packit |
0b5880 |
my ($name, $fh) = @_;
|
|
Packit |
0b5880 |
my ($condition) = $name;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my ($failIf, $failUnless, $assertNot, $assert);
|
|
Packit |
0b5880 |
for ($condition) {
|
|
Packit |
0b5880 |
$failIf = 1, next if s/^ Fail_ if ([A-Z0-9]?) /$1/x;
|
|
Packit |
0b5880 |
$failUnless = 1, next if s/^ Fail_ unless ([A-Z0-9]?) /$1/x;
|
|
Packit |
0b5880 |
$assertNot = 1, next if s/^ Assert_ not ([A-Z0-9] ) /$1/x;
|
|
Packit |
0b5880 |
$assert = 1, next if s/^ Assert_ (. ) /$1/x;
|
|
Packit |
0b5880 |
$assert = 1, next if s/^ Assert $//x;
|
|
Packit |
0b5880 |
print $fh "#error don't know how to make ${name}\n\n";
|
|
Packit |
0b5880 |
return;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my ($invert) = 0;
|
|
Packit |
0b5880 |
foreach ($failIf, $assertNot) {
|
|
Packit |
0b5880 |
$invert = !$invert if $_;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my $type = "";
|
|
Packit |
0b5880 |
if ($condition =~ s/(LT|LE|EQ|GE|GT|NE)$//) {
|
|
Packit |
0b5880 |
$type = $condition;
|
|
Packit |
0b5880 |
$condition = $1;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
$type = "Number" unless length $type;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my (@args) = qw( expr );
|
|
Packit |
0b5880 |
my ($expr) = qw( (expr) );
|
|
Packit |
0b5880 |
my ($msg);
|
|
Packit |
0b5880 |
my ($doc);
|
|
Packit |
0b5880 |
my (%argdocs) = (
|
|
Packit |
0b5880 |
expr => "The expression to test."
|
|
Packit |
0b5880 |
);
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my ($not) = sub { $invert ? "not " : "" };
|
|
Packit |
0b5880 |
my ($Not) = sub { $invert ? "" : "not " };
|
|
Packit |
0b5880 |
my ($EQ) = sub { $invert ? "!=" : "==" };
|
|
Packit |
0b5880 |
my ($NE) = sub { $invert ? "==" : "!=" };
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
given ($condition) {
|
|
Packit |
0b5880 |
when "" {
|
|
Packit |
0b5880 |
unless ( $invert ) {
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr is true.";
|
|
Packit |
0b5880 |
$msg = "Assertion '\"#expr\"' failed.";
|
|
Packit |
0b5880 |
} else {
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr is false.";
|
|
Packit |
0b5880 |
$msg = "Negative assertion '\"#expr\"' failed";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when [qw(Error error Failure failure Success success)] {
|
|
Packit |
0b5880 |
$invert = !$invert when [qw(Success success)];
|
|
Packit |
0b5880 |
unless ( $invert ) {
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr failed.";
|
|
Packit |
0b5880 |
$msg = "'\"#expr\"' did not fail";
|
|
Packit |
0b5880 |
} else {
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr did not fail.";
|
|
Packit |
0b5880 |
$msg = "'\"#expr\"' failed";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
$invert = !$invert;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when [qw(True true False false)] {
|
|
Packit |
0b5880 |
$invert = !$invert when "false";
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr is ".( $invert ? "false" : "true" ).".";
|
|
Packit |
0b5880 |
$msg = "'\"#expr\"' was " . ( $invert ? "true" : "false" );
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when "NULL" {
|
|
Packit |
0b5880 |
$msg = "'\"#expr\"' was ".&$Not."NULL";
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr is ".&$not."NULL";
|
|
Packit |
0b5880 |
$expr = "(expr) ".&$EQ." NULL";
|
|
Packit |
0b5880 |
$invert = 0;
|
|
Packit |
0b5880 |
$include{"stddef.h"} = 1;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when m/^(?:[1-9]\d*|0x[0-9A-Fa-f]+|0b[01]+|0[0-7]+)$/x {
|
|
Packit |
0b5880 |
$msg = "'\"#expr\"' was ".&$Not."equal to $condition";
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p expr is ".&$not."equal to $condition.";
|
|
Packit |
0b5880 |
$condition = oct($condition) if $condition =~ /^0/;
|
|
Packit |
0b5880 |
$expr = "(expr) ".&$EQ." $condition";
|
|
Packit |
0b5880 |
$invert = 0;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when [qw(GT GE LT LE EQ NE Equal equal)] {
|
|
Packit |
0b5880 |
my $op;
|
|
Packit |
0b5880 |
given ( $condition ) {
|
|
Packit |
0b5880 |
$op = [ "less than" , "<" ] when "LT";
|
|
Packit |
0b5880 |
$op = [ "less than that or equal to", "<=" ] when "LE";
|
|
Packit |
0b5880 |
$op = [ "equal to" , "==" ] when ["EQ", "Equal", "equal", "NE"];
|
|
Packit |
0b5880 |
$op = [ "greater than or equal to" , ">=" ] when "GE";
|
|
Packit |
0b5880 |
$op = [ "greater than" , ">" ] when "GT";
|
|
Packit |
0b5880 |
};
|
|
Packit |
0b5880 |
$invert = !$invert when "NE";
|
|
Packit |
0b5880 |
@args = ( $type."1", $type."2" );
|
|
Packit |
0b5880 |
%argdocs = (
|
|
Packit |
0b5880 |
$type."1" => "The expression to test.",
|
|
Packit |
0b5880 |
$type."2" => "The test value."
|
|
Packit |
0b5880 |
);
|
|
Packit |
0b5880 |
$msg = "'\"#$args[0]\"' is ".&$Not.$op->[0]." '\"#$args[1]\"'";
|
|
Packit |
0b5880 |
$doc = "Asserts that \@p $args[0] is ".&$not.$op->[0]." \@p $args[1].";
|
|
Packit |
0b5880 |
$expr = "(${type}_compare( $args[0], $args[1] ) ".$op->[1]." 0)";
|
|
Packit |
0b5880 |
$need{$type."_compare"} = 1;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when [qw(Same same)] {
|
|
Packit |
0b5880 |
@args = qw( arg1 arg2 );
|
|
Packit |
0b5880 |
%argdocs = (
|
|
Packit |
0b5880 |
arg1 => "The expression to test.",
|
|
Packit |
0b5880 |
arg2 => "The expected value."
|
|
Packit |
0b5880 |
);
|
|
Packit |
0b5880 |
$msg = "'\"#arg1\"' and '\"#arg2\"' are ".&$Not."the same";
|
|
Packit |
0b5880 |
$msg = "Asserts that \@p arg1 and \@p arg2 are ".&$not."the same";
|
|
Packit |
0b5880 |
$expr = "(arg1) ".&$EQ." (arg2)";
|
|
Packit |
0b5880 |
$invert = 0;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
default {
|
|
Packit |
0b5880 |
print $fh "#error don't know how to make ${name}\n\n";
|
|
Packit |
0b5880 |
return;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
if ($invert) {
|
|
Packit |
0b5880 |
$expr = "!$expr";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
if ($doc) {
|
|
Packit |
0b5880 |
print $fh "/**\n";
|
|
Packit |
0b5880 |
print $fh wrap(" * "," * ","$doc\n");
|
|
Packit |
0b5880 |
my ($maxlength) = 3;
|
|
Packit |
0b5880 |
foreach (keys %argdocs) {
|
|
Packit |
0b5880 |
$maxlength = length $_ if length $_ > $maxlength;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
my ($indent) = " " x ($maxlength + 1 + 7);
|
|
Packit |
0b5880 |
foreach (keys %argdocs) {
|
|
Packit |
0b5880 |
print $fh wrap(" * ",
|
|
Packit |
0b5880 |
" * $indent",
|
|
Packit |
0b5880 |
"\@param $_ ".(" " x ($maxlength - length $_)).
|
|
Packit |
0b5880 |
"$argdocs{$_}\n");
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
print $fh wrap(" * ",
|
|
Packit |
0b5880 |
" * $indent",
|
|
Packit |
0b5880 |
"\@param ... ".(" " x ($maxlength - 3)).
|
|
Packit |
0b5880 |
"An optional message to indicate the assertion failed; ".
|
|
Packit |
0b5880 |
"Omit for a default message.\n");
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
print $fh " */\n";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
print $fh "#define ${name}(",(join ", ", @args, '...'),") \\\n";
|
|
Packit |
0b5880 |
print $fh " _ck_assert_msg( $expr, __FILE__, __LINE__, \\\n";
|
|
Packit |
0b5880 |
print $fh " \"$msg\", ## __VA_ARGS__, NULL)\n";
|
|
Packit |
0b5880 |
print $fh "\n";
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
$macros{$name} = 1;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
sub make_compare {
|
|
Packit |
0b5880 |
my ($name, $fh) = @_;
|
|
Packit |
0b5880 |
my ($type) = $name;
|
|
Packit |
0b5880 |
$type =~ s/_compare$//;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my ($expr);
|
|
Packit |
0b5880 |
my ($warning);
|
|
Packit |
0b5880 |
my ($ord);
|
|
Packit |
0b5880 |
my (@name) = ( "", "" );
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
given ($type) {
|
|
Packit |
0b5880 |
when "Number" {
|
|
Packit |
0b5880 |
$expr = "( ${type}1 - ${type}2 )";
|
|
Packit |
0b5880 |
$ord = "is";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
when "String" {
|
|
Packit |
0b5880 |
$expr = "strcmp( ${type}1, ${type}2 )";
|
|
Packit |
0b5880 |
$include{"string.h"} = 1;
|
|
Packit |
0b5880 |
$ord = "is";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
default {
|
|
Packit |
0b5880 |
$expr = "memcmp( ${type}1, ${type}2, sizeof( ${type} ) )";
|
|
Packit |
0b5880 |
$include{"string.h"} = 1;
|
|
Packit |
0b5880 |
$ord = "are";
|
|
Packit |
0b5880 |
@name = ( "'s bytes ", "'s" );
|
|
Packit |
0b5880 |
$warning = "This compares \@p ${type}1 and \@p ${type}2 "
|
|
Packit |
0b5880 |
. "byte-for-byte, this is probably not what you want "
|
|
Packit |
0b5880 |
. "for all but the simplest of structures.";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
print $fh "/**\n";
|
|
Packit |
0b5880 |
print $fh " * Compares \@p ${type}1 and \@p ${type}2.\n";
|
|
Packit |
0b5880 |
print $fh wrap(" * "," * ",$warning . "\n") if $warning;
|
|
Packit |
0b5880 |
print $fh " * \@param ${type}1 The first ${type}.\n";
|
|
Packit |
0b5880 |
print $fh " * \@param ${type}2 The second ${type}.\n";
|
|
Packit |
0b5880 |
my (%val_name) = (
|
|
Packit |
0b5880 |
">0" => "greater than",
|
|
Packit |
0b5880 |
"0 " => "equal to",
|
|
Packit |
0b5880 |
"<0" => "less than",
|
|
Packit |
0b5880 |
);
|
|
Packit |
0b5880 |
while (my ($val, $name) = each %val_name) {
|
|
Packit |
0b5880 |
print $fh " * \@retval $val If \@p ${type}1 $name[0]$ord $name \@p ${type}2 $name[1].\n";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
print $fh " */\n";
|
|
Packit |
0b5880 |
print $fh "#define ${type}_compare(${type}1, ${type}2) \\\n";
|
|
Packit |
0b5880 |
print $fh " $expr\n";
|
|
Packit |
0b5880 |
print $fh "\n";
|
|
Packit |
0b5880 |
$macros{$name} = 1;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my $INCLUDES = '';
|
|
Packit |
0b5880 |
open my $includes, ">", \$INCLUDES or die;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my $MACROS = '';
|
|
Packit |
0b5880 |
open my $macros, ">", \$MACROS or die;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
my $MACROS2 = '';
|
|
Packit |
0b5880 |
open my $macros2, ">", \$MACROS2 or die;
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
while (<>) {
|
|
Packit |
0b5880 |
chomp;
|
|
Packit |
0b5880 |
make_macro( $_, $macros2 ) if /^(?:Assert|Fail)/;
|
|
Packit |
0b5880 |
make_compare( $_, $macros ) if /_compare$/;
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
foreach my $need (keys %need) {
|
|
Packit |
0b5880 |
given ($need) {
|
|
Packit |
0b5880 |
when /^(?:String|Number)_compare$/ {
|
|
Packit |
0b5880 |
make_compare( $need, $macros );
|
|
Packit |
0b5880 |
delete $need{$need};
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
foreach my $macro (keys %macros) {
|
|
Packit |
0b5880 |
delete $need{$macro};
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
if (scalar %need) {
|
|
Packit |
0b5880 |
print $includes "/* needed functions/macros:\n";
|
|
Packit |
0b5880 |
foreach my $need (keys %need) {
|
|
Packit |
0b5880 |
if ($need =~ /^(.*)_compare$/) {
|
|
Packit |
0b5880 |
print $includes " * int $need(${1}1,${1}2);\n";
|
|
Packit |
0b5880 |
} else {
|
|
Packit |
0b5880 |
print $includes " * $need\n";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
print $includes " */\n\n";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
foreach my $include (keys %include) {
|
|
Packit |
0b5880 |
print $includes "#include <$include>\n";
|
|
Packit |
0b5880 |
}
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
print <<'END';
|
|
Packit |
0b5880 |
#ifndef _CHECK_MACROS_H
|
|
Packit |
0b5880 |
#define _CHECK_MACROS_H
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
END
|
|
Packit |
0b5880 |
print $INCLUDES;
|
|
Packit |
0b5880 |
print "\n";
|
|
Packit |
0b5880 |
print $MACROS;
|
|
Packit |
0b5880 |
print $MACROS2;
|
|
Packit |
0b5880 |
print <<'END';
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
#endif /* _CHECK_MACROS_H */
|
|
Packit |
0b5880 |
END
|
|
Packit |
0b5880 |
|
|
Packit |
0b5880 |
|