mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-05-15 22:06:48 +02:00
174 lines
5.0 KiB
Perl
174 lines
5.0 KiB
Perl
|
####################################################################################################################################
|
||
|
# Generate Truth Tables in Markdown Format
|
||
|
####################################################################################################################################
|
||
|
package pgBackRestBuild::CodeGen::Truth;
|
||
|
|
||
|
use strict;
|
||
|
use warnings FATAL => qw(all);
|
||
|
use Carp qw(confess);
|
||
|
use English '-no_match_vars';
|
||
|
|
||
|
use Exporter qw(import);
|
||
|
our @EXPORT = qw();
|
||
|
use Storable qw(dclone);
|
||
|
|
||
|
use pgBackRest::Common::Log;
|
||
|
|
||
|
use pgBackRestBuild::CodeGen::Common;
|
||
|
|
||
|
####################################################################################################################################
|
||
|
# cgenTruthTable - Main builder
|
||
|
####################################################################################################################################
|
||
|
sub cgenTruthTable
|
||
|
{
|
||
|
my $strFunction = shift;
|
||
|
my $rstryParam = shift;
|
||
|
my $strReturnType = shift;
|
||
|
my $strReturnDefault = shift;
|
||
|
my $rxyMatrix = shift;
|
||
|
my $strRedundantParam = shift;
|
||
|
my $rhParamValueMap = shift;
|
||
|
my $rhReturnValueMap = shift;
|
||
|
|
||
|
# Write table header
|
||
|
my $strTruthTable = '| Function';
|
||
|
|
||
|
for (my $iParamIdx = 0; $iParamIdx < @{$rstryParam}; $iParamIdx++)
|
||
|
{
|
||
|
$strTruthTable .= ' | ' . $rstryParam->[$iParamIdx];
|
||
|
}
|
||
|
|
||
|
$strTruthTable .=
|
||
|
" | Result |\n" .
|
||
|
'| --------';
|
||
|
|
||
|
for (my $iParamIdx = 0; $iParamIdx < @{$rstryParam}; $iParamIdx++)
|
||
|
{
|
||
|
$strTruthTable .= ' | ' . ('-' x length($rstryParam->[$iParamIdx]));
|
||
|
}
|
||
|
|
||
|
$strTruthTable .=
|
||
|
" | ------ |\n";
|
||
|
|
||
|
# Format matrix data so that can be ordered (even by integer)
|
||
|
my @stryOrderedMatrix;
|
||
|
|
||
|
foreach my $rxyEntry (@{$rxyMatrix})
|
||
|
{
|
||
|
my $strEntry;
|
||
|
|
||
|
for (my $iEntryIdx = 0; $iEntryIdx < @{$rxyEntry}; $iEntryIdx++)
|
||
|
{
|
||
|
my $strValue = defined($rxyEntry->[$iEntryIdx]) ? $rxyEntry->[$iEntryIdx] : CGEN_DATAVAL_NULL;
|
||
|
|
||
|
if ($iEntryIdx != @{$rxyEntry} - 1)
|
||
|
{
|
||
|
$strEntry .= (defined($strEntry) ? '~' : '') . sprintf('%016d', $strValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$strEntry .= '~' . $strValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
push(@stryOrderedMatrix, $strEntry);
|
||
|
}
|
||
|
|
||
|
# Optimize away one parameter that is frequently redundant
|
||
|
my $rhMatrixFilter;
|
||
|
my @stryFilteredMatrix;
|
||
|
|
||
|
if ($rstryParam->[0] eq $strRedundantParam)
|
||
|
{
|
||
|
foreach my $strEntry (sort(@stryOrderedMatrix))
|
||
|
{
|
||
|
my @xyEntry = split('\~', $strEntry);
|
||
|
|
||
|
shift(@xyEntry);
|
||
|
my $strValue = pop(@xyEntry);
|
||
|
my $strKey = join('~', @xyEntry);
|
||
|
|
||
|
push(@{$rhMatrixFilter->{$strKey}{entry}}, $strEntry);
|
||
|
$rhMatrixFilter->{$strKey}{value}{$strValue} = true;
|
||
|
}
|
||
|
|
||
|
foreach my $strKey (sort(keys(%{$rhMatrixFilter})))
|
||
|
{
|
||
|
if (keys(%{$rhMatrixFilter->{$strKey}{value}}) == 1)
|
||
|
{
|
||
|
my $strEntry =
|
||
|
|
||
|
push(
|
||
|
@stryFilteredMatrix,
|
||
|
CGEN_DATAVAL_NULL . "~${strKey}~" . (keys(%{$rhMatrixFilter->{$strKey}{value}}))[0]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
push(@stryFilteredMatrix, @{$rhMatrixFilter->{$strKey}{entry}});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
@stryFilteredMatrix = @stryOrderedMatrix;
|
||
|
}
|
||
|
|
||
|
# Output function entry
|
||
|
foreach my $strEntry (sort(@stryFilteredMatrix))
|
||
|
{
|
||
|
my @xyEntry = split('\~', $strEntry);
|
||
|
my $strRow = '| ' . $strFunction;
|
||
|
my $strValue;
|
||
|
|
||
|
for (my $iEntryIdx = 0; $iEntryIdx < @xyEntry; $iEntryIdx++)
|
||
|
{
|
||
|
$strValue = $xyEntry[$iEntryIdx];
|
||
|
$strRow .= ' | ';
|
||
|
|
||
|
if ($iEntryIdx != @xyEntry - 1)
|
||
|
{
|
||
|
my $strParam = $rstryParam->[$iEntryIdx];
|
||
|
|
||
|
if ($strValue eq CGEN_DATAVAL_NULL)
|
||
|
{
|
||
|
$strRow .= '_\<ANY\>_';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$strRow .=
|
||
|
'`' .
|
||
|
(defined($rhParamValueMap->{$strParam}) ?
|
||
|
$rhParamValueMap->{$strParam}{int($strValue)} : int($strValue)) .
|
||
|
'`';
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$strRow .=
|
||
|
'`' .
|
||
|
cgenTypeFormat(
|
||
|
$strReturnType,
|
||
|
defined($rhReturnValueMap) &&
|
||
|
defined($rhReturnValueMap->{$strValue}) ?
|
||
|
$rhReturnValueMap->{$strValue} : $strValue) .
|
||
|
'`';
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# If default default value is returned then skip this entry
|
||
|
if (defined($strReturnDefault) && $strReturnDefault eq $strValue)
|
||
|
{
|
||
|
next;
|
||
|
}
|
||
|
|
||
|
$strTruthTable .= "${strRow} |\n";
|
||
|
}
|
||
|
|
||
|
return $strTruthTable;
|
||
|
}
|
||
|
|
||
|
push @EXPORT, qw(cgenTruthTable);
|
||
|
|
||
|
1;
|