1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-18 04:58:51 +02:00

Add option groups.

Group related options together so operations (e.g. valid, test, index total) can be performed on all options in the group.

Previously, options at the top of the hierarchy of the related options were used to do these tests. This was prone to error as option relationships changed and it was not always clear which option (or options) should be used.
This commit is contained in:
David Steele 2020-10-08 10:52:19 -04:00 committed by GitHub
parent dc8a9dab1b
commit e0f09687e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 657 additions and 105 deletions

View File

@ -29,7 +29,9 @@ use constant BLDLCL_FILE_CONFIG => 'config';
use constant BLDLCL_CONSTANT_COMMAND => '01-constantCommand';
use constant BLDLCL_CONSTANT_COMMAND_TOTAL => 'CFG_COMMAND_TOTAL';
use constant BLDLCL_CONSTANT_OPTION => '02-constantOption';
use constant BLDLCL_CONSTANT_OPTION_GROUP => '02-constantOptionGroup';
use constant BLDLCL_CONSTANT_OPTION_GROUP_TOTAL => 'CFG_OPTION_GROUP_TOTAL';
use constant BLDLCL_CONSTANT_OPTION => '03-constantOption';
use constant BLDLCL_CONSTANT_OPTION_TOTAL => 'CFG_OPTION_TOTAL';
use constant BLDLCL_DATA_COMMAND_CONSTANT => '01-commandConstant';
@ -38,7 +40,8 @@ use constant BLDLCL_DATA_OPTION_CONSTANT => '03-optio
use constant BLDLCL_DATA_OPTION => '04-option';
use constant BLDLCL_ENUM_COMMAND => '01-enumCommand';
use constant BLDLCL_ENUM_OPTION => '02-enumOption';
use constant BLDLCL_ENUM_OPTION_GROUP => '02-enumOptionGroup';
use constant BLDLCL_ENUM_OPTION => '03-enumOption';
####################################################################################################################################
# Definitions for constants and data to build
@ -58,6 +61,10 @@ my $rhBuild =
{
&BLD_SUMMARY => 'Command',
},
&BLDLCL_CONSTANT_OPTION_GROUP =>
{
&BLD_SUMMARY => 'Option group',
},
&BLDLCL_CONSTANT_OPTION =>
{
&BLD_SUMMARY => 'Option',
@ -73,6 +80,13 @@ my $rhBuild =
&BLD_LIST => [],
},
&BLDLCL_ENUM_OPTION_GROUP =>
{
&BLD_SUMMARY => 'Option group',
&BLD_NAME => 'ConfigOptionGroup',
&BLD_LIST => [],
},
&BLDLCL_ENUM_OPTION =>
{
&BLD_SUMMARY => 'Option',
@ -124,6 +138,13 @@ sub buildConfigOptionEnum
push @EXPORT, qw(buildConfigOptionEnum);
sub buildConfigOptionGroupEnum
{
return bldEnum('cfgOptGrp', shift)
}
push @EXPORT, qw(buildConfigOptionGroupEnum);
####################################################################################################################################
# Build constants and data
####################################################################################################################################
@ -197,6 +218,24 @@ sub buildConfig
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_CONFIG}{&BLD_CONSTANT_GROUP}{&BLDLCL_CONSTANT_COMMAND}{&BLD_CONSTANT}
{&BLDLCL_CONSTANT_COMMAND_TOTAL}{&BLD_CONSTANT_VALUE} = $iCommandTotal;
# Build option group constants and data
#-------------------------------------------------------------------------------------------------------------------------------
my $rhOptionGroupDefine = cfgDefineOptionGroup();
$rhEnum = $rhBuild->{&BLD_FILE}{&BLDLCL_FILE_CONFIG}{&BLD_ENUM}{&BLDLCL_ENUM_OPTION_GROUP};
my $iGroupTotal = 0;
foreach my $strGroup (sort(keys(%{$rhOptionGroupDefine})))
{
my $strGroupEnum = buildConfigOptionGroupEnum($strGroup);
push(@{$rhEnum->{&BLD_LIST}}, $strGroupEnum);
$iGroupTotal++;
}
# Set option total constant
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_CONFIG}{&BLD_CONSTANT_GROUP}{&BLDLCL_CONSTANT_OPTION_GROUP}{&BLD_CONSTANT}
{&BLDLCL_CONSTANT_OPTION_GROUP_TOTAL}{&BLD_CONSTANT_VALUE} = $iGroupTotal;
# Build option constants and data
#-------------------------------------------------------------------------------------------------------------------------------
my $strOptionConst;
@ -238,7 +277,22 @@ sub buildConfig
" (\n" .
" CONFIG_OPTION_NAME(${strOptionConst})\n" .
" CONFIG_OPTION_INDEX(" . ($iOptionIndex - 1) . ")\n" .
" CONFIG_OPTION_DEFINE_ID(" . buildConfigDefineOptionEnum($strOption) . ")\n" .
" CONFIG_OPTION_DEFINE_ID(" . buildConfigDefineOptionEnum($strOption) . ")\n";
if ($rhConfigDefine->{$strOption}{&CFGDEF_GROUP})
{
$strBuildSource .=
" CONFIG_OPTION_GROUP(true)\n" .
" CONFIG_OPTION_GROUP_ID(" . buildConfigOptionGroupEnum($rhConfigDefine->{$strOption}{&CFGDEF_GROUP}) .
")\n";
}
else
{
$strBuildSource .=
" CONFIG_OPTION_GROUP(false)\n";
}
$strBuildSource .=
" )\n";

