my $ignore_re = '^(' . join("|",
qw(
_
[a-z]
DBM
DBC
DB_AM_
DB_BT_
DB_RE_
DB_HS_
DB_FUNC_
DB_DBT_
DB_DBM
DB_TSL
MP
TXN
DB_TXN_GETPGNOS
)) . ')' ;
my %ignore_def = map {$_, 1} qw() ;
%ignore_enums = map {$_, 1} qw( ACTION db_status_t db_notices db_lockmode_t ) ;
my %ignore_exact_enum = map { $_ => 1}
qw(
DB_TXN_GETPGNOS
);
my $filler = ' ' x 26 ;
chdir "libraries" || die "Cannot chdir into './libraries': $!\n";
foreach my $name (sort tuple glob "[2-9]*")
{
next if $name =~ /(NC|private)$/;
my $inc = "$name/include/db.h" ;
next unless -f $inc ;
my $file = readFile($inc) ;
StripCommentsAndStrings($file) ;
my $result = scan($name, $file) ;
print "\n\t#########\n\t# $name\n\t#########\n\n$result"
if $result;
}
exit ;
sub scan
{
my $version = shift ;
my $file = shift ;
my %seen_define = () ;
my $result = "" ;
if (1) {
$file =~ s/\?\?=/ $file =~ s/\?\?\!/|/g; $file =~ s/\?\?'/^/g; # | ??'| ^|
$file =~ s/\?\?\(/[/g; $file =~ s/\?\?\)/]/g; $file =~ s/\?\?\-/~/g; $file =~ s/\?\?\//\\/g; # | ??/| \|
$file =~ s/\?\?</{/g; $file =~ s/\?\?>/}/g; }
while ( $file =~ /^\s* {
my $def = $1;
my $rest = $2;
my $ignore = 0 ;
$ignore = 1 if $ignore_def{$def} || $def =~ /$ignore_re/o ;
$rest =~ s/\s*$//;
next if $before{$def} ++ ;
if ($ignore)
{ $seen_define{$def} = 'IGNORE' }
elsif ($rest =~ /"/)
{ $seen_define{$def} = 'STRING' }
else
{ $seen_define{$def} = 'DEFINE' }
}
foreach $define (sort keys %seen_define)
{
my $out = $filler ;
substr($out,0, length $define) = $define;
$result .= "\t$out => $seen_define{$define},\n" ;
}
while ($file =~ /\btypedef\s+enum\s*{(.*?)}\s*(\w+)/gs )
{
my $enum = $1 ;
my $name = $2 ;
my $ignore = 0 ;
$ignore = 1 if $ignore_enums{$name} ;
#$enum =~ s/\s*=\s*\S+\s*(,?)\s*\n/$1/g;
$enum =~ s/^\s*//;
$enum =~ s/\s*$//;
my @tokens = map { s/\s*=.*// ; $_} split /\s*,\s*/, $enum ;
my @new = grep { ! $Enums{$_}++ } @tokens ;
if (@new)
{
my $value ;
if ($ignore)
{ $value = "IGNORE, else
{ $value = "'$version'," }
$result .= "\n\t# enum $name\n";
my $out = $filler ;
foreach $name (@new)
{
next if $ignore_exact_enum{$name} ;
$out = $filler ;
substr($out,0, length $name) = $name;
$result .= "\t$out => $value\n" ;
}
}
}
return $result ;
}
sub StripCommentsAndStrings
{
$_[0] =~
s{
/\* [^*]*\*+ (
[^/*][^*]*\*+
)* /
| // ## Start of C++ comment //
[^\n]*
|
(
" ## Start of " ... " string
(
\\. ## Escaped char
| ## OR
[^"\\] )*
" ## End of " ... " string
| ## OR
' ## Start of ' ... ' string
(
\\. ## Escaped char
| ## OR
[^'\\] ## Non '\
)*
' ## End of ' ... ' string
| ## OR
. ## Anything other char
[^/"'\\]* ## Chars which doesn't start a comment, string or escape
)
}{$2}gxs;
$_[0] =~ s/\A\s+//m ;
$_[0] =~ s/\s+\Z//m ;
}
sub readFile
{
my $filename = shift ;
open F, "<$filename" || die "Cannot open $filename: $!\n" ;
local $/ ;
my $x = <F> ;
close F ;
return $x ;
}
sub tuple
{
my (@a) = split(/\./, $a) ;
my (@b) = split(/\./, $b) ;
if (@a != @b) {
my $diff = @a - @b ;
push @b, (0 x $diff) if $diff > 0 ;
push @a, (0 x -$diff) if $diff < 0 ;
}
foreach $A (@a) {
$B = shift @b ;
$A == $B or return $A <=> $B ;
}
return 0;
}
__END__