mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-18 04:58:51 +02:00
Implement version command in C.
This commit is contained in:
parent
bd74711ceb
commit
915ae5662a
@ -16,11 +16,11 @@ use Storable qw(dclone);
|
||||
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Common::String;
|
||||
use pgBackRestBuild::Config::Data;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestBuild::Build::Common;
|
||||
use pgBackRestBuild::Config::BuildDefine;
|
||||
use pgBackRestBuild::Config::Data;
|
||||
|
||||
####################################################################################################################################
|
||||
# Constants
|
||||
@ -123,6 +123,9 @@ sub buildConfig
|
||||
" )\n";
|
||||
}
|
||||
|
||||
# Add "none" command that is used to initialize the current command before anything is parsed
|
||||
push(@{$rhEnum->{&BLD_LIST}}, buildConfigCommandEnum('none'));
|
||||
|
||||
$strBuildSource .=
|
||||
")\n";
|
||||
|
||||
|
@ -16,10 +16,10 @@ use Storable qw(dclone);
|
||||
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Common::String;
|
||||
use pgBackRestBuild::Config::Data;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestBuild::Build::Common;
|
||||
use pgBackRestBuild::Config::Data;
|
||||
|
||||
####################################################################################################################################
|
||||
# Constants
|
||||
|
132
build/lib/pgBackRestBuild/Config/BuildParse.pm
Normal file
132
build/lib/pgBackRestBuild/Config/BuildParse.pm
Normal file
@ -0,0 +1,132 @@
|
||||
####################################################################################################################################
|
||||
# Auto-Generate Option Definition for Parsing with getopt_long().
|
||||
####################################################################################################################################
|
||||
package pgBackRestBuild::Config::BuildParse;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
use English '-no_match_vars';
|
||||
|
||||
use Cwd qw(abs_path);
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw();
|
||||
use File::Basename qw(dirname);
|
||||
use Storable qw(dclone);
|
||||
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Common::String;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestBuild::Build::Common;
|
||||
use pgBackRestBuild::Config::Build;
|
||||
use pgBackRestBuild::Config::Data;
|
||||
|
||||
####################################################################################################################################
|
||||
# Constants
|
||||
####################################################################################################################################
|
||||
use constant BLDLCL_FILE_DEFINE => 'parse';
|
||||
|
||||
use constant BLDLCL_DATA_OPTION => '01-dataOption';
|
||||
|
||||
####################################################################################################################################
|
||||
# Definitions for constants and data to build
|
||||
####################################################################################################################################
|
||||
my $strSummary = 'Option Parse Definition';
|
||||
|
||||
my $rhBuild =
|
||||
{
|
||||
&BLD_FILE =>
|
||||
{
|
||||
&BLDLCL_FILE_DEFINE =>
|
||||
{
|
||||
&BLD_SUMMARY => $strSummary,
|
||||
|
||||
&BLD_DATA =>
|
||||
{
|
||||
&BLDLCL_DATA_OPTION =>
|
||||
{
|
||||
&BLD_SUMMARY => 'Option parse data',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Build configuration constants and data
|
||||
####################################################################################################################################
|
||||
sub buildConfigParse
|
||||
{
|
||||
# Build option parse list
|
||||
#-------------------------------------------------------------------------------------------------------------------------------
|
||||
my $rhConfigDefine = cfgDefine();
|
||||
|
||||
my $strBuildSource =
|
||||
"static const struct option optionList[] =\n" .
|
||||
"{\n";
|
||||
|
||||
foreach my $strOption (sort(keys(%{$rhConfigDefine})))
|
||||
{
|
||||
my $rhOption = $rhConfigDefine->{$strOption};
|
||||
my $strOptionEnum = buildConfigOptionEnum($strOption);
|
||||
my $strOptionArg = ($rhOption->{&CFGDEF_TYPE} ne CFGDEF_TYPE_BOOLEAN ? " .has_arg = required_argument,\n" : '');
|
||||
my $strOptionPrefix = $rhConfigDefine->{$strOption}{&CFGDEF_PREFIX};
|
||||
|
||||
for (my $iOptionIdx = 0; $iOptionIdx <= $rhOption->{&CFGDEF_INDEX_TOTAL}; $iOptionIdx++)
|
||||
{
|
||||
# Don't and option indexes if it is not indexeds
|
||||
next if ($iOptionIdx == 1 && $rhOption->{&CFGDEF_INDEX_TOTAL} == 1);
|
||||
|
||||
# Generate option name
|
||||
my $strOptionName = $iOptionIdx > 0 ?
|
||||
"${strOptionPrefix}${iOptionIdx}-" . substr($strOption, length($strOptionPrefix) + 1) : $strOption;
|
||||
|
||||
# Generate option value used for parsing (offset is added so options don't conflict with getopt_long return values)
|
||||
my $strOptionVal = 'PARSE_OPTION_OFFSET + ' . $strOptionEnum . ($iOptionIdx > 1 ? " + " . ($iOptionIdx - 1) : '');
|
||||
|
||||
# Add option
|
||||
$strBuildSource .=
|
||||
" {\n" .
|
||||
" .name = \"${strOptionName}\",\n" .
|
||||
$strOptionArg .
|
||||
" .val = ${strOptionVal},\n" .
|
||||
" },\n";
|
||||
|
||||
# Add negation when defined
|
||||
if ($rhOption->{&CFGDEF_NEGATE})
|
||||
{
|
||||
$strBuildSource .=
|
||||
" {\n" .
|
||||
" .name = \"no-${strOptionName}\",\n" .
|
||||
" .val = ${strOptionVal},\n" .
|
||||
" },\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Perl options passed to the C binary should be ignored (unless calling Perl which is done elsewhere)
|
||||
$strBuildSource .=
|
||||
" // Perl option is ignored by normal config parsing\n" .
|
||||
" {\n" .
|
||||
" .name = \"perl-option\",\n" .
|
||||
" .has_arg = required_argument,\n" .
|
||||
" .val = 0,\n" .
|
||||
" },\n";
|
||||
|
||||
# The option list needs to be terminated or getopt_long will just keep on reading
|
||||
$strBuildSource .=
|
||||
" // Terminate option list\n" .
|
||||
" {\n" .
|
||||
" .name = NULL\n" .
|
||||
" }\n" .
|
||||
"};\n";
|
||||
|
||||
$rhBuild->{&BLD_FILE}{&BLDLCL_FILE_DEFINE}{&BLD_DATA}{&BLDLCL_DATA_OPTION}{&BLD_SOURCE} = $strBuildSource;
|
||||
|
||||
return $rhBuild;
|
||||
}
|
||||
|
||||
push @EXPORT, qw(buildConfigParse);
|
||||
|
||||
1;
|
@ -23,6 +23,10 @@
|
||||
</release-improvement-list>
|
||||
|
||||
<release-development-list>
|
||||
<release-item>
|
||||
<p>Implement <cmd>version</cmd> command in C.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>memGrowRaw()</code> to memory context module.</p>
|
||||
</release-item>
|
||||
|
30
src/Makefile
30
src/Makefile
@ -2,12 +2,30 @@ CC=gcc
|
||||
CFLAGS=-I. -Wfatal-errors -Wall -Wextra -Wwrite-strings -Wno-clobbered -std=c99 -funroll-loops -ftree-vectorize
|
||||
DESTDIR=
|
||||
|
||||
pgbackrest: main.o \
|
||||
common/error.o common/errorType.o common/memContext.o common/type/list.o common/type/string.o common/type/stringList.o \
|
||||
perl/exec.o
|
||||
$(CC) $(CFLAGS) -o pgbackrest main.o \
|
||||
common/error.o common/errorType.o common/memContext.o common/type/list.o common/type/string.o common/type/stringList.o \
|
||||
perl/exec.o
|
||||
pgbackrest: \
|
||||
common/error.o \
|
||||
common/errorType.o \
|
||||
common/memContext.o \
|
||||
common/type/list.o \
|
||||
common/type/string.o \
|
||||
common/type/stringList.o \
|
||||
config/config.o \
|
||||
config/define.o \
|
||||
config/parse.o \
|
||||
perl/exec.o \
|
||||
main.o
|
||||
$(CC) $(CFLAGS) -o pgbackrest \
|
||||
common/error.o \
|
||||
common/errorType.o \
|
||||
common/memContext.o \
|
||||
common/type/list.o \
|
||||
common/type/string.o \
|
||||
common/type/stringList.o \
|
||||
config/config.o \
|
||||
config/define.o \
|
||||
config/parse.o \
|
||||
perl/exec.o \
|
||||
main.o
|
||||
|
||||
install: pgbackrest
|
||||
sudo install -d $(DESTDIR)/usr/bin
|
||||
|
@ -31,6 +31,8 @@ Define errors
|
||||
ERROR_DEFINE(ERROR_CODE_MIN, AssertError, RuntimeError);
|
||||
|
||||
ERROR_DEFINE(ERROR_CODE_MIN + 04, FormatError, RuntimeError);
|
||||
ERROR_DEFINE(ERROR_CODE_MIN + 23, CommandInvalidError, FormatError);
|
||||
ERROR_DEFINE(ERROR_CODE_MIN + 31, OptionInvalidError, FormatError);
|
||||
ERROR_DEFINE(ERROR_CODE_MIN + 69, MemoryError, RuntimeError);
|
||||
ERROR_DEFINE(ERROR_CODE_MIN + 70, CipherError, FormatError);
|
||||
|
||||
|
@ -17,6 +17,8 @@ typedef struct ErrorType ErrorType;
|
||||
ERROR_DECLARE(AssertError);
|
||||
|
||||
ERROR_DECLARE(FormatError);
|
||||
ERROR_DECLARE(CommandInvalidError);
|
||||
ERROR_DECLARE(OptionInvalidError);
|
||||
ERROR_DECLARE(MemoryError);
|
||||
ERROR_DECLARE(CipherError);
|
||||
|
||||
|
@ -26,6 +26,7 @@ typedef enum
|
||||
cfgCmdStart,
|
||||
cfgCmdStop,
|
||||
cfgCmdVersion,
|
||||
cfgCmdNone,
|
||||
} ConfigCommand;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
|
@ -52,6 +52,31 @@ Include the automatically generated configuration data
|
||||
***********************************************************************************************************************************/
|
||||
#include "config.auto.c"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Store the current command
|
||||
|
||||
This is generally set by the command parser but can also be set by during execute to change commands, i.e. backup -> expire.
|
||||
***********************************************************************************************************************************/
|
||||
ConfigCommand command = cfgCmdNone;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Get the current command
|
||||
***********************************************************************************************************************************/
|
||||
ConfigCommand
|
||||
cfgCommand()
|
||||
{
|
||||
return command;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Set the current command
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
cfgCommandSet(ConfigCommand commandParam)
|
||||
{
|
||||
command = commandParam;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Ensure that command id is valid
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -12,9 +12,11 @@ Command and Option Configuration
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
ConfigCommand cfgCommand();
|
||||
int cfgCommandId(const char *commandName);
|
||||
const char *cfgCommandName(ConfigCommand commandId);
|
||||
ConfigDefineCommand cfgCommandDefIdFromId(ConfigCommand commandId);
|
||||
void cfgCommandSet(ConfigCommand commandParam);
|
||||
unsigned int cfgCommandTotal();
|
||||
|
||||
int cfgOptionId(const char *optionName);
|
||||
|
797
src/config/parse.auto.c
Normal file
797
src/config/parse.auto.c
Normal file
@ -0,0 +1,797 @@
|
||||
/***********************************************************************************************************************************
|
||||
Option Parse Definition
|
||||
|
||||
Automatically generated by Build.pm -- do not modify directly.
|
||||
***********************************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Option parse data
|
||||
***********************************************************************************************************************************/
|
||||
static const struct option optionList[] =
|
||||
{
|
||||
{
|
||||
.name = "archive-async",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveAsync,
|
||||
},
|
||||
{
|
||||
.name = "no-archive-async",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveAsync,
|
||||
},
|
||||
{
|
||||
.name = "archive-check",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveCheck,
|
||||
},
|
||||
{
|
||||
.name = "no-archive-check",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveCheck,
|
||||
},
|
||||
{
|
||||
.name = "archive-copy",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveCopy,
|
||||
},
|
||||
{
|
||||
.name = "no-archive-copy",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveCopy,
|
||||
},
|
||||
{
|
||||
.name = "archive-queue-max",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveQueueMax,
|
||||
},
|
||||
{
|
||||
.name = "archive-timeout",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptArchiveTimeout,
|
||||
},
|
||||
{
|
||||
.name = "backup-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupCmd,
|
||||
},
|
||||
{
|
||||
.name = "backup-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupConfig,
|
||||
},
|
||||
{
|
||||
.name = "backup-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupHost,
|
||||
},
|
||||
{
|
||||
.name = "backup-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupSshPort,
|
||||
},
|
||||
{
|
||||
.name = "backup-standby",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupStandby,
|
||||
},
|
||||
{
|
||||
.name = "no-backup-standby",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupStandby,
|
||||
},
|
||||
{
|
||||
.name = "backup-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBackupUser,
|
||||
},
|
||||
{
|
||||
.name = "buffer-size",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptBufferSize,
|
||||
},
|
||||
{
|
||||
.name = "checksum-page",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptChecksumPage,
|
||||
},
|
||||
{
|
||||
.name = "no-checksum-page",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptChecksumPage,
|
||||
},
|
||||
{
|
||||
.name = "cmd-ssh",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptCmdSsh,
|
||||
},
|
||||
{
|
||||
.name = "command",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptCommand,
|
||||
},
|
||||
{
|
||||
.name = "compress",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptCompress,
|
||||
},
|
||||
{
|
||||
.name = "no-compress",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptCompress,
|
||||
},
|
||||
{
|
||||
.name = "compress-level",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptCompressLevel,
|
||||
},
|
||||
{
|
||||
.name = "compress-level-network",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptCompressLevelNetwork,
|
||||
},
|
||||
{
|
||||
.name = "config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptConfig,
|
||||
},
|
||||
{
|
||||
.name = "no-config",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptConfig,
|
||||
},
|
||||
{
|
||||
.name = "db-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd,
|
||||
},
|
||||
{
|
||||
.name = "db1-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd,
|
||||
},
|
||||
{
|
||||
.name = "db2-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-cmd",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbCmd + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig,
|
||||
},
|
||||
{
|
||||
.name = "db1-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig,
|
||||
},
|
||||
{
|
||||
.name = "db2-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-config",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbConfig + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost,
|
||||
},
|
||||
{
|
||||
.name = "db1-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost,
|
||||
},
|
||||
{
|
||||
.name = "db2-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbHost + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-include",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbInclude,
|
||||
},
|
||||
{
|
||||
.name = "db-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath,
|
||||
},
|
||||
{
|
||||
.name = "db1-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath,
|
||||
},
|
||||
{
|
||||
.name = "db2-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPath + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort,
|
||||
},
|
||||
{
|
||||
.name = "db1-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort,
|
||||
},
|
||||
{
|
||||
.name = "db2-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbPort + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath,
|
||||
},
|
||||
{
|
||||
.name = "db1-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath,
|
||||
},
|
||||
{
|
||||
.name = "db2-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-socket-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSocketPath + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort,
|
||||
},
|
||||
{
|
||||
.name = "db1-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort,
|
||||
},
|
||||
{
|
||||
.name = "db2-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-ssh-port",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbSshPort + 7,
|
||||
},
|
||||
{
|
||||
.name = "db-timeout",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbTimeout,
|
||||
},
|
||||
{
|
||||
.name = "db-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser,
|
||||
},
|
||||
{
|
||||
.name = "db1-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser,
|
||||
},
|
||||
{
|
||||
.name = "db2-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 1,
|
||||
},
|
||||
{
|
||||
.name = "db3-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 2,
|
||||
},
|
||||
{
|
||||
.name = "db4-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 3,
|
||||
},
|
||||
{
|
||||
.name = "db5-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 4,
|
||||
},
|
||||
{
|
||||
.name = "db6-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 5,
|
||||
},
|
||||
{
|
||||
.name = "db7-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 6,
|
||||
},
|
||||
{
|
||||
.name = "db8-user",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDbUser + 7,
|
||||
},
|
||||
{
|
||||
.name = "delta",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptDelta,
|
||||
},
|
||||
{
|
||||
.name = "force",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptForce,
|
||||
},
|
||||
{
|
||||
.name = "hardlink",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptHardlink,
|
||||
},
|
||||
{
|
||||
.name = "no-hardlink",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptHardlink,
|
||||
},
|
||||
{
|
||||
.name = "host-id",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptHostId,
|
||||
},
|
||||
{
|
||||
.name = "link-all",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLinkAll,
|
||||
},
|
||||
{
|
||||
.name = "no-link-all",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLinkAll,
|
||||
},
|
||||
{
|
||||
.name = "link-map",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLinkMap,
|
||||
},
|
||||
{
|
||||
.name = "lock-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLockPath,
|
||||
},
|
||||
{
|
||||
.name = "log-level-console",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLogLevelConsole,
|
||||
},
|
||||
{
|
||||
.name = "log-level-file",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLogLevelFile,
|
||||
},
|
||||
{
|
||||
.name = "log-level-stderr",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLogLevelStderr,
|
||||
},
|
||||
{
|
||||
.name = "log-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLogPath,
|
||||
},
|
||||
{
|
||||
.name = "log-timestamp",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLogTimestamp,
|
||||
},
|
||||
{
|
||||
.name = "no-log-timestamp",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptLogTimestamp,
|
||||
},
|
||||
{
|
||||
.name = "manifest-save-threshold",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptManifestSaveThreshold,
|
||||
},
|
||||
{
|
||||
.name = "neutral-umask",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptNeutralUmask,
|
||||
},
|
||||
{
|
||||
.name = "no-neutral-umask",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptNeutralUmask,
|
||||
},
|
||||
{
|
||||
.name = "online",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptOnline,
|
||||
},
|
||||
{
|
||||
.name = "no-online",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptOnline,
|
||||
},
|
||||
{
|
||||
.name = "output",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptOutput,
|
||||
},
|
||||
{
|
||||
.name = "process",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptProcess,
|
||||
},
|
||||
{
|
||||
.name = "process-max",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptProcessMax,
|
||||
},
|
||||
{
|
||||
.name = "protocol-timeout",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptProtocolTimeout,
|
||||
},
|
||||
{
|
||||
.name = "recovery-option",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRecoveryOption,
|
||||
},
|
||||
{
|
||||
.name = "repo-cipher-pass",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoCipherPass,
|
||||
},
|
||||
{
|
||||
.name = "repo-cipher-type",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoCipherType,
|
||||
},
|
||||
{
|
||||
.name = "repo-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoPath,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-bucket",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3Bucket,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-ca-file",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3CaFile,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-ca-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3CaPath,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-endpoint",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3Endpoint,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-host",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3Host,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-key",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3Key,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-key-secret",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3KeySecret,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-region",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3Region,
|
||||
},
|
||||
{
|
||||
.name = "repo-s3-verify-ssl",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3VerifySsl,
|
||||
},
|
||||
{
|
||||
.name = "no-repo-s3-verify-ssl",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoS3VerifySsl,
|
||||
},
|
||||
{
|
||||
.name = "repo-type",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRepoType,
|
||||
},
|
||||
{
|
||||
.name = "resume",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptResume,
|
||||
},
|
||||
{
|
||||
.name = "no-resume",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptResume,
|
||||
},
|
||||
{
|
||||
.name = "retention-archive",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRetentionArchive,
|
||||
},
|
||||
{
|
||||
.name = "retention-archive-type",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRetentionArchiveType,
|
||||
},
|
||||
{
|
||||
.name = "retention-diff",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRetentionDiff,
|
||||
},
|
||||
{
|
||||
.name = "retention-full",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptRetentionFull,
|
||||
},
|
||||
{
|
||||
.name = "set",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptSet,
|
||||
},
|
||||
{
|
||||
.name = "spool-path",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptSpoolPath,
|
||||
},
|
||||
{
|
||||
.name = "stanza",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptStanza,
|
||||
},
|
||||
{
|
||||
.name = "start-fast",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptStartFast,
|
||||
},
|
||||
{
|
||||
.name = "no-start-fast",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptStartFast,
|
||||
},
|
||||
{
|
||||
.name = "stop-auto",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptStopAuto,
|
||||
},
|
||||
{
|
||||
.name = "no-stop-auto",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptStopAuto,
|
||||
},
|
||||
{
|
||||
.name = "tablespace-map",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTablespaceMap,
|
||||
},
|
||||
{
|
||||
.name = "tablespace-map-all",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTablespaceMapAll,
|
||||
},
|
||||
{
|
||||
.name = "target",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTarget,
|
||||
},
|
||||
{
|
||||
.name = "target-action",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTargetAction,
|
||||
},
|
||||
{
|
||||
.name = "target-exclusive",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTargetExclusive,
|
||||
},
|
||||
{
|
||||
.name = "target-timeline",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTargetTimeline,
|
||||
},
|
||||
{
|
||||
.name = "test",
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTest,
|
||||
},
|
||||
{
|
||||
.name = "test-delay",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTestDelay,
|
||||
},
|
||||
{
|
||||
.name = "test-point",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptTestPoint,
|
||||
},
|
||||
{
|
||||
.name = "type",
|
||||
.has_arg = required_argument,
|
||||
.val = PARSE_OPTION_OFFSET + cfgOptType,
|
||||
},
|
||||
// Perl option is ignored by normal config parsing
|
||||
{
|
||||
.name = "perl-option",
|
||||
.has_arg = required_argument,
|
||||
.val = 0,
|
||||
},
|
||||
// Terminate option list
|
||||
{
|
||||
.name = NULL
|
||||
}
|
||||
};
|
78
src/config/parse.c
Normal file
78
src/config/parse.c
Normal file
@ -0,0 +1,78 @@
|
||||
/***********************************************************************************************************************************
|
||||
Command and Option Configuration
|
||||
***********************************************************************************************************************************/
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/error.h"
|
||||
#include "config/config.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Include the automatically generated configuration data
|
||||
***********************************************************************************************************************************/
|
||||
// Offset the option values so they don't conflict with getopt_long return codes
|
||||
#define PARSE_OPTION_OFFSET 100000
|
||||
|
||||
#include "parse.auto.c"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Map command names to ids and vice versa
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
configParse(int argListSize, const char *argList[])
|
||||
{
|
||||
// Reset optind to 1 in case getopt_long has been called before
|
||||
optind = 1;
|
||||
|
||||
// Don't error automatically on unknown options - they will be processed in the loop below
|
||||
opterr = false;
|
||||
|
||||
// Only the first non-option parameter should be treated as a command so track if the command has been set
|
||||
bool commandSet = false;
|
||||
|
||||
// Parse options
|
||||
int option;
|
||||
int optionIdx;
|
||||
|
||||
while ((option = getopt_long(argListSize, (char **)argList, "-", optionList, &optionIdx)) != -1)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
// Perl options that should be ignored
|
||||
case 0:
|
||||
break;
|
||||
|
||||
// Parse parameters that are not options, i.e. commands and parameters passed to commands
|
||||
case 1:
|
||||
// The first parameter should be the command
|
||||
if (!commandSet)
|
||||
{
|
||||
// Try getting the command from the valid command list
|
||||
TRY_BEGIN()
|
||||
{
|
||||
cfgCommandSet(cfgCommandId(argList[optind - 1]));
|
||||
}
|
||||
// Assert error means the command does not exist, which is correct for all usages but this one (since we don't
|
||||
// have any control over what the user passes), so modify the error code and message.
|
||||
CATCH(AssertError)
|
||||
{
|
||||
THROW(CommandInvalidError, "invalid command '%s'", argList[optind - 1]);
|
||||
}
|
||||
TRY_END();
|
||||
}
|
||||
// Else implement additional parameters here for more complex commands
|
||||
|
||||
commandSet = true;
|
||||
break;
|
||||
|
||||
// If the option is unknown generate an error
|
||||
case '?':
|
||||
THROW(OptionInvalidError, "invalid option '%s'", argList[optind - 1]);
|
||||
break; // {uncoverable - case statement does not return}
|
||||
|
||||
// Parse valid option
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
12
src/config/parse.h
Normal file
12
src/config/parse.h
Normal file
@ -0,0 +1,12 @@
|
||||
/***********************************************************************************************************************************
|
||||
Parse Configuration
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef CONFIG_PARSE_H
|
||||
#define CONFIG_PARSE_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
void configParse(int argListSize, char *argList[]);
|
||||
|
||||
#endif
|
32
src/main.c
32
src/main.c
@ -1,10 +1,38 @@
|
||||
/***********************************************************************************************************************************
|
||||
Main
|
||||
***********************************************************************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common/error.h"
|
||||
#include "config/config.h"
|
||||
#include "config/parse.h"
|
||||
#include "perl/exec.h"
|
||||
#include "version.h"
|
||||
|
||||
int main(int argListSize, char *argList[])
|
||||
{
|
||||
// Execute Perl since nothing is implemented in C (yet)
|
||||
perlExec(perlCommand(argListSize, argList));
|
||||
TRY_BEGIN()
|
||||
{
|
||||
// Parse command line
|
||||
configParse(argListSize, argList);
|
||||
|
||||
// Display version
|
||||
if (cfgCommand() == cfgCmdVersion)
|
||||
{
|
||||
printf(PGBACKREST_NAME " " PGBACKREST_VERSION "\n");
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Execute Perl for commands not implemented in C
|
||||
perlExec(perlCommand(argListSize, argList));
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
fprintf(stderr, "ERROR: [%03d]: %s\n", errorCode(), errorMessage());
|
||||
fflush(stderr);
|
||||
exit(errorCode());
|
||||
}
|
||||
TRY_END();
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ StringList *perlCommand(int argListSize, char *argList[])
|
||||
// Reset optind to 1 in case getopt_long has been called before
|
||||
optind = 1;
|
||||
|
||||
// Don't error on unknown options -- they are expected since we are passing options through to Perl
|
||||
opterr = false;
|
||||
|
||||
// Struct with all valid options
|
||||
static struct option optionList[] =
|
||||
{
|
||||
@ -54,7 +57,6 @@ StringList *perlCommand(int argListSize, char *argList[])
|
||||
// Parse options
|
||||
int option;
|
||||
int optionIdx;
|
||||
opterr = false;
|
||||
|
||||
while ((option = getopt_long(argListSize, argList, "-", optionList, &optionIdx)) != -1)
|
||||
{
|
||||
|
@ -9,4 +9,9 @@ Official name of the software, also used for Perl package name
|
||||
***********************************************************************************************************************************/
|
||||
#define PGBACKREST_NAME "pgBackRest"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Version of the software. Currently this value is maintained in Version.pm and updated by test.pl.
|
||||
***********************************************************************************************************************************/
|
||||
#define PGBACKREST_VERSION "2.00dev"
|
||||
|
||||
#endif
|
||||
|
@ -318,7 +318,7 @@ my $oTestDef =
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'config',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_C => true,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
@ -327,6 +327,17 @@ my $oTestDef =
|
||||
'config/config.auto' => TESTDEF_COVERAGE_NOCODE,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'parse',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
&TESTDEF_C => true,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
'config/parse' => TESTDEF_COVERAGE_FULL,
|
||||
'config/parse.auto' => TESTDEF_COVERAGE_NOCODE,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
|
@ -25,7 +25,7 @@ Test that an expected error is actually thrown and error when it isn't
|
||||
{ \
|
||||
bool TEST_ERROR_catch = false; \
|
||||
\
|
||||
printf(" l%04d - expect error: %s\n", __LINE__, errorMessageExpected); \
|
||||
printf(" l%04d - expect %s: %s\n", __LINE__, errorTypeName(&errorTypeExpected), errorMessageExpected); \
|
||||
fflush(stdout); \
|
||||
\
|
||||
TRY_BEGIN() \
|
||||
@ -89,6 +89,15 @@ Compare types
|
||||
#define TEST_TYPE_COMPARE(result, value, typeOp, valueExpected) \
|
||||
result = value typeOp valueExpected;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Output information about the test
|
||||
***********************************************************************************************************************************/
|
||||
#define TEST_RESULT_INFO(...) \
|
||||
printf(" l%04d - ", __LINE__); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
fflush(stdout);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test the result of a statement and make sure it matches the expected value. This macro can test any C type given the correct
|
||||
parameters.
|
||||
@ -99,10 +108,7 @@ parameters.
|
||||
const type TEST_RESULT_resultExpected = (type)(resultExpectedValue); \
|
||||
\
|
||||
/* Output test info */ \
|
||||
printf(" l%04d - ", __LINE__); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
fflush(stdout); \
|
||||
TEST_RESULT_INFO(__VA_ARGS__); \
|
||||
\
|
||||
/* Format the expected result */ \
|
||||
formatMacro(type, format, TEST_RESULT_resultExpected); \
|
||||
@ -141,6 +147,27 @@ parameters.
|
||||
} \
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test that a void statement returns and does not throw an error
|
||||
***********************************************************************************************************************************/
|
||||
#define TEST_RESULT_VOID(statement, ...) \
|
||||
{ \
|
||||
/* Output test info */ \
|
||||
TEST_RESULT_INFO(__VA_ARGS__); \
|
||||
\
|
||||
TRY_BEGIN() \
|
||||
{ \
|
||||
statement; \
|
||||
} \
|
||||
/* Catch any errors */ \
|
||||
CATCH_ANY() \
|
||||
{ \
|
||||
/* No errors were expected so error */ \
|
||||
THROW(AssertError, "statement '%s' threw error %s, '%s' but void expected", #statement, errorName(), errorMessage()); \
|
||||
} \
|
||||
TRY_END(); \
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros to ease the use of common data types
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -67,4 +67,12 @@ void testRun()
|
||||
TEST_ERROR(cfgOptionName(-1), AssertError, optionIdInvalidLowError);
|
||||
TEST_RESULT_STR(cfgOptionName(cfgOptBackupStandby), "backup-standby", "option id from name");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("configuration"))
|
||||
{
|
||||
TEST_RESULT_INT(cfgCommand(), cfgCmdNone, "command begins as none");
|
||||
TEST_RESULT_VOID(cfgCommandSet(cfgCmdBackup), "command set to backup");
|
||||
TEST_RESULT_INT(cfgCommand(), cfgCmdBackup, "command is backup");
|
||||
}
|
||||
}
|
||||
|
52
test/src/module/config/parseTest.c
Normal file
52
test/src/module/config/parseTest.c
Normal file
@ -0,0 +1,52 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Configuration Parse
|
||||
***********************************************************************************************************************************/
|
||||
|
||||
#define TEST_BACKREST_EXE "pgbackrest"
|
||||
|
||||
#define TEST_COMMAND_HELP "help"
|
||||
#define TEST_COMMAND_VERSION "version"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test run
|
||||
***********************************************************************************************************************************/
|
||||
void testRun()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("configParse()"))
|
||||
{
|
||||
StringList *argList = strLstNew();
|
||||
strLstAdd(argList, strNew(TEST_BACKREST_EXE));
|
||||
TEST_RESULT_VOID(configParse(strLstSize(argList), strLstPtr(argList)), "exe only");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAdd(argList, strNew(TEST_COMMAND_VERSION));
|
||||
TEST_RESULT_VOID(configParse(strLstSize(argList), strLstPtr(argList)), TEST_COMMAND_VERSION " command");
|
||||
TEST_RESULT_INT(cfgCommand(), cfgCmdVersion, "command is " TEST_COMMAND_VERSION);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAdd(argList, strNew("--perl-option=value"));
|
||||
TEST_RESULT_VOID(configParse(strLstSize(argList), strLstPtr(argList)), "perl option");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAdd(argList, strNewFmt("--%s", cfgOptionName(cfgOptDelta)));
|
||||
TEST_RESULT_VOID(configParse(strLstSize(argList), strLstPtr(argList)), "delta option");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAdd(argList, strNew("--" BOGUS_STR));
|
||||
TEST_ERROR(configParse(strLstSize(argList), strLstPtr(argList)), OptionInvalidError, "invalid option '--BOGUS'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstNew();
|
||||
strLstAdd(argList, strNew(TEST_BACKREST_EXE));
|
||||
strLstAdd(argList, strNew("--no-archive-check"));
|
||||
strLstAdd(argList, strNew(TEST_COMMAND_HELP));
|
||||
TEST_RESULT_VOID(configParse(strLstSize(argList), strLstPtr(argList)), TEST_COMMAND_HELP " command");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstNew();
|
||||
strLstAdd(argList, strNew(TEST_BACKREST_EXE));
|
||||
strLstAdd(argList, strNew(BOGUS_STR));
|
||||
TEST_ERROR(configParse(strLstSize(argList), strLstPtr(argList)), CommandInvalidError, "invalid command 'BOGUS'");
|
||||
}
|
||||
}
|
@ -38,6 +38,6 @@ main(void)
|
||||
// End test run an make sure all tests ran
|
||||
testComplete();
|
||||
|
||||
printf("\nTESTS COMPLETED SUCCESSFULLY (DESPITE ANY ERROR MESSAGES YOU SAW)\n");
|
||||
printf("\nTESTS COMPLETED SUCCESSFULLY\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
96
test/test.pl
96
test/test.pl
@ -41,6 +41,7 @@ use pgBackRestBuild::Build;
|
||||
use pgBackRestBuild::Build::Common;
|
||||
use pgBackRestBuild::Config::Build;
|
||||
use pgBackRestBuild::Config::BuildDefine;
|
||||
use pgBackRestBuild::Config::BuildParse;
|
||||
|
||||
use BackRestDoc::Custom::DocCustomRelease;
|
||||
|
||||
@ -281,41 +282,6 @@ eval
|
||||
my $oStorageBackRest = new pgBackRest::Storage::Local(
|
||||
$strBackRestBase, new pgBackRest::Storage::Posix::Driver({bFileSync => false, bPathSync => false}));
|
||||
|
||||
################################################################################################################################
|
||||
# Auto-generate C files
|
||||
################################################################################################################################
|
||||
my $rhBuild =
|
||||
{
|
||||
'config' =>
|
||||
{
|
||||
&BLD_DATA => buildConfig(),
|
||||
&BLD_PATH => 'config',
|
||||
},
|
||||
|
||||
'configDefine' =>
|
||||
{
|
||||
&BLD_DATA => buildConfigDefine(),
|
||||
&BLD_PATH => 'config',
|
||||
},
|
||||
};
|
||||
|
||||
buildAll("${strBackRestBase}/src", $rhBuild);
|
||||
|
||||
################################################################################################################################
|
||||
# Auto-generate XS files
|
||||
#
|
||||
# Use statements are put here so this will be easy to get ride of someday.
|
||||
################################################################################################################################
|
||||
use lib dirname(dirname($0)) . '/libc/build/lib';
|
||||
use pgBackRestLibC::Build; ## no critic (Modules::ProhibitConditionalUseStatements)
|
||||
|
||||
buildXsAll("${strBackRestBase}/libc");
|
||||
|
||||
if ($bGenOnly)
|
||||
{
|
||||
exit 0;
|
||||
}
|
||||
|
||||
################################################################################################################################
|
||||
# Build Docker containers
|
||||
################################################################################################################################
|
||||
@ -330,6 +296,45 @@ eval
|
||||
################################################################################################################################
|
||||
if (!defined($iVmId))
|
||||
{
|
||||
# Auto-generate C files
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $rhBuild =
|
||||
{
|
||||
'config' =>
|
||||
{
|
||||
&BLD_DATA => buildConfig(),
|
||||
&BLD_PATH => 'config',
|
||||
},
|
||||
|
||||
'configDefine' =>
|
||||
{
|
||||
&BLD_DATA => buildConfigDefine(),
|
||||
&BLD_PATH => 'config',
|
||||
},
|
||||
|
||||
'configParse' =>
|
||||
{
|
||||
&BLD_DATA => buildConfigParse(),
|
||||
&BLD_PATH => 'config',
|
||||
},
|
||||
};
|
||||
|
||||
buildAll("${strBackRestBase}/src", $rhBuild);
|
||||
|
||||
# Auto-generate XS files
|
||||
#
|
||||
# Use statements are put here so this will be easy to get rid of someday.
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
use lib dirname(dirname($0)) . '/libc/build/lib';
|
||||
use pgBackRestLibC::Build; ## no critic (Modules::ProhibitConditionalUseStatements)
|
||||
|
||||
buildXsAll("${strBackRestBase}/libc");
|
||||
|
||||
if ($bGenOnly)
|
||||
{
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# Sync time to prevent build failures when running on VirtualBox.
|
||||
my $strVBoxService = '/usr/sbin/VBoxService';
|
||||
|
||||
@ -370,6 +375,27 @@ eval
|
||||
confess 'unable to find version ' . BACKREST_VERSION . " as the most recent release in ${strReleaseFile}";
|
||||
}
|
||||
|
||||
# Update version for the C code based on the current Perl version
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $strCVersionFile = "${strBackRestBase}/src/version.h";
|
||||
my $strCVersionOld = ${$oStorageTest->get($strCVersionFile)};
|
||||
my $strCVersionNew;
|
||||
|
||||
foreach my $strLine (split("\n", $strCVersionOld))
|
||||
{
|
||||
if ($strLine =~ /^#define PGBACKREST_VERSION/)
|
||||
{
|
||||
$strLine = '#define PGBACKREST_VERSION' . (' ' x 42) . '"' . BACKREST_VERSION . '"';
|
||||
}
|
||||
|
||||
$strCVersionNew .= "${strLine}\n";
|
||||
}
|
||||
|
||||
if ($strCVersionNew ne $strCVersionOld)
|
||||
{
|
||||
$oStorageTest->put($strCVersionFile, $strCVersionNew);
|
||||
}
|
||||
|
||||
# Clean up
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $iTestFail = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user