View File

@ -431,6 +431,11 @@ use constant CFGDEF_DEPEND_OPTION => 'depend-o
push @EXPORT, qw(CFGDEF_DEPEND_OPTION);
use constant CFGDEF_DEPEND_LIST => 'depend-list';
push @EXPORT, qw(CFGDEF_DEPEND_LIST);
# Group options together to share common configuration
use constant CFGDEF_GROUP => 'group';
push @EXPORT, qw(CFGDEF_GROUP);
use constant CFGDEF_INDEX => 'index';
push @EXPORT, qw(CFGDEF_INDEX);
use constant CFGDEF_INDEX_TOTAL => 'indexTotal';
@ -615,6 +620,30 @@ my $rhCommandDefine =
},
};
####################################################################################################################################
# Option group definition data
#
# Options groups allow related options to be grouped together so, e.g. test and valid, operations can be run across all options in
# the group.
####################################################################################################################################
use constant CFGOPTGRP_PG => CFGDEF_PREFIX_PG;
use constant CFGOPTGRP_REPO => CFGDEF_PREFIX_REPO;
my $rhOptionGroupDefine =
{
&CFGOPTGRP_PG =>
{
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
},
&CFGOPTGRP_REPO =>
{
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
},
};
####################################################################################################################################
# Option definition data
####################################################################################################################################
@ -1458,10 +1487,9 @@ my %hConfigDefine =
#-------------------------------------------------------------------------------------------------------------------------------
&CFGOPT_REPO_CIPHER_PASS =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_SECURE => true,
&CFGDEF_REQUIRED => true,
&CFGDEF_DEPEND =>
@ -1478,10 +1506,9 @@ my %hConfigDefine =
&CFGOPT_REPO_CIPHER_TYPE =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => CFGOPTVAL_REPO_CIPHER_TYPE_NONE,
&CFGDEF_ALLOW_LIST =>
[
@ -1497,10 +1524,9 @@ my %hConfigDefine =
&CFGOPT_REPO_HARDLINK =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_NAME_ALT =>
{
'hardlink' => {&CFGDEF_INDEX => 1, &CFGDEF_RESET => false},
@ -1514,11 +1540,10 @@ my %hConfigDefine =
&CFGOPT_REPO_LOCAL =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_INTERNAL => true,
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => false,
&CFGDEF_COMMAND =>
{
@ -1560,10 +1585,9 @@ my %hConfigDefine =
&CFGOPT_REPO_HOST =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_NAME_ALT =>
{
@ -1579,10 +1603,9 @@ my %hConfigDefine =
&CFGOPT_REPO_HOST_CMD =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_NAME_ALT =>
{
@ -1612,10 +1635,9 @@ my %hConfigDefine =
&CFGOPT_REPO_HOST_CONFIG =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => CFGDEF_DEFAULT_CONFIG,
&CFGDEF_NAME_ALT =>
{
@ -1644,10 +1666,9 @@ my %hConfigDefine =
&CFGOPT_REPO_HOST_PORT =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_ALLOW_RANGE => [CFGDEF_DEFAULT_PROTOCOL_PORT_MIN, CFGDEF_DEFAULT_PROTOCOL_PORT_MAX],
&CFGDEF_REQUIRED => false,
&CFGDEF_NAME_ALT =>
@ -1663,10 +1684,9 @@ my %hConfigDefine =
&CFGOPT_REPO_HOST_USER =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => PROJECT_EXE,
&CFGDEF_NAME_ALT =>
{
@ -1682,10 +1702,9 @@ my %hConfigDefine =
&CFGOPT_REPO_PATH =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_PATH,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => '/var/lib/' . PROJECT_EXE,
&CFGDEF_NAME_ALT =>
{
@ -1696,10 +1715,9 @@ my %hConfigDefine =
&CFGOPT_REPO_RETENTION_ARCHIVE =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_ALLOW_RANGE => [CFGDEF_DEFAULT_RETENTION_MIN, CFGDEF_DEFAULT_RETENTION_MAX],
&CFGDEF_NAME_ALT =>
@ -1715,10 +1733,9 @@ my %hConfigDefine =
&CFGOPT_REPO_RETENTION_ARCHIVE_TYPE =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => CFGOPTVAL_BACKUP_TYPE_FULL,
&CFGDEF_COMMAND =>
{
@ -1739,10 +1756,9 @@ my %hConfigDefine =
&CFGOPT_REPO_RETENTION_DIFF =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_ALLOW_RANGE => [CFGDEF_DEFAULT_RETENTION_MIN, CFGDEF_DEFAULT_RETENTION_MAX],
&CFGDEF_NAME_ALT =>
@ -1758,10 +1774,9 @@ my %hConfigDefine =
&CFGOPT_REPO_RETENTION_FULL =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_ALLOW_RANGE => [CFGDEF_DEFAULT_RETENTION_MIN, CFGDEF_DEFAULT_RETENTION_MAX],
&CFGDEF_NAME_ALT =>
@ -1773,10 +1788,9 @@ my %hConfigDefine =
&CFGOPT_REPO_RETENTION_FULL_TYPE =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => 'count',
&CFGDEF_ALLOW_LIST =>
[
@ -1792,10 +1806,9 @@ my %hConfigDefine =
&CFGOPT_REPO_AZURE_ACCOUNT =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_SECURE => true,
&CFGDEF_REQUIRED => true,
&CFGDEF_DEPEND =>
@ -1819,9 +1832,8 @@ my %hConfigDefine =
&CFGOPT_REPO_AZURE_CONTAINER =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_DEPEND => CFGOPT_REPO_AZURE_ACCOUNT,
&CFGDEF_COMMAND => CFGOPT_REPO_TYPE,
@ -1835,10 +1847,9 @@ my %hConfigDefine =
&CFGOPT_REPO_AZURE_HOST =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_DEPEND => CFGOPT_REPO_AZURE_ACCOUNT,
&CFGDEF_COMMAND => CFGOPT_REPO_TYPE,
@ -1862,10 +1873,9 @@ my %hConfigDefine =
&CFGOPT_REPO_AZURE_PORT =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => 443,
&CFGDEF_ALLOW_RANGE => [1, 65535],
&CFGDEF_DEPEND => CFGOPT_REPO_AZURE_ACCOUNT,
@ -1874,10 +1884,9 @@ my %hConfigDefine =
&CFGOPT_REPO_AZURE_VERIFY_TLS =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => true,
&CFGDEF_DEPEND => CFGOPT_REPO_AZURE_ACCOUNT,
&CFGDEF_COMMAND => CFGOPT_REPO_TYPE,
@ -1885,9 +1894,8 @@ my %hConfigDefine =
&CFGOPT_REPO_S3_BUCKET =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_DEPEND =>
{
@ -1933,10 +1941,9 @@ my %hConfigDefine =
&CFGOPT_REPO_S3_KEY =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_SECURE => true,
&CFGDEF_REQUIRED => true,
&CFGDEF_DEPEND =>
@ -1991,10 +1998,9 @@ my %hConfigDefine =
&CFGOPT_REPO_S3_HOST =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_REQUIRED => false,
&CFGDEF_DEPEND => CFGOPT_REPO_S3_BUCKET,
&CFGDEF_NAME_ALT =>
@ -2006,10 +2012,9 @@ my %hConfigDefine =
&CFGOPT_REPO_S3_PORT =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => 443,
&CFGDEF_ALLOW_RANGE => [1, 65535],
&CFGDEF_DEPEND => CFGOPT_REPO_S3_BUCKET,
@ -2045,10 +2050,9 @@ my %hConfigDefine =
&CFGOPT_REPO_S3_URI_STYLE =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => CFGOPTVAL_REPO_S3_URI_STYLE_HOST,
&CFGDEF_ALLOW_LIST =>
[
@ -2061,10 +2065,9 @@ my %hConfigDefine =
&CFGOPT_REPO_S3_VERIFY_TLS =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => true,
&CFGDEF_NAME_ALT =>
{
@ -2077,10 +2080,9 @@ my %hConfigDefine =
&CFGOPT_REPO_TYPE =>
{
&CFGDEF_GROUP => CFGOPTGRP_REPO,
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_REPO,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_REPO,
&CFGDEF_DEFAULT => CFGOPTVAL_REPO_TYPE_POSIX,
&CFGDEF_ALLOW_LIST =>
[
@ -2566,11 +2568,10 @@ my %hConfigDefine =
#-------------------------------------------------------------------------------------------------------------------------------
&CFGOPT_PG_LOCAL =>
{
&CFGDEF_GROUP => CFGOPTGRP_PG,
&CFGDEF_SECTION => CFGDEF_SECTION_STANZA,
&CFGDEF_INTERNAL => true,
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
&CFGDEF_DEFAULT => false,
&CFGDEF_COMMAND =>
{
@ -2599,10 +2600,9 @@ my %hConfigDefine =
&CFGOPT_PG_HOST =>
{
&CFGDEF_GROUP => CFGOPTGRP_PG,
&CFGDEF_SECTION => CFGDEF_SECTION_STANZA,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
&CFGDEF_REQUIRED => false,
&CFGDEF_NAME_ALT =>
{
@ -2619,10 +2619,9 @@ my %hConfigDefine =
&CFGOPT_PG_HOST_CMD =>
{
&CFGDEF_GROUP => CFGOPTGRP_PG,
&CFGDEF_SECTION => CFGDEF_SECTION_STANZA,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
&CFGDEF_REQUIRED => false,
&CFGDEF_NAME_ALT =>
{
@ -2699,10 +2698,9 @@ my %hConfigDefine =
&CFGOPT_PG_PATH =>
{
&CFGDEF_GROUP => CFGOPTGRP_PG,
&CFGDEF_SECTION => CFGDEF_SECTION_STANZA,
&CFGDEF_TYPE => CFGDEF_TYPE_PATH,
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
&CFGDEF_REQUIRED => true,
&CFGDEF_NAME_ALT =>
{
@ -2727,10 +2725,9 @@ my %hConfigDefine =
&CFGOPT_PG_PORT =>
{
&CFGDEF_GROUP => CFGOPTGRP_PG,
&CFGDEF_SECTION => CFGDEF_SECTION_STANZA,
&CFGDEF_TYPE => CFGDEF_TYPE_INTEGER,
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
&CFGDEF_DEFAULT => 5432,
&CFGDEF_ALLOW_RANGE => [CFGDEF_DEFAULT_PROTOCOL_PORT_MIN, CFGDEF_DEFAULT_PROTOCOL_PORT_MAX],
&CFGDEF_NAME_ALT =>
@ -2767,10 +2764,9 @@ my %hConfigDefine =
&CFGOPT_PG_USER =>
{
&CFGDEF_GROUP => CFGOPTGRP_PG,
&CFGDEF_SECTION => CFGDEF_SECTION_STANZA,
&CFGDEF_TYPE => CFGDEF_TYPE_STRING,
&CFGDEF_PREFIX => CFGDEF_PREFIX_PG,
&CFGDEF_INDEX_TOTAL => CFGDEF_INDEX_PG,
&CFGDEF_REQUIRED => false,
&CFGDEF_COMMAND =>
{
@ -2849,16 +2845,38 @@ foreach my $strCommand (sort(keys(%{$rhCommandDefine})))
}
}
####################################################################################################################################
# Process option group defaults
####################################################################################################################################
foreach my $strGroup (sort(keys(%{$rhOptionGroupDefine})))
{
# Error if prefix and index total are not both defined
if ((defined($rhOptionGroupDefine->{$strGroup}{&CFGDEF_PREFIX}) &&
!defined($rhOptionGroupDefine->{$strGroup}{&CFGDEF_INDEX_TOTAL})) ||
(!defined($rhOptionGroupDefine->{$strGroup}{&CFGDEF_PREFIX}) &&
defined($rhOptionGroupDefine->{$strGroup}{&CFGDEF_INDEX_TOTAL})))
{
confess &log(
ASSERT, "CFGDEF_PREFIX and CFGDEF_INDEX_TOTAL must both be defined (or neither) for option group '${strGroup}'");
}
}
####################################################################################################################################
# Process option define defaults
####################################################################################################################################
foreach my $strKey (sort(keys(%hConfigDefine)))
{
# Error if prefix and index total are not both defined
if ((defined($hConfigDefine{$strKey}{&CFGDEF_PREFIX}) && !defined($hConfigDefine{$strKey}{&CFGDEF_INDEX_TOTAL})) ||
(!defined($hConfigDefine{$strKey}{&CFGDEF_PREFIX}) && defined($hConfigDefine{$strKey}{&CFGDEF_INDEX_TOTAL})))
my $rhOption = $hConfigDefine{$strKey};
# Error on invalid configuration
if (defined($rhOption->{&CFGDEF_INDEX_TOTAL}))
{
confess &log(ASSERT, "CFGDEF_PREFIX and CFGDEF_INDEX_TOTAL must both be defined (or neither) for option '${strKey}'");
confess &log(ASSERT, "CFGDEF_INDEX_TOTAL cannot be defined for option '${strKey}'");
}
if (defined($rhOption->{&CFGDEF_PREFIX}))
{
confess &log(ASSERT, "CFGDEF_PREFIX cannot be defined for option '${strKey}'");
}
# If the define is a scalar then copy the entire define from the referenced option
@ -2881,6 +2899,18 @@ foreach my $strKey (sort(keys(%hConfigDefine)))
{
$hConfigDefine{$strKey}{$strOptionDef} = $hConfigDefineOverride->{$strOptionDef};
}
# Update option variable with new hash reference
$rhOption = $hConfigDefine{$strKey}
}
# If the option group is defined then copy configuration from the group to the option
if (defined($rhOption->{&CFGDEF_GROUP}))
{
my $rhGroup = $rhOptionGroupDefine->{$hConfigDefine{$strKey}{&CFGDEF_GROUP}};
$rhOption->{&CFGDEF_INDEX_TOTAL} = $rhGroup->{&CFGDEF_INDEX_TOTAL};
$rhOption->{&CFGDEF_PREFIX} = $rhGroup->{&CFGDEF_PREFIX};
}
# If the command section is a scalar then copy the section from the referenced option
@ -3001,6 +3031,16 @@ sub cfgDefineCommand
push @EXPORT, qw(cfgDefineCommand);
####################################################################################################################################
# Get option group definition
####################################################################################################################################
sub cfgDefineOptionGroup
{
return dclone($rhOptionGroupDefine);
}
push @EXPORT, qw(cfgDefineOptionGroup);
####################################################################################################################################
# Get list of all commands
####################################################################################################################################

View File

@ -27,6 +27,16 @@
<p>Add <br-option>repo-azure-endpoint</br-option> option.</p>
</release-item>
</release-feature-list>
<release-development-list>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="cynthia.shang"/>
</release-item-contributor-list>
<p>Add option groups.</p>
</release-item>
</release-development-list>
</release-core-list>
</release>

View File

@ -30,9 +30,9 @@ checkManifest(void)
MEM_CONTEXT_TEMP_BEGIN()
{
// Loop through all defined databases and attempt to build a manifest
for (unsigned int pgIdx = 0; pgIdx < cfgOptionIndexTotal(cfgOptPgPath); pgIdx++)
for (unsigned int pgIdx = 0; pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); pgIdx++)
{
if (cfgOptionTest(cfgOptPgHost + pgIdx) || cfgOptionTest(cfgOptPgPath + pgIdx))
if (cfgOptionGroupIdxTest(cfgOptGrpPg, pgIdx))
{
result++;
// ??? Placeholder for manifest build

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,11 @@ Command constants
#define CFG_COMMAND_TOTAL 21
/***********************************************************************************************************************************
Option group constants
***********************************************************************************************************************************/
#define CFG_OPTION_GROUP_TOTAL 2
/***********************************************************************************************************************************
Option constants
***********************************************************************************************************************************/
@ -500,6 +505,15 @@ typedef enum
cfgCmdNone,
} ConfigCommand;
/***********************************************************************************************************************************
Option group enum
***********************************************************************************************************************************/
typedef enum
{
cfgOptGrpPg,
cfgOptGrpRepo,
} ConfigOptionGroup;
/***********************************************************************************************************************************
Option enum
***********************************************************************************************************************************/

View File

@ -60,6 +60,8 @@ typedef struct ConfigOptionData
unsigned int index:5;
unsigned int defineId:7;
bool group:1; // Is the option in a group?
unsigned int groupId:1; // Group id if option is in a group
} ConfigOptionData;
#define CONFIG_OPTION_LIST(...) \
@ -74,6 +76,10 @@ typedef struct ConfigOptionData
.name = nameParam,
#define CONFIG_OPTION_DEFINE_ID(defineIdParam) \
.defineId = defineIdParam,
#define CONFIG_OPTION_GROUP(groupParam) \
.group = groupParam,
#define CONFIG_OPTION_GROUP_ID(groupIdParam) \
.groupId = groupIdParam,
/***********************************************************************************************************************************
Include the automatically generated configuration data
@ -95,6 +101,14 @@ static struct ConfigStatic
bool help; // Was help requested for the command?
StringList *paramList; // Parameters passed to the command (if any)
// Group options that are related together to allow valid and test checks across all options in the group
struct
{
bool valid; // Is option group valid for the current command?
unsigned int indexMax; // Max index in option group
unsigned int value; // Does option group index have any values?
} optionGroup[CFG_OPTION_GROUP_TOTAL];
// Map options names and indexes to option definitions
struct
{
@ -470,6 +484,47 @@ cfgParameterAllowed(void)
FUNCTION_TEST_RETURN(configCommandData[cfgCommand()].parameterAllowed);
}
/**********************************************************************************************************************************/
bool
cfgOptionGroupIdxTest(ConfigOptionGroup groupId, unsigned int index)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, groupId);
FUNCTION_TEST_PARAM(UINT, index);
FUNCTION_TEST_END();
ASSERT(groupId < CFG_OPTION_GROUP_TOTAL);
FUNCTION_TEST_RETURN(
cfgOptionGroupValid(groupId) && (index == 0 || configStatic.optionGroup[groupId].value & ((unsigned int)1 << index)));
}
/**********************************************************************************************************************************/
unsigned int
cfgOptionGroupIdxTotal(ConfigOptionGroup groupId)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, groupId);
FUNCTION_TEST_END();
ASSERT(groupId < CFG_OPTION_GROUP_TOTAL);
FUNCTION_TEST_RETURN(cfgOptionGroupValid(groupId) ? configStatic.optionGroup[groupId].indexMax + 1 : 0);
}
/**********************************************************************************************************************************/
bool
cfgOptionGroupValid(ConfigOptionGroup groupId)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, groupId);
FUNCTION_TEST_END();
ASSERT(groupId < CFG_OPTION_GROUP_TOTAL);
FUNCTION_TEST_RETURN(configStatic.optionGroup[groupId].valid);
}
/**********************************************************************************************************************************/
ConfigDefineOption
cfgOptionDefIdFromId(ConfigOption optionId)
@ -689,19 +744,6 @@ cfgOptionId(const char *optionName)
FUNCTION_TEST_RETURN(result);
}
/**********************************************************************************************************************************/
unsigned int
cfgOptionIndexTotal(ConfigOption optionId)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, optionId);
FUNCTION_TEST_END();
ASSERT(optionId < CFG_OPTION_TOTAL);
FUNCTION_TEST_RETURN(cfgDefOptionIndexTotal(configOptionData[optionId].defineId));
}
/**********************************************************************************************************************************/
ConfigOption
cfgOptionIdFromDefId(ConfigDefineOption optionDefId, unsigned int index)
@ -983,6 +1025,18 @@ cfgOptionSet(ConfigOption optionId, ConfigSource source, const Variant *value)
// Only set value if it is not null
if (value != NULL)
{
// If this option is in a group then set the value in the group for the option's index. This indicates that there is at
// least one option set in the group for that index.
if (configOptionData[optionId].group && source != cfgSourceDefault)
{
unsigned int groupId = configOptionData[optionId].groupId;
configStatic.optionGroup[groupId].value |= (unsigned int)1 << configOptionData[optionId].index;
if (configOptionData[optionId].index > configStatic.optionGroup[groupId].indexMax)
configStatic.optionGroup[groupId].indexMax = configOptionData[optionId].index;
}
switch (cfgDefOptionType(cfgOptionDefIdFromId(optionId)))
{
case cfgDefOptTypeBoolean:
@ -1111,5 +1165,9 @@ cfgOptionValidSet(ConfigOption optionId, bool valid)
configStatic.option[optionId].valid = valid;
// If this option is in a group then the group is also valid
if (configOptionData[optionId].group)
configStatic.optionGroup[configOptionData[optionId].groupId].valid = true;
FUNCTION_TEST_RETURN_VOID();
}

View File

@ -94,6 +94,19 @@ bool cfgParameterAllowed(void);
// Command parameters, if any
const StringList *cfgCommandParam(void);
/***********************************************************************************************************************************
Option Group Functions
***********************************************************************************************************************************/
// Are any options in the group with the specified index valid for the command and set by the user (i.e. not default)?
bool cfgOptionGroupIdxTest(ConfigOptionGroup groupId, unsigned int index);
// Total indexed groups, 0 if the group is not valid. Note that there may be gaps so each group index will need to be tested with
// cfgOptionGroupIdxTest() to make sure it contains data.
unsigned int cfgOptionGroupIdxTotal(ConfigOptionGroup groupId);
// Are any options in the group valid for the command?
bool cfgOptionGroupValid(ConfigOptionGroup groupId);
/***********************************************************************************************************************************
Option Functions
@ -115,9 +128,6 @@ uint64_t cfgOptionUInt64(ConfigOption optionId);
// Get index for option
unsigned int cfgOptionIndex(ConfigOption optionId);
// Get total indexed values for option
unsigned int cfgOptionIndexTotal(ConfigOption optionDefId);
// Option name by id
const char *cfgOptionName(ConfigOption optionId);

View File

@ -71,7 +71,7 @@ cfgLoadUpdateOption(void)
// Set default for pg-host-cmd
if (cfgOptionValid(cfgOptPgHostCmd))
{
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIndexTotal(cfgOptPgHost); optionIdx++)
for (unsigned int optionIdx = 0; optionIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); optionIdx++)
{
if (cfgOptionTest(cfgOptPgHost + optionIdx) && cfgOptionSource(cfgOptPgHostCmd + optionIdx) == cfgSourceDefault)
cfgOptionDefaultSet(cfgOptPgHostCmd + optionIdx, VARSTR(cfgExe()));
@ -114,7 +114,7 @@ cfgLoadUpdateOption(void)
{
bool pgHostFound = false;
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIndexTotal(cfgOptPgHost); optionIdx++)
for (unsigned int optionIdx = 0; optionIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); optionIdx++)
{
if (cfgOptionTest(cfgOptPgHost + optionIdx))
{
@ -126,7 +126,7 @@ cfgLoadUpdateOption(void)
// If a pg-host was found, see if a repo-host is configured
if (pgHostFound == true)
{
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIndexTotal(cfgOptRepoHost); optionIdx++)
for (unsigned int optionIdx = 0; optionIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); optionIdx++)
{
if (cfgOptionTest(cfgOptRepoHost + optionIdx))
THROW_FMT(ConfigError, "pg and repo hosts cannot both be configured as remote");
@ -137,7 +137,7 @@ cfgLoadUpdateOption(void)
// Warn when repo-retention-full is not set on a configured repo
if (!cfgCommandHelp() && cfgOptionValid(cfgOptRepoRetentionFullType) && cfgCommandRole() == cfgCmdRoleDefault)
{
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIndexTotal(cfgOptRepoType); optionIdx++)
for (unsigned int optionIdx = 0; optionIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); optionIdx++)
{
// If the repo-type is defined, then see if corresponding retention-full is set
if (cfgOptionTest(cfgOptRepoType + optionIdx) && !(cfgOptionTest(cfgOptRepoRetentionFull + optionIdx)))
@ -156,7 +156,7 @@ cfgLoadUpdateOption(void)
if (cfgOptionValid(cfgOptRepoRetentionArchive))
{
// For each possible repo, check and adjust the settings as appropriate
for (unsigned int optionIdx = 0; optionIdx < cfgOptionIndexTotal(cfgOptRepoType); optionIdx++)
for (unsigned int optionIdx = 0; optionIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); optionIdx++)
{
const String *archiveRetentionType = cfgOptionStr(cfgOptRepoRetentionArchiveType + optionIdx);

View File

@ -63,9 +63,9 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
MEM_CONTEXT_TEMP_BEGIN()
{
// Loop through to look for primary and standby (if required)
for (unsigned int pgIdx = 0; pgIdx < cfgOptionIndexTotal(cfgOptPgPath); pgIdx++)
for (unsigned int pgIdx = 0; pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); pgIdx++)
{
if (cfgOptionTest(cfgOptPgHost + pgIdx) || cfgOptionTest(cfgOptPgPath + pgIdx))
if (cfgOptionGroupIdxTest(cfgOptGrpPg, pgIdx))
{
Db *db = NULL;
bool standby = false;

View File

@ -43,9 +43,6 @@ testRun(void)
TEST_RESULT_INT(cfgOptionIndex(cfgOptPgHostCmd + 6), 6, "option index");
TEST_RESULT_INT(cfgOptionIndex(cfgOptCompressLevel), 0, "option index");
TEST_RESULT_INT(cfgOptionIndexTotal(cfgOptPgPath), 8, "option index total");
TEST_RESULT_INT(cfgOptionIndexTotal(cfgOptLogLevelConsole), 1, "option index total");
TEST_RESULT_Z(cfgOptionName(cfgOptBackupStandby), "backup-standby", "option id from name");
}
@ -144,6 +141,30 @@ testRun(void)
TEST_RESULT_VOID(cfgOptionSet(cfgOptConfig, cfgSourceParam, varNewStrZ("cfg")), "set option config");
TEST_RESULT_BOOL(cfgOptionTest(cfgOptConfig), true, "option valid and value not null");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("option groups");
TEST_RESULT_BOOL(cfgOptionGroupValid(cfgOptGrpPg), false, "pg option group is not valid");
TEST_RESULT_BOOL(cfgOptionGroupIdxTest(cfgOptGrpPg, 0), false, "pg option group index 0 is not set");
TEST_RESULT_UINT(cfgOptionGroupIdxTotal(cfgOptGrpPg), 0, "pg option group index total is 0");
TEST_RESULT_VOID(cfgOptionValidSet(cfgOptPgPath + 1, true), "set pg1-path valid");
TEST_RESULT_BOOL(cfgOptionGroupValid(cfgOptGrpPg), true, "pg option group is valid");
TEST_RESULT_BOOL(cfgOptionGroupIdxTest(cfgOptGrpPg, 0), true, "pg option group index 0 is set");
TEST_RESULT_BOOL(cfgOptionGroupIdxTest(cfgOptGrpPg, 1), false, "pg option group index 1 is not set");
TEST_RESULT_UINT(cfgOptionGroupIdxTotal(cfgOptGrpPg), 1, "pg option group index total is 1");
TEST_RESULT_VOID(cfgOptionValidSet(cfgOptPgPath + 7, true), "set pg7-path valid");
TEST_RESULT_VOID(cfgOptionSet(cfgOptPgPath + 7, cfgSourceParam, VARSTRDEF("/path")), "set pg7-path");
TEST_RESULT_BOOL(cfgOptionGroupIdxTest(cfgOptGrpPg, 1), false, "pg option group index 1 is not set");
TEST_RESULT_BOOL(cfgOptionGroupIdxTest(cfgOptGrpPg, 7), true, "pg option group index 7 is set");
TEST_RESULT_UINT(cfgOptionGroupIdxTotal(cfgOptGrpPg), 8, "pg option group index total is 8");
TEST_RESULT_VOID(cfgOptionValidSet(cfgOptPgPath + 5, true), "set pg5-path valid");
TEST_RESULT_VOID(cfgOptionSet(cfgOptPgPath + 5, cfgSourceDefault, VARSTRDEF("/path")), "set pg5-path");
TEST_RESULT_BOOL(cfgOptionGroupIdxTest(cfgOptGrpPg, 5), false, "pg option group index 5 is not set");
TEST_RESULT_UINT(cfgOptionGroupIdxTotal(cfgOptGrpPg), 8, "pg option group index total is 8");
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_PTR(cfgOption(cfgOptOnline), NULL, "online is null");
TEST_RESULT_VOID(cfgOptionSet(cfgOptOnline, cfgSourceParam, varNewBool(false)), "set online");

View File

@ -68,15 +68,15 @@ testRun(void)
cfgOptionValidSet(cfgOptPgHostCmd + 2, true);
cfgOptionValidSet(cfgOptPgHost + cfgOptionIndexTotal(cfgOptPgHost) - 1, true);
cfgOptionSet(cfgOptPgHost + cfgOptionIndexTotal(cfgOptPgHost) - 1, cfgSourceParam, varNewStrZ("pgX-host"));
cfgOptionValidSet(cfgOptPgHostCmd + cfgOptionIndexTotal(cfgOptPgHost) - 1, true);
cfgOptionValidSet(cfgOptPgHost + cfgDefOptionIndexTotal(cfgDefOptPgHost) - 1, true);
cfgOptionSet(cfgOptPgHost + cfgDefOptionIndexTotal(cfgDefOptPgHost) - 1, cfgSourceParam, varNewStrZ("pgX-host"));
cfgOptionValidSet(cfgOptPgHostCmd + cfgDefOptionIndexTotal(cfgDefOptPgHost) - 1, true);
TEST_RESULT_VOID(cfgLoadUpdateOption(), "pg remote command is updated");
TEST_RESULT_STR(cfgOptionStr(cfgOptPgHostCmd), exe, " check pg1-host-cmd");
TEST_RESULT_STR(cfgOptionStr(cfgOptPgHostCmd + 1), exeOther, " check pg2-host-cmd is already set");
TEST_RESULT_STR(cfgOptionStrNull(cfgOptPgHostCmd + 2), NULL, " check pg3-host-cmd is not set");
TEST_RESULT_STR(cfgOptionStr(cfgOptPgHostCmd + cfgOptionIndexTotal(cfgOptPgHost) - 1), exe, " check pgX-host-cmd");
TEST_RESULT_STR(cfgOptionStr(cfgOptPgHostCmd + cfgDefOptionIndexTotal(cfgDefOptPgHost) - 1), exe, " check pgX-host-cmd");
// -------------------------------------------------------------------------------------------------------------------------
cfgInit();